From 61c0d2a10a7e3e51b8b4854f0add202943980964 Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Fri, 13 Sep 2024 13:22:38 -0500 Subject: [PATCH 01/51] Fix up some bugs. --- .../IkvmReflectionSymbolTests.cs | 8 + .../Reflection/ReflectionSymbolTests.cs | 8 + .../Symbols/ICustomAttributeSymbolProvider.cs | 17 +- .../IkvmReflectionAssemblySymbol.cs | 16 +- .../IkvmReflectionMemberSymbol.cs | 107 ++++++++++++- .../IkvmReflectionModuleSymbol.cs | 18 ++- .../IkvmReflectionParameterSymbol.cs | 20 ++- .../Reflection/ReflectionAssemblySymbol.cs | 37 ++++- .../Reflection/ReflectionMemberSymbol.cs | 149 ++++++++++++++---- .../Reflection/ReflectionModuleSymbol.cs | 22 +-- .../Reflection/ReflectionParameterSymbol.cs | 23 ++- .../Symbols/Reflection/ReflectionSymbol.cs | 14 ++ src/IKVM.Runtime/RuntimeManagedJavaType.cs | 2 - 13 files changed, 362 insertions(+), 79 deletions(-) diff --git a/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs b/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs index c683fdbb1..8e933cc67 100644 --- a/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs +++ b/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs @@ -194,6 +194,14 @@ public void CanGetMethod() m.IsPrivate.Should().BeFalse(); } + [TestMethod] + public void CanReadCustomAttributes() + { + var c = new IkvmReflectionSymbolContext(); + var s = c.GetOrCreateTypeSymbol(coreAssembly!.GetType("System.AttributeUsageAttribute")); + var a = s.GetCustomAttribute(s); + } + } } diff --git a/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs b/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs index 37b66bf09..a63114293 100644 --- a/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs +++ b/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs @@ -142,6 +142,14 @@ public void CanGetMethod() m.IsPrivate.Should().BeFalse(); } + [TestMethod] + public void CanReadCustomAttributes() + { + var c = new ReflectionSymbolContext(); + var s = c.GetOrCreateTypeSymbol(typeof(AttributeUsageAttribute)); + var a = s.GetCustomAttributes(); + } + } } diff --git a/src/IKVM.CoreLib/Symbols/ICustomAttributeSymbolProvider.cs b/src/IKVM.CoreLib/Symbols/ICustomAttributeSymbolProvider.cs index d7354b219..7659f048f 100644 --- a/src/IKVM.CoreLib/Symbols/ICustomAttributeSymbolProvider.cs +++ b/src/IKVM.CoreLib/Symbols/ICustomAttributeSymbolProvider.cs @@ -10,22 +10,33 @@ interface ICustomAttributeSymbolProvider /// /// Returns an array of all of the custom attributes defined on this member, excluding named attributes, or an empty array if there are no custom attributes. /// + /// /// - CustomAttributeSymbol[] GetCustomAttributes(); + CustomAttributeSymbol[] GetCustomAttributes(bool inherit = false); /// /// Returns an array of custom attributes defined on this member, identified by type, or an empty array if there are no custom attributes of that type. /// /// + /// /// - CustomAttributeSymbol[] GetCustomAttributes(ITypeSymbol attributeType); + CustomAttributeSymbol[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false); + + /// + /// Retrieves a custom attribute of a specified type that is applied to a specified member. + /// + /// + /// + /// + CustomAttributeSymbol? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false); /// /// Indicates whether one or more instance of is defined on this member. /// /// + /// /// - bool IsDefined(ITypeSymbol attributeType); + bool IsDefined(ITypeSymbol attributeType, bool inherit = false); } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs index 12920dd97..987c8af15 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Linq; using System.Runtime.CompilerServices; using Assembly = IKVM.Reflection.Assembly; @@ -135,17 +136,26 @@ public ITypeSymbol[] GetTypes() return ResolveTypeSymbols(_assembly.GetTypes()); } - public CustomAttributeSymbol[] GetCustomAttributes() + /// + public CustomAttributeSymbol[] GetCustomAttributes(bool inherit = false) { return ResolveCustomAttributes(_assembly.GetCustomAttributesData()); } - public CustomAttributeSymbol[] GetCustomAttributes(ITypeSymbol attributeType) + /// + public CustomAttributeSymbol[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) { return ResolveCustomAttributes(_assembly.__GetCustomAttributes(((IkvmReflectionTypeSymbol)attributeType).ReflectionObject, false)); } - public bool IsDefined(ITypeSymbol attributeType) + /// + public CustomAttributeSymbol? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) + { + return GetCustomAttributes(attributeType, inherit).FirstOrDefault(); + } + + /// + public bool IsDefined(ITypeSymbol attributeType, bool inherit = false) { return _assembly.IsDefined(((IkvmReflectionTypeSymbol)attributeType).ReflectionObject, false); } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs index e32966d91..70fcc692f 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq; using ConstructorInfo = IKVM.Reflection.ConstructorInfo; @@ -15,10 +16,41 @@ namespace IKVM.CoreLib.Symbols.IkvmReflection abstract class IkvmReflectionMemberSymbol : IkvmReflectionSymbol, IMemberSymbol { + /// + /// Concatinates the list of arrays. + /// + /// + /// + static T[] Concat(List? list) + { + if (list == null) + return []; + + var c = 0; + foreach (var i in list) + c += i.Length; + + if (c == 0) + return []; + + var t = 0; + var a = new T[c]; + foreach (var i in list) + { + Array.Copy(i, 0, a, t, i.Length); + t += i.Length; + } + + return a; + } + readonly IkvmReflectionModuleSymbol _module; readonly IkvmReflectionTypeSymbol? _type; readonly MemberInfo _member; + CustomAttributeSymbol[]? _customAttributes; + CustomAttributeSymbol[]? _inheritedCustomAttributes; + /// /// Initializes a new instance. /// @@ -126,37 +158,100 @@ protected internal override IkvmReflectionEventSymbol ResolveEventSymbol(EventIn return base.ResolveEventSymbol(@event); } + /// internal MemberInfo ReflectionObject => _member; + /// internal IkvmReflectionModuleSymbol ContainingModule => _module; + /// internal IkvmReflectionTypeSymbol? ContainingType => _type; + /// public virtual ITypeSymbol? DeclaringType => _member.DeclaringType is Type t ? Context.GetOrCreateTypeSymbol(t) : null; + /// public virtual System.Reflection.MemberTypes MemberType => (System.Reflection.MemberTypes)_member.MemberType; + /// public virtual int MetadataToken => _member.MetadataToken; + /// public virtual IModuleSymbol Module => Context.GetOrCreateModuleSymbol(_member.Module); + /// public virtual string Name => _member.Name; + /// public override bool IsMissing => _member.__IsMissing; - public virtual CustomAttributeSymbol[] GetCustomAttributes() + /// + public virtual CustomAttributeSymbol[] GetCustomAttributes(bool inherit = false) + { + if (inherit) + { + // check that we've already processed this + if (_inheritedCustomAttributes != null) + return _inheritedCustomAttributes; + + var self = _member; + var list = default(List?); + for (; ; ) + { + // get attribute for current member and append to list + var attr = ResolveMemberSymbol(self).GetCustomAttributes(false); + if (attr.Length > 0) + { + list ??= []; + list.Add(attr); + } + + var type = self as Type; + if (type != null) + { + type = type.BaseType; + if (type == null) + return _inheritedCustomAttributes ??= Concat(list); + + self = type; + continue; + } + + var method = self as MethodInfo; + if (method != null) + { + var prev = self; + method = method.GetBaseDefinition(); + if (method == null || method == prev) + return _inheritedCustomAttributes ??= Concat(list); + + self = method; + continue; + } + + return _inheritedCustomAttributes ??= Concat(list); + } + } + + return _customAttributes ??= ResolveCustomAttributes(_member.GetCustomAttributesData()); + } + + /// + public virtual CustomAttributeSymbol[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) { - return ResolveCustomAttributes(_member.GetCustomAttributesData()); + return ResolveCustomAttributes(_member.__GetCustomAttributes(((IkvmReflectionTypeSymbol)attributeType).ReflectionObject, inherit)); } - public virtual CustomAttributeSymbol[] GetCustomAttributes(ITypeSymbol attributeType) + /// + public virtual CustomAttributeSymbol? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) { - return ResolveCustomAttributes(_member.GetCustomAttributesData()).Where(i => i.AttributeType == attributeType).ToArray(); + return GetCustomAttributes(attributeType, inherit).FirstOrDefault(); } - public virtual bool IsDefined(ITypeSymbol attributeType) + /// + public virtual bool IsDefined(ITypeSymbol attributeType, bool inherit = false) { - return _member.IsDefined(((IkvmReflectionTypeSymbol)attributeType).ReflectionObject, false); + return _member.IsDefined(((IkvmReflectionTypeSymbol)attributeType).ReflectionObject, inherit); } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs index 9c30b305a..f1a88c657 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs @@ -2,6 +2,7 @@ using System.Diagnostics; using System.Linq; using System.Reflection.Metadata.Ecma335; +using System.Runtime.InteropServices; using System.Threading; using IKVM.Reflection; @@ -83,10 +84,7 @@ internal IkvmReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) _types ??= new IkvmReflectionTypeSymbol?[_typesSource.Length]; // index of current record is specified row - base - var idx = row - _typesBaseRow; - if (idx < 0) - throw new Exception(); - + var idx = row - _typesBaseRow - 1; Debug.Assert(idx >= 0); Debug.Assert(idx < _typesSource.Length); @@ -335,19 +333,25 @@ public ITypeSymbol ResolveType(int metadataToken, ITypeSymbol[]? genericTypeArgu } /// - public CustomAttributeSymbol[] GetCustomAttributes() + public CustomAttributeSymbol[] GetCustomAttributes(bool inherit = false) { return ResolveCustomAttributes(_module.GetCustomAttributesData()); } /// - public CustomAttributeSymbol[] GetCustomAttributes(ITypeSymbol attributeType) + public CustomAttributeSymbol[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) { return ResolveCustomAttributes(_module.__GetCustomAttributes(((IkvmReflectionTypeSymbol)attributeType).ReflectionObject, false)); } /// - public bool IsDefined(ITypeSymbol attributeType) + public CustomAttributeSymbol? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) + { + return GetCustomAttributes(attributeType, inherit).FirstOrDefault(); + } + + /// + public bool IsDefined(ITypeSymbol attributeType, bool inherit = false) { return _module.IsDefined(((IkvmReflectionTypeSymbol)attributeType).ReflectionObject, false); } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterSymbol.cs index c63d92cad..80a558f4b 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterSymbol.cs @@ -1,4 +1,6 @@ using System; +using System.Linq; +using System.Runtime.InteropServices; using ParameterInfo = IKVM.Reflection.ParameterInfo; @@ -52,21 +54,29 @@ public IkvmReflectionParameterSymbol(IkvmReflectionSymbolContext context, IkvmRe public int Position => _parameter.Position; - public CustomAttributeSymbol[] GetCustomAttributes() + /// + public CustomAttributeSymbol[] GetCustomAttributes(bool inherit = false) { return ResolveCustomAttributes(_parameter.GetCustomAttributesData()); } - public CustomAttributeSymbol[] GetCustomAttributes(ITypeSymbol attributeType) + /// + public virtual CustomAttributeSymbol[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) { - return ResolveCustomAttributes(_parameter.__GetCustomAttributes(((IkvmReflectionTypeSymbol)attributeType).ReflectionObject, false)); + return ResolveCustomAttributes(_parameter.__GetCustomAttributes(((IkvmReflectionTypeSymbol)attributeType).ReflectionObject, inherit)); } - public bool IsDefined(ITypeSymbol attributeType) + /// + public virtual CustomAttributeSymbol? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) { - return _parameter.IsDefined(((IkvmReflectionTypeSymbol)attributeType).ReflectionObject, false); + return GetCustomAttributes(attributeType, inherit).FirstOrDefault(); } + /// + public virtual bool IsDefined(ITypeSymbol attributeType, bool inherit = false) + { + return _parameter.IsDefined(((IkvmReflectionTypeSymbol)attributeType).ReflectionObject, inherit); + } } } \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs index 516514618..bd5721750 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs @@ -39,88 +39,115 @@ internal ReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) return _modules.GetValue(module, _ => new ReflectionModuleSymbol(Context, _)); } + /// public IEnumerable DefinedTypes => ResolveTypeSymbols(_assembly.DefinedTypes); + /// public IMethodSymbol? EntryPoint => _assembly.EntryPoint is { } m ? ResolveMethodSymbol(m) : null; + /// public IEnumerable ExportedTypes => ResolveTypeSymbols(_assembly.ExportedTypes); + /// public string? FullName => _assembly.FullName; + /// public string ImageRuntimeVersion => _assembly.ImageRuntimeVersion; + /// public IModuleSymbol ManifestModule => ResolveModuleSymbol(_assembly.ManifestModule); + /// public IEnumerable Modules => ResolveModuleSymbols(_assembly.Modules); + /// public ITypeSymbol[] GetExportedTypes() { return ResolveTypeSymbols(_assembly.GetExportedTypes()); } + /// public IModuleSymbol? GetModule(string name) { return _assembly.GetModule(name) is Module m ? GetOrCreateModuleSymbol(m) : null; } + /// public IModuleSymbol[] GetModules() { return ResolveModuleSymbols(_assembly.GetModules()); } + /// public IModuleSymbol[] GetModules(bool getResourceModules) { return ResolveModuleSymbols(_assembly.GetModules(getResourceModules)); } + /// public AssemblyName GetName() { return _assembly.GetName(); } + /// public AssemblyName GetName(bool copiedName) { return _assembly.GetName(copiedName); } + /// public AssemblyName[] GetReferencedAssemblies() { return _assembly.GetReferencedAssemblies(); } + /// public ITypeSymbol? GetType(string name, bool throwOnError) { return _assembly.GetType(name, throwOnError) is Type t ? Context.GetOrCreateTypeSymbol(t) : null; } + /// public ITypeSymbol? GetType(string name, bool throwOnError, bool ignoreCase) { return _assembly.GetType(name, throwOnError, ignoreCase) is Type t ? Context.GetOrCreateTypeSymbol(t) : null; } + /// public ITypeSymbol? GetType(string name) { return _assembly.GetType(name) is Type t ? Context.GetOrCreateTypeSymbol(t) : null; } + /// public ITypeSymbol[] GetTypes() { return ResolveTypeSymbols(_assembly.GetTypes()); } - public CustomAttributeSymbol[] GetCustomAttributes() + /// + public CustomAttributeSymbol[] GetCustomAttributes(bool inherit = false) { return ResolveCustomAttributes(_assembly.GetCustomAttributesData()); } - public CustomAttributeSymbol[] GetCustomAttributes(ITypeSymbol attributeType) + /// + public CustomAttributeSymbol[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) { - return ResolveCustomAttributes(_assembly.GetCustomAttributesData()).Where(i => i.AttributeType == attributeType).ToArray(); + return ResolveCustomAttributes(_assembly.GetCustomAttributesData().Where(i => i.AttributeType == ((ReflectionTypeSymbol)attributeType).ReflectionObject)); } - public bool IsDefined(ITypeSymbol attributeType) + /// + public CustomAttributeSymbol? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) { - return _assembly.IsDefined(((ReflectionTypeSymbol)attributeType).ReflectionObject); + return GetCustomAttributes(attributeType, inherit).FirstOrDefault(); + } + + /// + public bool IsDefined(ITypeSymbol attributeType, bool inherit = false) + { + return _assembly.IsDefined(((ReflectionTypeSymbol)attributeType).ReflectionObject, false); } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs index 28e417cab..850276ccf 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq; using System.Reflection; @@ -11,22 +12,53 @@ namespace IKVM.CoreLib.Symbols.Reflection abstract class ReflectionMemberSymbol : ReflectionSymbol, IMemberSymbol { - readonly ReflectionModuleSymbol _module; - readonly ReflectionTypeSymbol? _type; + /// + /// Concatinates the list of arrays. + /// + /// + /// + static T[] Concat(List? list) + { + if (list == null) + return []; + + var c = 0; + foreach (var i in list) + c += i.Length; + + if (c == 0) + return []; + + var t = 0; + var a = new T[c]; + foreach (var i in list) + { + Array.Copy(i, 0, a, t, i.Length); + t += i.Length; + } + + return a; + } + + readonly ReflectionModuleSymbol _containingModule; + readonly ReflectionTypeSymbol? _containingType; readonly MemberInfo _member; + CustomAttributeSymbol[]? _customAttributes; + CustomAttributeSymbol[]? _inheritedCustomAttributes; + /// /// Initializes a new instance. /// /// - /// - /// + /// + /// /// - public ReflectionMemberSymbol(ReflectionSymbolContext context, ReflectionModuleSymbol module, ReflectionTypeSymbol? type, MemberInfo member) : + public ReflectionMemberSymbol(ReflectionSymbolContext context, ReflectionModuleSymbol containingModule, ReflectionTypeSymbol? containingType, MemberInfo member) : base(context) { - _module = module ?? throw new ArgumentNullException(nameof(module)); - _type = type; + _containingModule = containingModule ?? throw new ArgumentNullException(nameof(containingModule)); + _containingType = containingType; _member = member ?? throw new ArgumentNullException(nameof(member)); } @@ -37,10 +69,10 @@ public ReflectionMemberSymbol(ReflectionSymbolContext context, ReflectionModuleS /// protected internal override ReflectionTypeSymbol ResolveTypeSymbol(Type type) { - if (_type != null && type == _type.ReflectionObject) - return _type; + if (_containingType != null && type == _containingType.ReflectionObject) + return _containingType; else if (type.Module == _member.Module) - return _module.GetOrCreateTypeSymbol(type); + return _containingModule.GetOrCreateTypeSymbol(type); else return base.ResolveTypeSymbol(type); } @@ -52,10 +84,10 @@ protected internal override ReflectionTypeSymbol ResolveTypeSymbol(Type type) /// protected internal override ReflectionConstructorSymbol ResolveConstructorSymbol(ConstructorInfo ctor) { - if (_type != null && ctor.DeclaringType == _type.ReflectionObject) - return _type.GetOrCreateConstructorSymbol(ctor); + if (_containingType != null && ctor.DeclaringType == _containingType.ReflectionObject) + return _containingType.GetOrCreateConstructorSymbol(ctor); else if (ctor.DeclaringType != null && ctor.Module == _member.Module) - return _module.GetOrCreateTypeSymbol(ctor.DeclaringType).GetOrCreateConstructorSymbol(ctor); + return _containingModule.GetOrCreateTypeSymbol(ctor.DeclaringType).GetOrCreateConstructorSymbol(ctor); else return base.ResolveConstructorSymbol(ctor); } @@ -67,10 +99,10 @@ protected internal override ReflectionConstructorSymbol ResolveConstructorSymbol /// protected internal override ReflectionMethodSymbol ResolveMethodSymbol(MethodInfo method) { - if (_type != null && method.DeclaringType == _type.ReflectionObject) - return _type.GetOrCreateMethodSymbol(method); + if (_containingType != null && method.DeclaringType == _containingType.ReflectionObject) + return _containingType.GetOrCreateMethodSymbol(method); else if (method.DeclaringType != null && method.Module == _member.Module) - return _module.GetOrCreateTypeSymbol(method.DeclaringType).GetOrCreateMethodSymbol(method); + return _containingModule.GetOrCreateTypeSymbol(method.DeclaringType).GetOrCreateMethodSymbol(method); else return base.ResolveMethodSymbol(method); } @@ -82,10 +114,10 @@ protected internal override ReflectionMethodSymbol ResolveMethodSymbol(MethodInf /// protected internal override ReflectionFieldSymbol ResolveFieldSymbol(FieldInfo field) { - if (_type != null && field.DeclaringType == _type.ReflectionObject) - return _type.GetOrCreateFieldSymbol(field); + if (_containingType != null && field.DeclaringType == _containingType.ReflectionObject) + return _containingType.GetOrCreateFieldSymbol(field); else if (field.DeclaringType != null && field.Module == _member.Module) - return _module.GetOrCreateTypeSymbol(field.DeclaringType).GetOrCreateFieldSymbol(field); + return _containingModule.GetOrCreateTypeSymbol(field.DeclaringType).GetOrCreateFieldSymbol(field); else return base.ResolveFieldSymbol(field); } @@ -99,10 +131,10 @@ protected internal override ReflectionFieldSymbol ResolveFieldSymbol(FieldInfo f protected internal override ReflectionPropertySymbol ResolvePropertySymbol(PropertyInfo property) { - if (_type != null && property.DeclaringType == _type.ReflectionObject) - return _type.GetOrCreatePropertySymbol(property); + if (_containingType != null && property.DeclaringType == _containingType.ReflectionObject) + return _containingType.GetOrCreatePropertySymbol(property); else if (property.DeclaringType != null && property.Module == _member.Module) - return _module.GetOrCreateTypeSymbol(property.DeclaringType).GetOrCreatePropertySymbol(property); + return _containingModule.GetOrCreateTypeSymbol(property.DeclaringType).GetOrCreatePropertySymbol(property); else return base.ResolvePropertySymbol(property); } @@ -114,10 +146,10 @@ protected internal override ReflectionPropertySymbol ResolvePropertySymbol(Prope /// protected internal override ReflectionEventSymbol ResolveEventSymbol(EventInfo @event) { - if (_type != null && @event.DeclaringType == _type.ReflectionObject) - return _type.GetOrCreateEventSymbol(@event); + if (_containingType != null && @event.DeclaringType == _containingType.ReflectionObject) + return _containingType.GetOrCreateEventSymbol(@event); else if (@event.DeclaringType != null && @event.Module == _member.Module) - return _module.GetOrCreateTypeSymbol(@event.DeclaringType).GetOrCreateEventSymbol(@event); + return _containingModule.GetOrCreateTypeSymbol(@event.DeclaringType).GetOrCreateEventSymbol(@event); else return base.ResolveEventSymbol(@event); } @@ -130,12 +162,12 @@ protected internal override ReflectionEventSymbol ResolveEventSymbol(EventInfo @ /// /// Gets the which contains the metadata of this member. /// - internal ReflectionModuleSymbol ContainingModule => _module; + internal ReflectionModuleSymbol ContainingModule => _containingModule; /// /// Gets the which contains the metadata of this member, or null if the member is not a member of a type. /// - internal ReflectionTypeSymbol? ContainingType => _type; + internal ReflectionTypeSymbol? ContainingType => _containingType; /// public virtual IModuleSymbol Module => Context.GetOrCreateModuleSymbol(_member.Module); @@ -153,21 +185,72 @@ protected internal override ReflectionEventSymbol ResolveEventSymbol(EventInfo @ public virtual string Name => _member.Name; /// - public virtual CustomAttributeSymbol[] GetCustomAttributes() + public virtual CustomAttributeSymbol[] GetCustomAttributes(bool inherit = false) + { + if (inherit) + { + // check that we've already processed this + if (_inheritedCustomAttributes != null) + return _inheritedCustomAttributes; + + var self = _member; + var list = default(List?); + for (; ; ) + { + // get attribute for current member and append to list + var attr = ResolveMemberSymbol(self).GetCustomAttributes(false); + if (attr.Length > 0) + { + list ??= []; + list.Add(attr); + } + + var type = self as Type; + if (type != null) + { + type = type.BaseType; + if (type == null) + return _inheritedCustomAttributes ??= Concat(list); + + self = type; + continue; + } + + var method = self as MethodInfo; + if (method != null) + { + var prev = self; + method = method.GetBaseDefinition(); + if (method == null || method == prev) + return _inheritedCustomAttributes ??= Concat(list); + + self = method; + continue; + } + + return _inheritedCustomAttributes ??= Concat(list); + } + } + + return _customAttributes ??= ResolveCustomAttributes(_member.GetCustomAttributesData()); + } + + /// + public virtual CustomAttributeSymbol[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) { - return ResolveCustomAttributes(_member.GetCustomAttributesData()); + return GetCustomAttributes(inherit).Where(i => i.AttributeType == attributeType).ToArray(); } /// - public virtual CustomAttributeSymbol[] GetCustomAttributes(ITypeSymbol attributeType) + public virtual CustomAttributeSymbol? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) { - return ResolveCustomAttributes(_member.GetCustomAttributesData()).Where(i => i.AttributeType == attributeType).ToArray(); + return GetCustomAttributes(attributeType, inherit).FirstOrDefault(); } /// - public virtual bool IsDefined(ITypeSymbol attributeType) + public virtual bool IsDefined(ITypeSymbol attributeType, bool inherit = false) { - return _member.IsDefined(((ReflectionTypeSymbol)attributeType).ReflectionObject); + return _member.IsDefined(((ReflectionTypeSymbol)attributeType).ReflectionObject, inherit); } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs index 3b9612481..0e8bc370f 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Reflection; using System.Reflection.Metadata.Ecma335; +using System.Runtime.InteropServices; using System.Threading; namespace IKVM.CoreLib.Symbols.Reflection @@ -84,10 +85,7 @@ internal ReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) Interlocked.CompareExchange(ref _types, new ReflectionTypeSymbol?[_typesSource.Length], null); // index of current record is specified row - base - var idx = row - _typesBaseRow; - if (idx < 0) - throw new Exception(); - + var idx = row - _typesBaseRow - 1; Debug.Assert(idx >= 0); Debug.Assert(idx < _typesSource.Length); @@ -330,21 +328,27 @@ public ITypeSymbol ResolveType(int metadataToken, ITypeSymbol[]? genericTypeArgu } /// - public CustomAttributeSymbol[] GetCustomAttributes() + public CustomAttributeSymbol[] GetCustomAttributes(bool inherit = false) { return ResolveCustomAttributes(_module.GetCustomAttributesData()); } /// - public CustomAttributeSymbol[] GetCustomAttributes(ITypeSymbol attributeType) + public CustomAttributeSymbol[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) + { + return ResolveCustomAttributes(_module.GetCustomAttributesData().Where(i => i.AttributeType == ((ReflectionTypeSymbol)attributeType).ReflectionObject)); + } + + /// + public CustomAttributeSymbol? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) { - return ResolveCustomAttributes(_module.GetCustomAttributesData()).Where(i => i.AttributeType == attributeType).ToArray(); + return GetCustomAttributes(attributeType, inherit).FirstOrDefault(); } /// - public bool IsDefined(ITypeSymbol attributeType) + public bool IsDefined(ITypeSymbol attributeType, bool inherit = false) { - return _module.IsDefined(((ReflectionTypeSymbol)attributeType).ReflectionObject); + return _module.IsDefined(((ReflectionTypeSymbol)attributeType).ReflectionObject, false); } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterSymbol.cs index 1bf805672..2ad73f260 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterSymbol.cs @@ -11,6 +11,8 @@ class ReflectionParameterSymbol : ReflectionSymbol, IParameterSymbol readonly ParameterInfo _parameter; readonly ReflectionMethodBaseSymbol _method; + CustomAttributeSymbol[]? _customAttributes; + /// /// Initializes a new instance. /// @@ -52,19 +54,28 @@ public ReflectionParameterSymbol(ReflectionSymbolContext context, ReflectionMeth public int Position => _parameter.Position; - public CustomAttributeSymbol[] GetCustomAttributes() + /// + public CustomAttributeSymbol[] GetCustomAttributes(bool inherit = false) + { + return _customAttributes ??= ResolveCustomAttributes(_parameter.GetCustomAttributesData()); + } + + /// + public virtual CustomAttributeSymbol[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) { - return ResolveCustomAttributes(_parameter.GetCustomAttributesData()); + return GetCustomAttributes(inherit).Where(i => i.AttributeType == attributeType).ToArray(); } - public CustomAttributeSymbol[] GetCustomAttributes(ITypeSymbol attributeType) + /// + public virtual CustomAttributeSymbol? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) { - return ResolveCustomAttributes(_parameter.GetCustomAttributesData()).Where(i => i.AttributeType == attributeType).ToArray(); + return GetCustomAttributes(attributeType, inherit).FirstOrDefault(); } - public bool IsDefined(ITypeSymbol attributeType) + /// + public virtual bool IsDefined(ITypeSymbol attributeType, bool inherit = false) { - return _parameter.IsDefined(((ReflectionTypeSymbol)attributeType).ReflectionObject); + return _parameter.IsDefined(((ReflectionTypeSymbol)attributeType).ReflectionObject, inherit); } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbol.cs index 03ad96cf3..f0aa2a89a 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbol.cs @@ -350,6 +350,20 @@ protected internal CustomAttributeSymbol[] ResolveCustomAttributes(IList + /// Transforms a custom set of custom attribute data records to a symbol record. + /// + /// + /// + protected internal CustomAttributeSymbol[] ResolveCustomAttributes(IEnumerable attributes) + { + var a = new List(); + foreach (var i in attributes) + a.Add(ResolveCustomAttribute(i)); + + return a.ToArray(); + } + /// /// Transforms a custom attribute data record to a symbol record. /// diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.cs index 04a159d57..c864042da 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.cs @@ -26,8 +26,6 @@ Jeroen Frijters using System.Diagnostics; using IKVM.Attributes; -using System.Collections.Concurrent; -using System.Runtime.CompilerServices; #if IMPORTER || EXPORTER using IKVM.Reflection; From 4119fcb2430e1f2eccbcd414c5fb78c78b13463c Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Sun, 15 Sep 2024 13:58:04 -0500 Subject: [PATCH 02/51] Builder infrastructure mostly in place. --- Directory.Build.props | 4 + IKVM.deps.targets | 1 + .../Collections/IndexRangeDictionaryTests.cs | 56 + .../IkvmReflectionSymbolTests.cs | 27 +- .../Reflection/ReflectionSymbolTests.cs | 298 +- .../Collections/IndexRangeDictionary.cs | 140 + src/IKVM.CoreLib/IKVM.CoreLib.csproj | 1 + src/IKVM.CoreLib/Symbols/CustomAttribute.cs | 13 + ...ent.cs => CustomAttributeNamedArgument.cs} | 4 +- .../Symbols/CustomAttributeSymbol.cs | 12 - ...ent.cs => CustomAttributeTypedArgument.cs} | 2 +- .../Symbols/Emit/IAssemblySymbolBuilder.cs | 29 + .../Symbols/Emit/IConstructorSymbolBuilder.cs | 50 + .../Symbols/Emit/ICustomAttributeBuilder.cs | 11 + .../Symbols/Emit/IEventSymbolBuilder.cs | 46 + .../Symbols/Emit/IFieldSymbolBuilder.cs | 34 + .../IGenericTypeParameterSymbolBuilder.cs | 11 + src/IKVM.CoreLib/Symbols/Emit/IILGenerator.cs | 11 + .../Symbols/Emit/IMethodSymbolBuilder.cs | 80 + .../Symbols/Emit/IModuleSymbolBuilder.cs | 90 + .../Symbols/Emit/IParameterSymbolBuilder.cs | 27 + .../Symbols/Emit/IPropertySymbolBuilder.cs | 22 + .../Symbols/Emit/ISymbolBuilder.cs | 32 + .../Symbols/Emit/ITypeSymbolBuilder.cs | 326 ++ src/IKVM.CoreLib/Symbols/IAssemblySymbol.cs | 2 +- ...rovider.cs => ICustomAttributeProvider.cs} | 8 +- src/IKVM.CoreLib/Symbols/IMemberSymbol.cs | 2 +- src/IKVM.CoreLib/Symbols/IMethodSymbol.cs | 2 +- src/IKVM.CoreLib/Symbols/IModuleSymbol.cs | 2 +- src/IKVM.CoreLib/Symbols/IParameterSymbol.cs | 14 +- src/IKVM.CoreLib/Symbols/ISymbol.cs | 5 + src/IKVM.CoreLib/Symbols/ISymbolResolver.cs | 2 +- src/IKVM.CoreLib/Symbols/ITypeSymbol.cs | 50 +- .../IkvmReflectionAssemblySymbol.cs | 31 +- .../IkvmReflectionMemberSymbol.cs | 16 +- .../IkvmReflectionMethodBaseSymbol.cs | 30 + .../IkvmReflectionMethodSymbol.cs | 2 +- .../IkvmReflectionModuleSymbol.cs | 9 +- .../IkvmReflectionParameterSymbol.cs | 43 +- .../IkvmReflection/IkvmReflectionSymbol.cs | 48 +- .../IkvmReflectionTypeSymbol.cs | 135 +- .../Emit/ReflectionAssemblySymbolBuilder.cs | 49 + .../ReflectionConstructorSymbolBuilder.cs | 74 + .../Emit/ReflectionCustomAttributeBuilder.cs | 29 + .../Emit/ReflectionEventBuilderInfo.cs | 81 + .../Emit/ReflectionEventSymbolBuilder.cs | 72 + .../Emit/ReflectionFieldSymbolBuilder.cs | 88 + .../Emit/ReflectionMethodBaseSymbolBuilder.cs | 49 + .../Emit/ReflectionMethodSymbolBuilder.cs | 107 + .../Emit/ReflectionModuleSymbolBuilder.cs | 86 + .../Emit/ReflectionParameterSymbolBuilder.cs | 102 + .../Emit/ReflectionPropertySymbolBuilder.cs | 47 + .../Emit/ReflectionSymbolBuilder.cs | 94 + .../Emit/ReflectionTypeSymbolBuilder.cs | 238 ++ .../Reflection/ReflectionAssemblySymbol.cs | 24 +- .../Reflection/ReflectionEventSymbol.cs | 2 +- .../Reflection/ReflectionFieldSymbol.cs | 18 +- .../Reflection/ReflectionMemberSymbol.cs | 59 +- .../Reflection/ReflectionMethodBaseSymbol.cs | 55 +- .../Reflection/ReflectionMethodSymbol.cs | 27 +- .../Reflection/ReflectionModuleSymbol.cs | 319 +- .../Reflection/ReflectionParameterSymbol.cs | 125 +- .../Symbols/Reflection/ReflectionSymbol.cs | 144 +- .../Reflection/ReflectionSymbolContext.cs | 50 +- .../Reflection/ReflectionTypeSymbol.cs | 560 ++-- .../Symbols/Reflection/ReflectionUtil.cs | 146 + src/IKVM.CoreLib/System/TypeExtensions.cs | 450 +++ .../ReaderWriterLockSlimExtensions.cs | 99 + src/IKVM.Reflection/ArrayType.cs | 2 +- src/IKVM.Reflection/CustomAttributeData.cs | 4 +- src/IKVM.Reflection/Emit/ModuleBuilder.cs | 2 +- src/IKVM.Reflection/Signature.cs | 2 +- src/IKVM.Reflection/Type.cs | 13 +- src/IKVM.Runtime/Annotation.cs | 49 +- src/IKVM.Runtime/AttributeHelper.cs | 1596 +++++----- .../Attributes/LineNumberTableAttribute.cs | 425 +-- src/IKVM.Runtime/ByteCodeHelperMethods.cs | 181 +- src/IKVM.Runtime/CodeEmitter.cs | 130 +- src/IKVM.Runtime/CodeEmitterLocal.cs | 15 +- src/IKVM.Runtime/DefineMethodHelper.cs | 2 +- src/IKVM.Runtime/DynamicClassLoader.cs | 4 +- src/IKVM.Runtime/EnumHelper.cs | 28 +- src/IKVM.Runtime/IRuntimeSymbolResolver.cs | 28 + src/IKVM.Runtime/JNI/JNIEnv.cs | 2 +- src/IKVM.Runtime/JVM.Resolver.cs | 12 +- .../Java/Externs/java/lang/Class.cs | 41 +- .../Externs/sun/reflect/ReflectionFactory.cs | 20 +- src/IKVM.Runtime/LambdaMetafactory.cs | 4 +- src/IKVM.Runtime/MethodHandleUtil.root.cs | 83 +- src/IKVM.Runtime/ReflectUtil.cs | 67 +- .../RuntimeAccessStubJavaMethod.cs | 11 +- src/IKVM.Runtime/RuntimeAnonymousJavaType.cs | 13 +- src/IKVM.Runtime/RuntimeArrayJavaType.cs | 10 +- .../RuntimeAssemblyClassLoader.cs | 109 +- .../RuntimeAssemblyClassLoaderFactory.cs | 13 +- .../RuntimeByteCodeJavaType.FinishContext.cs | 22 +- ...ypeImpl.DelegateInvokeStubMethodWrapper.cs | 50 +- .../RuntimeByteCodeJavaType.JavaTypeImpl.cs | 2813 +++++++++-------- src/IKVM.Runtime/RuntimeByteCodeJavaType.cs | 2 +- .../RuntimeByteCodePropertyJavaField.cs | 4 +- src/IKVM.Runtime/RuntimeClassLoader.cs | 2 +- src/IKVM.Runtime/RuntimeClassLoaderFactory.cs | 29 +- src/IKVM.Runtime/RuntimeConstantJavaField.cs | 4 +- .../RuntimeConstructorAccessStubJavaMethod.cs | 9 +- src/IKVM.Runtime/RuntimeContext.cs | 28 +- .../RuntimeDefaultInterfaceJavaMethod.cs | 13 +- src/IKVM.Runtime/RuntimeGhostJavaMethod.cs | 15 +- src/IKVM.Runtime/RuntimeJavaField.cs | 39 +- src/IKVM.Runtime/RuntimeJavaMethod.cs | 65 +- src/IKVM.Runtime/RuntimeJavaType.cs | 224 +- src/IKVM.Runtime/RuntimeJavaTypeFactory.cs | 11 +- ...ntimeManagedByteCodeAccessStubJavaField.cs | 14 +- ...eJavaType.DelegateConstructorJavaMethod.cs | 13 +- ...meManagedByteCodeJavaType.GhostJavaType.cs | 42 +- ...agedByteCodeJavaType.RemappedJavaMethod.cs | 25 +- ...anagedByteCodeJavaType.RemappedJavaType.cs | 44 +- .../RuntimeManagedByteCodeJavaType.cs | 305 +- ...RuntimeManagedByteCodePropertyJavaField.cs | 11 +- ...tionJavaType.MultipleAnnotationJavaType.cs | 2 +- ...gedJavaType.AttributeAnnotationJavaType.cs | 148 +- .../RuntimeManagedJavaType.ByRefJavaMethod.cs | 9 +- .../RuntimeManagedJavaType.CloneJavaMethod.cs | 2 +- ...agedJavaType.DelegateInnerClassJavaType.cs | 23 +- ...RuntimeManagedJavaType.EnumEnumJavaType.cs | 27 +- ...timeManagedJavaType.OpenGenericJavaType.cs | 9 +- src/IKVM.Runtime/RuntimeManagedJavaType.cs | 114 +- .../RuntimeManagedJavaTypeFactory.cs | 10 +- src/IKVM.Runtime/RuntimePrimitiveJavaType.cs | 10 +- .../RuntimePrivateInterfaceJavaMethod.cs | 7 +- src/IKVM.Runtime/RuntimeSimpleJavaField.cs | 10 +- src/IKVM.Runtime/RuntimeSmartJavaMethod.cs | 3 +- src/IKVM.Runtime/RuntimeTypicalJavaMethod.cs | 4 +- src/IKVM.Runtime/RuntimeUnloadableJavaType.cs | 20 +- .../RuntimeVolatileLongDoubleJavaField.cs | 4 +- src/IKVM.Runtime/SymbolExtensions.cs | 60 + src/IKVM.Runtime/Types.cs | 115 +- .../Vfs/VfsAssemblyClassDirectory.cs | 2 +- src/IKVM.Runtime/compiler.cs | 6 +- .../IKVM.Tools.Exporter.csproj | 1 + src/IKVM.Tools.Importer/FakeTypes.cs | 49 +- src/IKVM.Tools.Importer/ImportClassLoader.cs | 13 +- src/IKVM.Tools.Importer/StaticCompiler.cs | 14 +- 142 files changed, 7824 insertions(+), 4410 deletions(-) create mode 100644 src/IKVM.CoreLib.Tests/Collections/IndexRangeDictionaryTests.cs create mode 100644 src/IKVM.CoreLib/Collections/IndexRangeDictionary.cs create mode 100644 src/IKVM.CoreLib/Symbols/CustomAttribute.cs rename src/IKVM.CoreLib/Symbols/{CustomAttributeSymbolNamedArgument.cs => CustomAttributeNamedArgument.cs} (50%) delete mode 100644 src/IKVM.CoreLib/Symbols/CustomAttributeSymbol.cs rename src/IKVM.CoreLib/Symbols/{CustomAttributeSymbolTypedArgument.cs => CustomAttributeTypedArgument.cs} (60%) create mode 100644 src/IKVM.CoreLib/Symbols/Emit/IAssemblySymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Emit/IConstructorSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Emit/ICustomAttributeBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Emit/IEventSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Emit/IFieldSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Emit/IGenericTypeParameterSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Emit/IILGenerator.cs create mode 100644 src/IKVM.CoreLib/Symbols/Emit/IMethodSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Emit/IModuleSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Emit/IParameterSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Emit/IPropertySymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Emit/ISymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Emit/ITypeSymbolBuilder.cs rename src/IKVM.CoreLib/Symbols/{ICustomAttributeSymbolProvider.cs => ICustomAttributeProvider.cs} (81%) create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionConstructorSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionCustomAttributeBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionEventBuilderInfo.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionEventSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionFieldSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodBaseSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionModuleSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionParameterSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionPropertySymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/ReflectionUtil.cs create mode 100644 src/IKVM.CoreLib/System/TypeExtensions.cs create mode 100644 src/IKVM.CoreLib/Threading/ReaderWriterLockSlimExtensions.cs create mode 100644 src/IKVM.Runtime/IRuntimeSymbolResolver.cs diff --git a/Directory.Build.props b/Directory.Build.props index bde86f5e5..bc21f1c58 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -7,6 +7,10 @@ win-x64;win-x86;win-arm64;linux-x64;linux-arm;linux-arm64;linux-musl-x64;linux-musl-arm;linux-musl-arm64;osx-x64;osx-arm64 $(SupportedImageRuntimes) + win-x64;win-x86 + win-x64;win-x86 + win-x64;win-x86 + <_SupportedRuntimes>;$(SupportedRuntimes); <_EnabledRuntimes>;$(EnabledRuntimes); <_SupportedToolRuntimes>;$(SupportedToolRuntimes); diff --git a/IKVM.deps.targets b/IKVM.deps.targets index 7f0a15af2..e12e96949 100644 --- a/IKVM.deps.targets +++ b/IKVM.deps.targets @@ -16,6 +16,7 @@ + diff --git a/src/IKVM.CoreLib.Tests/Collections/IndexRangeDictionaryTests.cs b/src/IKVM.CoreLib.Tests/Collections/IndexRangeDictionaryTests.cs new file mode 100644 index 000000000..b42cc97a8 --- /dev/null +++ b/src/IKVM.CoreLib.Tests/Collections/IndexRangeDictionaryTests.cs @@ -0,0 +1,56 @@ +using FluentAssertions; + +using IKVM.CoreLib.Collections; + +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace IKVM.CoreLib.Tests.Collections +{ + + [TestClass] + public class IndexRangeDictionaryTests + { + + [TestMethod] + public void CanAddBasicItem() + { + var d = new IndexRangeDictionary(); + d[0] = "Item1"; + d[0].Should().Be("Item1"); + } + + [TestMethod] + public void CanAddOffsetItem() + { + var d = new IndexRangeDictionary(); + d[10] = "Item1"; + d[10].Should().Be("Item1"); + } + + [TestMethod] + public void CanAddSparseRange() + { + var d = new IndexRangeDictionary(); + d[10] = "Item1"; + d[20] = "Item2"; + d[9].Should().BeNull(); + d[10].Should().Be("Item1"); + d[11].Should().BeNull(); + d[19].Should().BeNull(); + d[20].Should().Be("Item2"); + d[21].Should().BeNull(); + } + + [TestMethod] + public void CanAddMaxBeforeMin() + { + var d = new IndexRangeDictionary(); + d[20] = "Item1"; + d[10] = "Item2"; + d[20].Should().Be("Item1"); + d[10].Should().Be("Item2"); + } + + } + +} diff --git a/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs b/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs index 8e933cc67..22936c64d 100644 --- a/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs +++ b/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs @@ -192,14 +192,37 @@ public void CanGetMethod() m.IsGenericMethodDefinition.Should().BeFalse(); m.IsPublic.Should().BeTrue(); m.IsPrivate.Should().BeFalse(); + } + + [System.AttributeUsage(System.AttributeTargets.Class)] + class AttributeWithType : System.Attribute + { + + public AttributeWithType(System.Type type) + { + Type = type; + } + + public System.Type Type { get; } + + } + + [AttributeWithType(typeof(object))] + class ClassWithAttributeWithType + { + + + } [TestMethod] public void CanReadCustomAttributes() { var c = new IkvmReflectionSymbolContext(); - var s = c.GetOrCreateTypeSymbol(coreAssembly!.GetType("System.AttributeUsageAttribute")); - var a = s.GetCustomAttribute(s); + var s = c.GetOrCreateTypeSymbol(thisAssembly!.GetType("IKVM.CoreLib.Tests.Symbols.IkvmReflection.IkvmReflectionSymbolTests+ClassWithAttributeWithType")); + var a = s.GetCustomAttribute(c.GetOrCreateTypeSymbol(thisAssembly!.GetType("IKVM.CoreLib.Tests.Symbols.IkvmReflection.IkvmReflectionSymbolTests+AttributeWithType"))); + var v = a.Value.ConstructorArguments[0].Value; + v.Should().BeOfType(); } } diff --git a/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs b/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs index a63114293..efbd5e284 100644 --- a/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs +++ b/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs @@ -1,8 +1,11 @@ using System; +using System.Reflection; +using System.Reflection.Emit; using FluentAssertions; using IKVM.CoreLib.Symbols.Reflection; +using IKVM.CoreLib.Symbols.Reflection.Emit; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -92,7 +95,7 @@ public void EnumTypeShouldBeSame() } [TestMethod] - public void CanGetType() + public void CanResolveType() { var c = new ReflectionSymbolContext(); var s = c.GetOrCreateTypeSymbol(typeof(object)); @@ -101,7 +104,7 @@ public void CanGetType() } [TestMethod] - public void CanGetFieldOfGenericTypeDefinition() + public void CanResolveFieldOfGenericTypeDefinition() { var c = new ReflectionSymbolContext(); var s = c.GetOrCreateTypeSymbol(typeof(Foo<>)); @@ -114,7 +117,7 @@ public void CanGetFieldOfGenericTypeDefinition() } [TestMethod] - public void CanGetFieldOfGenericType() + public void CanResolveFieldOfGenericType() { var c = new ReflectionSymbolContext(); var s = c.GetOrCreateTypeSymbol(typeof(Foo)); @@ -128,7 +131,7 @@ public void CanGetFieldOfGenericType() } [TestMethod] - public void CanGetMethod() + public void CanResolveMethod() { var c = new ReflectionSymbolContext(); var s = c.GetOrCreateTypeSymbol(typeof(object)); @@ -140,14 +143,297 @@ public void CanGetMethod() m.IsGenericMethodDefinition.Should().BeFalse(); m.IsPublic.Should().BeTrue(); m.IsPrivate.Should().BeFalse(); + } + + [TestMethod] + public void CanResolveParameters() + { + var c = new ReflectionSymbolContext(); + var s = c.GetOrCreateTypeSymbol(typeof(object)); + var m = s.GetMethod("ReferenceEquals"); + m.Name.Should().Be("ReferenceEquals"); + m.ReturnType.Should().BeSameAs(c.GetOrCreateTypeSymbol(typeof(bool))); + m.ReturnParameter.ParameterType.Should().BeSameAs(c.GetOrCreateTypeSymbol(typeof(bool))); + m.IsGenericMethod.Should().BeFalse(); + m.IsGenericMethodDefinition.Should().BeFalse(); + m.IsPublic.Should().BeTrue(); + m.IsPrivate.Should().BeFalse(); + var p = m.GetParameters(); + p.Length.Should().Be(2); + p[0].Name.Should().Be("objA"); + p[0].ParameterType.Should().Be(c.GetOrCreateTypeSymbol(typeof(object))); + p[1].Name.Should().Be("objB"); + p[1].ParameterType.Should().Be(c.GetOrCreateTypeSymbol(typeof(object))); + } + + [AttributeUsage(AttributeTargets.Class)] + class AttributeWithType : Attribute + { + + public AttributeWithType(Type type) + { + Type = type; + } + + public Type Type { get; } + + } + + [AttributeWithType(typeof(object))] + class ClassWithAttributeWithType + { + + + } [TestMethod] public void CanReadCustomAttributes() { var c = new ReflectionSymbolContext(); - var s = c.GetOrCreateTypeSymbol(typeof(AttributeUsageAttribute)); - var a = s.GetCustomAttributes(); + var s = c.GetOrCreateTypeSymbol(typeof(ClassWithAttributeWithType)); + var a = s.GetCustomAttribute(c.GetOrCreateTypeSymbol(typeof(AttributeWithType))); + var v = a.Value.ConstructorArguments[0].Value; + v.Should().BeOfType(); + } + + [TestMethod] + public void CanResolveAssemblyBuilder() + { + var c = new ReflectionSymbolContext(); + var a = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.RunAndCollect); + var assemblySymbol = c.GetOrCreateAssemblySymbol(a); + assemblySymbol.Should().BeOfType(); + assemblySymbol.Should().BeSameAs(c.GetOrCreateAssemblySymbol(a)); + } + + [TestMethod] + public void CanResolveModuleBuilder() + { + var c = new ReflectionSymbolContext(); + var a = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.RunAndCollect); + var module = a.DefineDynamicModule("Test"); + var moduleSymbol = c.GetOrCreateModuleSymbol(module); + moduleSymbol.Should().BeOfType(); + moduleSymbol.Should().BeSameAs(c.GetOrCreateModuleSymbol(module)); + } + + [TestMethod] + public void CanResolveTypeBuilder() + { + var c = new ReflectionSymbolContext(); + var a = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.RunAndCollect); + var m = a.DefineDynamicModule("DynamicModule"); + + var type1 = m.DefineType("DynamicType1"); + var type1Symbol = c.GetOrCreateTypeSymbol(type1); + type1Symbol.Should().BeOfType(); + type1Symbol.Should().BeSameAs(c.GetOrCreateTypeSymbol(type1)); + } + + [TestMethod] + public void CanResolveMultipleTypeBuilders() + { + var c = new ReflectionSymbolContext(); + var a = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.RunAndCollect); + var m = a.DefineDynamicModule("DynamicModule"); + + var type1 = m.DefineType("DynamicType1"); + var type1Symbol = c.GetOrCreateTypeSymbol(type1); + type1Symbol.Should().BeOfType(); + type1Symbol.Should().BeSameAs(c.GetOrCreateTypeSymbol(type1)); + type1.CreateType(); + + var type2 = m.DefineType("DynamicType2"); + var type2Symbol = c.GetOrCreateTypeSymbol(type2); + type2Symbol.Should().BeOfType(); + type2Symbol.Should().BeSameAs(c.GetOrCreateTypeSymbol(type2)); + } + + [TestMethod] + public void CanResolveMethodBuilder() + { + var c = new ReflectionSymbolContext(); + var a = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.RunAndCollect); + var m = a.DefineDynamicModule("DynamicModule"); + var t = m.DefineType("DynamicType"); + + var method1 = t.DefineMethod("DynamicMethod1", MethodAttributes.Public | MethodAttributes.Static); + var method1Symbol = c.GetOrCreateMethodSymbol(method1); + method1Symbol.Should().BeOfType(); + method1Symbol.Should().BeSameAs(c.GetOrCreateMethodSymbol(method1)); + } + + [TestMethod] + public void CanResolveMultipleMethodBuilders() + { + var c = new ReflectionSymbolContext(); + var a = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.RunAndCollect); + var m = a.DefineDynamicModule("DynamicModule"); + var t = m.DefineType("DynamicType"); + + var method1 = t.DefineMethod("DynamicMethod1", MethodAttributes.Public | MethodAttributes.Static); + var method1Symbol = c.GetOrCreateMethodSymbol(method1); + method1Symbol.Should().BeOfType(); + method1Symbol.Should().BeSameAs(c.GetOrCreateMethodSymbol(method1)); + + var method2 = t.DefineMethod("DynamicMethod2", MethodAttributes.Public | MethodAttributes.Static); + var method2Symbol = c.GetOrCreateMethodSymbol(method2); + method2Symbol.Should().BeOfType(); + method2Symbol.Should().BeSameAs(c.GetOrCreateMethodSymbol(method2)); + } + + [TestMethod] + public void CanResolveFieldBuilder() + { + var c = new ReflectionSymbolContext(); + var a = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.RunAndCollect); + var m = a.DefineDynamicModule("DynamicModule"); + var t = m.DefineType("DynamicType"); + + var field = t.DefineField("dynamicField", typeof(object), FieldAttributes.Public); + var fieldSymbol = c.GetOrCreateFieldSymbol(field); + fieldSymbol.Should().BeOfType(); + fieldSymbol.Should().BeSameAs(c.GetOrCreateFieldSymbol(field)); + } + + [TestMethod] + public void CanResolveMultipleFieldBuilders() + { + var c = new ReflectionSymbolContext(); + var a = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.RunAndCollect); + var m = a.DefineDynamicModule("DynamicModule"); + var t = m.DefineType("DynamicType"); + + var field1 = t.DefineField("dynamicField1", typeof(object), FieldAttributes.Public); + var field1Symbol = c.GetOrCreateFieldSymbol(field1); + field1Symbol.Should().BeOfType(); + field1Symbol.Should().BeSameAs(c.GetOrCreateFieldSymbol(field1)); + + var field2 = t.DefineField("dynamicField2", typeof(object), FieldAttributes.Public); + var field2Symbol = c.GetOrCreateFieldSymbol(field2); + field2Symbol.Should().BeOfType(); + field2Symbol.Should().BeSameAs(c.GetOrCreateFieldSymbol(field2)); + } + + [TestMethod] + public void CanResolvePropertyBuilder() + { + var c = new ReflectionSymbolContext(); + var a = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.RunAndCollect); + var m = a.DefineDynamicModule("DynamicModule"); + var t = m.DefineType("DynamicType"); + + var property = t.DefineProperty("DynamicProperty", PropertyAttributes.None, typeof(object), []); + var propertySymbol = c.GetOrCreatePropertySymbol(property); + propertySymbol.Should().BeOfType(); + propertySymbol.Should().BeSameAs(c.GetOrCreatePropertySymbol(property)); + } + + [TestMethod] + public void CanResolveMultiplePropertyBuilders() + { + var c = new ReflectionSymbolContext(); + var a = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.RunAndCollect); + var m = a.DefineDynamicModule("DynamicModule"); + var t = m.DefineType("DynamicType"); + + var property1 = t.DefineProperty("DynamicProperty1", PropertyAttributes.None, typeof(object), []); + var property1Symbol = c.GetOrCreatePropertySymbol(property1); + property1Symbol.Should().BeOfType(); + property1Symbol.Should().BeSameAs(c.GetOrCreatePropertySymbol(property1)); + + var property2 = t.DefineProperty("DynamicProperty2", PropertyAttributes.None, typeof(object), []); + var property2Symbol = c.GetOrCreatePropertySymbol(property2); + property2Symbol.Should().BeOfType(); + property2Symbol.Should().BeSameAs(c.GetOrCreatePropertySymbol(property2)); + } + + [TestMethod] + public void CanResolveEventBuilder() + { + var c = new ReflectionSymbolContext(); + var a = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.RunAndCollect); + var m = a.DefineDynamicModule("DynamicModule"); + var t = m.DefineType("DynamicType"); + + var event1 = t.DefineEvent("DynamicEvent", EventAttributes.None, typeof(EventHandler)); + var event1Symbol = c.GetOrCreateEventSymbol(event1); + event1Symbol.Should().BeOfType(); + event1Symbol.Should().BeSameAs(c.GetOrCreateEventSymbol(event1)); + } + + [TestMethod] + public void CanResolveMultipleEventBuilders() + { + var c = new ReflectionSymbolContext(); + var a = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.RunAndCollect); + var m = a.DefineDynamicModule("DynamicModule"); + var t = m.DefineType("DynamicType"); + + var event1 = t.DefineEvent("DynamicEvent", EventAttributes.None, typeof(EventHandler)); + var event1Symbol = c.GetOrCreateEventSymbol(event1); + event1Symbol.Should().BeOfType(); + event1Symbol.Should().BeSameAs(c.GetOrCreateEventSymbol(event1)); + + var event2 = t.DefineEvent("DynamicEvent", EventAttributes.None, typeof(EventHandler)); + var event2Symbol = c.GetOrCreateEventSymbol(event2); + event2Symbol.Should().BeOfType(); + event2Symbol.Should().BeSameAs(c.GetOrCreateEventSymbol(event2)); + } + + [TestMethod] + public void CanCreateAndResolveDynamicMethodOnModule() + { + var c = new ReflectionSymbolContext(); + + var method1 = new DynamicMethod("DynamicMethod1", null, null, typeof(ReflectionSymbolTests).Module); + var method1Symbol = c.GetOrCreateMethodSymbol(method1); + method1Symbol.Should().BeOfType(); + method1Symbol.Should().BeSameAs(c.GetOrCreateMethodSymbol(method1)); + } + + [TestMethod] + public void CanCreateAndResolveMultipleDynamicMethodsOnModule() + { + var c = new ReflectionSymbolContext(); + + var method1 = new DynamicMethod("DynamicMethod1", null, null, typeof(ReflectionSymbolTests).Module); + var method1Symbol = c.GetOrCreateMethodSymbol(method1); + method1Symbol.Should().BeOfType(); + method1Symbol.Should().BeSameAs(c.GetOrCreateMethodSymbol(method1)); + + var method2 = new DynamicMethod("DynamicMethod2", null, null, typeof(ReflectionSymbolTests).Module); + var method2Symbol = c.GetOrCreateMethodSymbol(method2); + method2Symbol.Should().BeOfType(); + method2Symbol.Should().BeSameAs(c.GetOrCreateMethodSymbol(method2)); + } + + [TestMethod] + public void CanCreateAndResolveDynamicMethodOnType() + { + var c = new ReflectionSymbolContext(); + + var method1 = new DynamicMethod("DynamicMethod", null, null, typeof(ReflectionSymbolTests)); + var method1Symbol = c.GetOrCreateMethodSymbol(method1); + method1Symbol.Should().BeOfType(); + method1Symbol.Should().BeSameAs(c.GetOrCreateMethodSymbol(method1)); + } + + [TestMethod] + public void CanCreateAndResolveMultipleDynamicMethodsOnType() + { + var c = new ReflectionSymbolContext(); + + var method1 = new DynamicMethod("DynamicMethod1", null, null, typeof(ReflectionSymbolTests)); + var method1Symbol = c.GetOrCreateMethodSymbol(method1); + method1Symbol.Should().BeOfType(); + method1Symbol.Should().BeSameAs(c.GetOrCreateMethodSymbol(method1)); + + var method2 = new DynamicMethod("DynamicMethod2", null, null, typeof(ReflectionSymbolTests)); + var method2Symbol = c.GetOrCreateMethodSymbol(method2); + method2Symbol.Should().BeOfType(); + method2Symbol.Should().BeSameAs(c.GetOrCreateMethodSymbol(method2)); } } diff --git a/src/IKVM.CoreLib/Collections/IndexRangeDictionary.cs b/src/IKVM.CoreLib/Collections/IndexRangeDictionary.cs new file mode 100644 index 000000000..deae4e8ae --- /dev/null +++ b/src/IKVM.CoreLib/Collections/IndexRangeDictionary.cs @@ -0,0 +1,140 @@ +using System; +using System.Diagnostics; + +namespace IKVM.CoreLib.Collections +{ + + /// + /// Represents a dictionary that can store int keys mapped to values, where the underlying storage is an array that + /// holds the minimum number of items for the minimum and maximum key values. + /// + struct IndexRangeDictionary + { + + int _initialCapacity; + int _maxCapacity; + int _minKey; + T?[]? _items; + + /// + /// Initializes a new instance. + /// + public IndexRangeDictionary() : this(initialCapacity: 4, maxCapacity: int.MaxValue) + { + + } + + /// + /// Initializes a new instance. + /// + public IndexRangeDictionary(int initialCapacity = 4, int maxCapacity = int.MaxValue) + { + if (initialCapacity < 0) + throw new ArgumentOutOfRangeException(nameof(initialCapacity)); + if (maxCapacity < 0) + throw new ArgumentOutOfRangeException(nameof(maxCapacity)); + + _initialCapacity = initialCapacity; + _maxCapacity = maxCapacity; + } + + /// + /// Gets the capacity of the dictionary. + /// + public readonly int Capacity => _items?.Length ?? 0; + + /// + /// Gets or sets the item with the specified key, optionally growing the list to accomidate. + /// + /// + /// + public T? this[int key] + { + readonly get => Get(key); + set => Set(key, value); + } + + /// + /// Ensures the list is sized such that it can hold the specified key. + /// + /// + /// + public void EnsureCapacity(int key) + { + // initial state, first item, hold only that + if (_items == null) + { + _minKey = key; + _items = new T[_initialCapacity]; + } + + // key is less than minKey, grow and shift by difference + if (key < _minKey) + { + // increase length until we encompass key + var len = _items.Length; + while (key - _minKey + len - _items.Length < 0) + len *= 2; + + if (len > _maxCapacity || len < 0) + throw new InvalidOperationException(); + + var end = _items.Length - 1; + Array.Resize(ref _items, len); + for (int i = end; i >= 0; i--) + _items[i + _minKey - key] = _items[i]; + Array.Clear(_items, 0, end); + + _minKey = key; + } + + // desired position if after the end of the array, we need to grow, but no copies needed + if (key - _minKey >= _items.Length) + { + // increase length until we encompass key + var len = _items.Length; + while (key - _minKey >= len) + len *= 2; + + if (len > _maxCapacity || len < 0) + throw new InvalidOperationException(); + + Array.Resize(ref _items, len); + } + + Debug.Assert(key - _minKey >= 0); + Debug.Assert(key - _minKey < _items.Length); + } + + /// + /// Adds a new item to the list. + /// + /// + readonly T? Get(int key) + { + var pos = key - _minKey; + if (_items == null || pos < 0 || pos >= _items.Length) + return default; + else + return _items[pos]; + } + + /// + /// Adds a new item to the list. + /// + /// + /// + void Set(int key, T? value) + { + EnsureCapacity(key); + if (_items == null) + throw new InvalidOperationException(); + + Debug.Assert(key - _minKey >= 0); + Debug.Assert(key - _minKey < _items.Length); + _items[key - _minKey] = value; + } + + } + +} diff --git a/src/IKVM.CoreLib/IKVM.CoreLib.csproj b/src/IKVM.CoreLib/IKVM.CoreLib.csproj index cede1bd12..5e31c90e3 100644 --- a/src/IKVM.CoreLib/IKVM.CoreLib.csproj +++ b/src/IKVM.CoreLib/IKVM.CoreLib.csproj @@ -25,6 +25,7 @@ + diff --git a/src/IKVM.CoreLib/Symbols/CustomAttribute.cs b/src/IKVM.CoreLib/Symbols/CustomAttribute.cs new file mode 100644 index 000000000..7b1af0a9d --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/CustomAttribute.cs @@ -0,0 +1,13 @@ +using System.Collections.Immutable; + +namespace IKVM.CoreLib.Symbols +{ + + readonly record struct CustomAttribute( + ITypeSymbol AttributeType, + IConstructorSymbol Constructor, + ImmutableArray ConstructorArguments, + ImmutableArray NamedArguments); + + +} diff --git a/src/IKVM.CoreLib/Symbols/CustomAttributeSymbolNamedArgument.cs b/src/IKVM.CoreLib/Symbols/CustomAttributeNamedArgument.cs similarity index 50% rename from src/IKVM.CoreLib/Symbols/CustomAttributeSymbolNamedArgument.cs rename to src/IKVM.CoreLib/Symbols/CustomAttributeNamedArgument.cs index c01598e24..9ba5842e8 100644 --- a/src/IKVM.CoreLib/Symbols/CustomAttributeSymbolNamedArgument.cs +++ b/src/IKVM.CoreLib/Symbols/CustomAttributeNamedArgument.cs @@ -1,10 +1,10 @@ namespace IKVM.CoreLib.Symbols { - readonly record struct CustomAttributeSymbolNamedArgument( + readonly record struct CustomAttributeNamedArgument( bool IsField, IMemberSymbol MemberInfo, string MemberName, - CustomAttributeSymbolTypedArgument TypedValue); + CustomAttributeTypedArgument TypedValue); } diff --git a/src/IKVM.CoreLib/Symbols/CustomAttributeSymbol.cs b/src/IKVM.CoreLib/Symbols/CustomAttributeSymbol.cs deleted file mode 100644 index dbdab0f3c..000000000 --- a/src/IKVM.CoreLib/Symbols/CustomAttributeSymbol.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.Collections.Immutable; - -namespace IKVM.CoreLib.Symbols -{ - - readonly record struct CustomAttributeSymbol( - ITypeSymbol AttributeType, - IConstructorSymbol Constructor, - ImmutableArray ConstructorArguments, - ImmutableArray NamedArguments); - -} diff --git a/src/IKVM.CoreLib/Symbols/CustomAttributeSymbolTypedArgument.cs b/src/IKVM.CoreLib/Symbols/CustomAttributeTypedArgument.cs similarity index 60% rename from src/IKVM.CoreLib/Symbols/CustomAttributeSymbolTypedArgument.cs rename to src/IKVM.CoreLib/Symbols/CustomAttributeTypedArgument.cs index 0f56df5a3..d19aebfdd 100644 --- a/src/IKVM.CoreLib/Symbols/CustomAttributeSymbolTypedArgument.cs +++ b/src/IKVM.CoreLib/Symbols/CustomAttributeTypedArgument.cs @@ -1,7 +1,7 @@ namespace IKVM.CoreLib.Symbols { - readonly record struct CustomAttributeSymbolTypedArgument( + readonly record struct CustomAttributeTypedArgument( ITypeSymbol ArgumentType, object? Value); diff --git a/src/IKVM.CoreLib/Symbols/Emit/IAssemblySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IAssemblySymbolBuilder.cs new file mode 100644 index 000000000..c89940b3a --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Emit/IAssemblySymbolBuilder.cs @@ -0,0 +1,29 @@ +namespace IKVM.CoreLib.Symbols.Emit +{ + + interface IAssemblySymbolBuilder : ISymbolBuilder + { + + /// + /// Defines a named module in this assembly. + /// + /// + /// + IModuleSymbolBuilder DefineModule(string name); + + /// + /// Set a custom attribute using a custom attribute builder. + /// + /// + void SetCustomAttribute(ICustomAttributeBuilder customBuilder); + + /// + /// Sets a custom attribute using a specified custom attribute blob. + /// + /// + /// + void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute); + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Emit/IConstructorSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IConstructorSymbolBuilder.cs new file mode 100644 index 000000000..72d628579 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Emit/IConstructorSymbolBuilder.cs @@ -0,0 +1,50 @@ +namespace IKVM.CoreLib.Symbols.Emit +{ + + interface IConstructorSymbolBuilder : ISymbolBuilder + { + + /// + /// Sets the method implementation flags for this constructor. + /// + /// + void SetImplementationFlags(System.Reflection.MethodImplAttributes attributes); + + /// + /// Defines a parameter of this constructor. + /// + /// + /// + /// + /// + IParameterSymbolBuilder DefineParameter(int iSequence, System.Reflection.ParameterAttributes attributes, string? strParamName); + + /// + /// Gets an ILGenerator object, with the specified MSIL stream size, that can be used to build a method body for this constructor. + /// + /// + /// + System.Reflection.Emit.ILGenerator GetILGenerator(int streamSize); + + /// + /// Gets an ILGenerator for this constructor. + /// + /// + System.Reflection.Emit.ILGenerator GetILGenerator(); + + /// + /// Set a custom attribute using a custom attribute builder. + /// + /// + void SetCustomAttribute(ICustomAttributeBuilder customBuilder); + + /// + /// Sets a custom attribute using a specified custom attribute blob. + /// + /// + /// + void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute); + + } + +} \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/Emit/ICustomAttributeBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/ICustomAttributeBuilder.cs new file mode 100644 index 000000000..e30a02e21 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Emit/ICustomAttributeBuilder.cs @@ -0,0 +1,11 @@ +namespace IKVM.CoreLib.Symbols.Emit +{ + + interface ICustomAttributeBuilder + { + + + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Emit/IEventSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IEventSymbolBuilder.cs new file mode 100644 index 000000000..b5378a41d --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Emit/IEventSymbolBuilder.cs @@ -0,0 +1,46 @@ +namespace IKVM.CoreLib.Symbols.Emit +{ + + interface IEventSymbolBuilder : ISymbolBuilder + { + + /// + /// Sets the method used to subscribe to this event. + /// + /// + void SetAddOnMethod(IMethodSymbolBuilder mdBuilder); + + /// + /// Sets the method used to unsubscribe to this event. + /// + /// + void SetRemoveOnMethod(IMethodSymbolBuilder mdBuilder); + + /// + /// Sets the method used to raise this event. + /// + /// + void SetRaiseMethod(IMethodSymbolBuilder mdBuilder); + + /// + /// Adds one of the "other" methods associated with this event. "Other" methods are methods other than the "on" and "raise" methods associated with an event. This function can be called many times to add as many "other" methods. + /// + /// + void AddOtherMethod(IMethodSymbolBuilder mdBuilder); + + /// + /// Set a custom attribute using a custom attribute builder. + /// + /// + void SetCustomAttribute(ICustomAttributeBuilder customBuilder); + + /// + /// Sets a custom attribute using a specified custom attribute blob. + /// + /// + /// + void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute); + + } + +} \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/Emit/IFieldSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IFieldSymbolBuilder.cs new file mode 100644 index 000000000..5b6706e3f --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Emit/IFieldSymbolBuilder.cs @@ -0,0 +1,34 @@ +namespace IKVM.CoreLib.Symbols.Emit +{ + + interface IFieldSymbolBuilder : ISymbolBuilder + { + + /// + /// Sets the default value of this field. + /// + /// + void SetConstant(object? defaultValue); + + /// + /// Specifies the field layout. + /// + /// + void SetOffset(int iOffset); + + /// + /// Set a custom attribute using a custom attribute builder. + /// + /// + void SetCustomAttribute(ICustomAttributeBuilder customBuilder); + + /// + /// Sets a custom attribute using a specified custom attribute blob. + /// + /// + /// + void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute); + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Emit/IGenericTypeParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IGenericTypeParameterSymbolBuilder.cs new file mode 100644 index 000000000..38bcde837 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Emit/IGenericTypeParameterSymbolBuilder.cs @@ -0,0 +1,11 @@ +namespace IKVM.CoreLib.Symbols.Emit +{ + + interface IGenericTypeParameterSymbolBuilder : ISymbolBuilder + { + + + + } + +} \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/Emit/IILGenerator.cs b/src/IKVM.CoreLib/Symbols/Emit/IILGenerator.cs new file mode 100644 index 000000000..69f29dfa3 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Emit/IILGenerator.cs @@ -0,0 +1,11 @@ +namespace IKVM.CoreLib.Symbols.Emit +{ + + interface IILGenerator + { + + + + } + +} \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/Emit/IMethodSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IMethodSymbolBuilder.cs new file mode 100644 index 000000000..9e251bed2 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Emit/IMethodSymbolBuilder.cs @@ -0,0 +1,80 @@ +namespace IKVM.CoreLib.Symbols.Emit +{ + + interface IMethodSymbolBuilder : ISymbolBuilder + { + + /// + /// Sets the implementation flags for this method. + /// + /// + void SetImplementationFlags(System.Reflection.MethodImplAttributes attributes); + + /// + /// Sets the number and types of parameters for a method. + /// + /// + void SetParameters(params ITypeSymbol[] parameterTypes); + + /// + /// Sets the return type of the method. + /// + /// + void SetReturnType(ITypeSymbol? returnType); + + /// + /// Sets the method signature, including the return type, the parameter types, and the required and optional custom modifiers of the return type and parameter types. + /// + /// + /// + /// + /// + /// + /// + void SetSignature(ITypeSymbol? returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers); + + /// + /// Sets the number of generic type parameters for the current method, specifies their names, and returns an array of GenericTypeParameterBuilder objects that can be used to define their constraints. + /// + /// + /// + IGenericTypeParameterSymbolBuilder[] DefineGenericParameters(params string[] names); + + /// + /// Sets the parameter attributes and the name of a parameter of this method, or of the return value of this method. Returns a ParameterBuilder that can be used to apply custom attributes. + /// + /// + /// + /// + /// + IParameterSymbolBuilder DefineParameter(int position, System.Reflection.ParameterAttributes attributes, string? strParamName); + + /// + /// Returns an ILGenerator for this method with a default Microsoft intermediate language (MSIL) stream size of 64 bytes. + /// + /// + IILGenerator GetILGenerator(); + + /// + /// Returns an ILGenerator for this method with the specified Microsoft intermediate language (MSIL) stream size. + /// + /// + /// + IILGenerator GetILGenerator(int size); + + /// + /// Set a custom attribute using a custom attribute builder. + /// + /// + void SetCustomAttribute(ICustomAttributeBuilder customBuilder); + + /// + /// Sets a custom attribute using a specified custom attribute blob. + /// + /// + /// + void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute); + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Emit/IModuleSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IModuleSymbolBuilder.cs new file mode 100644 index 000000000..5d059cc09 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Emit/IModuleSymbolBuilder.cs @@ -0,0 +1,90 @@ +using System.Reflection; +using System.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.Emit +{ + + interface IModuleSymbolBuilder : ISymbolBuilder + { + + /// + /// Constructs a TypeBuilder for a private type with the specified name in this module. + /// + /// + /// + ITypeSymbolBuilder DefineType(string name); + + /// + /// Constructs a TypeBuilder given the type name, the attributes, the type that the defined type extends, and the total size of the type. + /// + /// + /// + /// + /// + /// + ITypeSymbolBuilder DefineType(string name, TypeAttributes attr, ITypeSymbol? parent, int typesize); + + /// + /// Constructs a TypeBuilder given type name, its attributes, and the type that the defined type extends. + /// + /// + /// + /// + /// + ITypeSymbolBuilder DefineType(string name, TypeAttributes attr, ITypeSymbol? parent); + + /// + /// Constructs a TypeBuilder given the type name and the type attributes. + /// + /// + /// + /// + ITypeSymbolBuilder DefineType(string name, TypeAttributes attr); + + /// + /// Constructs a TypeBuilder given the type name, the attributes, the type that the defined type extends, and the packing size of the type. + /// + /// + /// + /// + /// + /// + ITypeSymbolBuilder DefineType(string name, TypeAttributes attr, ITypeSymbol? parent, PackingSize packsize); + + /// + /// Constructs a TypeBuilder given the type name, attributes, the type that the defined type extends, the packing size of the defined type, and the total size of the defined type. + /// + /// + /// + /// + /// + /// + /// + ITypeSymbolBuilder DefineType(string name, TypeAttributes attr, ITypeSymbol? parent, PackingSize packingSize, int typesize); + + /// + /// Constructs a TypeBuilder given the type name, attributes, the type that the defined type extends, and the interfaces that the defined type implements. + /// + /// + /// + /// + /// + /// + ITypeSymbolBuilder DefineType(string name, TypeAttributes attr, ITypeSymbol? parent, ITypeSymbol[]? interfaces); + + /// + /// Set a custom attribute using a custom attribute builder. + /// + /// + void SetCustomAttribute(ICustomAttributeBuilder customBuilder); + + /// + /// Sets a custom attribute using a specified custom attribute blob. + /// + /// + /// + void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute); + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Emit/IParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IParameterSymbolBuilder.cs new file mode 100644 index 000000000..9ac13b384 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Emit/IParameterSymbolBuilder.cs @@ -0,0 +1,27 @@ +namespace IKVM.CoreLib.Symbols.Emit +{ + + interface IParameterSymbolBuilder : ISymbolBuilder + { + /// + /// Sets the default value of the parameter. + /// + /// + void SetConstant(object? defaultValue); + + /// + /// Set a custom attribute using a custom attribute builder. + /// + /// + void SetCustomAttribute(ICustomAttributeBuilder customBuilder); + + /// + /// Sets a custom attribute using a specified custom attribute blob. + /// + /// + /// + void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute); + + } + +} \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/Emit/IPropertySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IPropertySymbolBuilder.cs new file mode 100644 index 000000000..6c2d9ade9 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Emit/IPropertySymbolBuilder.cs @@ -0,0 +1,22 @@ +namespace IKVM.CoreLib.Symbols.Emit +{ + + interface IPropertySymbolBuilder : ISymbolBuilder + { + + /// + /// Set a custom attribute using a custom attribute builder. + /// + /// + void SetCustomAttribute(ICustomAttributeBuilder customBuilder); + + /// + /// Sets a custom attribute using a specified custom attribute blob. + /// + /// + /// + void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute); + + } + +} \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/Emit/ISymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/ISymbolBuilder.cs new file mode 100644 index 000000000..8b7b295fe --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Emit/ISymbolBuilder.cs @@ -0,0 +1,32 @@ +namespace IKVM.CoreLib.Symbols.Emit +{ + + /// + /// Base interface for a builder of symbols. + /// + interface ISymbolBuilder + { + + /// + /// Gets the that is currently being built. Portions of this interface will be non-functional until the build is completed. + /// + ISymbol Symbol { get; } + + } + + /// + /// Base interface for a builder of symbols. + /// + /// + interface ISymbolBuilder : ISymbolBuilder + where TSymbol : ISymbol + { + + /// + /// Gets the that is currently being built. Portions of this interface will be non-functional until the build is completed. + /// + new TSymbol Symbol { get; } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Emit/ITypeSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/ITypeSymbolBuilder.cs new file mode 100644 index 000000000..ebe0c5915 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Emit/ITypeSymbolBuilder.cs @@ -0,0 +1,326 @@ +using System.Reflection; + +namespace IKVM.CoreLib.Symbols.Emit +{ + + interface ITypeSymbolBuilder : ISymbolBuilder + { + + /// + /// Sets the base type of the type currently under construction. + /// + /// + void SetParent(ITypeSymbol? parent); + + /// + /// Defines the generic type parameters for the current type, specifying their number and their names, and returns an array of GenericTypeParameterBuilder objects that can be used to set their constraints. + /// + /// + /// + IGenericTypeParameterSymbolBuilder[] DefineGenericParameters(params string[] names); + + /// + /// Defines the initializer for this type. + /// + /// + IConstructorSymbolBuilder DefineTypeInitializer(); + + /// + /// Adds an interface that this type implements. + /// + /// + void AddInterfaceImplementation(ITypeSymbol interfaceType); + + /// + /// Adds a new constructor to the type, with the given attributes and signature. + /// + /// + /// + /// + /// + IConstructorSymbolBuilder DefineConstructor(System.Reflection.MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol[]? parameterTypes); + + /// + /// Adds a new constructor to the type, with the given attributes, signature, and custom modifiers. + /// + /// + /// + /// + /// + /// + /// + IConstructorSymbolBuilder DefineConstructor(MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? requiredCustomModifiers, ITypeSymbol[][]? optionalCustomModifiers); + + /// + /// Defines the parameterless constructor. The constructor defined here will simply call the parameterless constructor of the parent. + /// + /// + /// + IConstructorSymbolBuilder DefineDefaultConstructor(MethodAttributes attributes); + + /// + /// Adds a new event to the type, with the given name, attributes and event type. + /// + /// + /// + /// + /// + IEventSymbolBuilder DefineEvent(string name, EventAttributes attributes, ITypeSymbol eventtype); + + /// + /// Adds a new field to the type, with the given name, attributes, and field type. + /// + /// + /// + /// + /// + IFieldSymbolBuilder DefineField(string fieldName, ITypeSymbol type, FieldAttributes attributes); + + /// + /// Adds a new field to the type, with the given name, attributes, field type, and custom modifiers. + /// + /// + /// + /// + /// + /// + /// + IFieldSymbolBuilder DefineField(string fieldName, ITypeSymbol type, ITypeSymbol[]? requiredCustomModifiers, ITypeSymbol[]? optionalCustomModifiers, FieldAttributes attributes); + + /// + /// Adds a new method to the type, with the specified name, method attributes, calling convention, method signature, and custom modifiers. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + IMethodSymbolBuilder DefineMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers); + + /// + /// Adds a new method to the type, with the specified name, method attributes, calling convention, and method signature. + /// + /// + /// + /// + /// + /// + /// + IMethodSymbolBuilder DefineMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes); + + /// + /// Adds a new method to the type, with the specified name, method attributes, and calling convention. + /// + /// + /// + /// + /// + IMethodSymbolBuilder DefineMethod(string name, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention); + + /// + /// Adds a new method to the type, with the specified name and method attributes. + /// + /// + /// + /// + IMethodSymbolBuilder DefineMethod(string name, System.Reflection.MethodAttributes attributes); + + /// + /// Adds a new method to the type, with the specified name, method attributes, and method signature. + /// + /// + /// + /// + /// + /// + IMethodSymbolBuilder DefineMethod(string name, System.Reflection.MethodAttributes attributes, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes); + + /// + /// Defines a nested type, given its name, attributes, the type that it extends, and the interfaces that it implements. + /// + /// + /// + /// + /// + /// + ITypeSymbolBuilder DefineNestedType(string name, System.Reflection.TypeAttributes attr, ITypeSymbol? parent, ITypeSymbol[]? interfaces); + + /// + /// Defines a nested type, given its name, attributes, size, and the type that it extends. + /// + /// + /// + /// + /// + /// + /// + ITypeSymbolBuilder DefineNestedType(string name, System.Reflection.TypeAttributes attr, ITypeSymbol? parent, System.Reflection.Emit.PackingSize packSize, int typeSize); + + /// + /// Defines a nested type, given its name, attributes, the type that it extends, and the packing size. + /// + /// + /// + /// + /// + /// + ITypeSymbolBuilder DefineNestedType(string name, System.Reflection.TypeAttributes attr, ITypeSymbol? parent, System.Reflection.Emit.PackingSize packSize); + + /// + /// Defines a nested type, given its name. + /// + /// + /// + ITypeSymbolBuilder DefineNestedType(string name); + + /// + /// Defines a nested type, given its name, attributes, and the type that it extends. + /// + /// + /// + /// + /// + ITypeSymbolBuilder DefineNestedType(string name, System.Reflection.TypeAttributes attr, ITypeSymbol? parent); + + /// + /// Defines a nested type, given its name and attributes. + /// + /// + /// + /// + ITypeSymbolBuilder DefineNestedType(string name, System.Reflection.TypeAttributes attr); + + /// + /// Defines a nested type, given its name, attributes, the total size of the type, and the type that it extends. + /// + /// + /// + /// + /// + /// + ITypeSymbolBuilder DefineNestedType(string name, System.Reflection.TypeAttributes attr, ITypeSymbol? parent, int typeSize); + + /// + /// Defines a PInvoke method given its name, the name of the DLL in which the method is defined, the attributes of the method, the calling convention of the method, the return type of the method, the types of the parameters of the method, and the PInvoke flags. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + IMethodSymbolBuilder DefinePInvokeMethod(string name, string dllName, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes, System.Runtime.InteropServices.CallingConvention nativeCallConv, System.Runtime.InteropServices.CharSet nativeCharSet); + + /// + /// Defines a PInvoke method given its name, the name of the DLL in which the method is defined, the name of the entry point, the attributes of the method, the calling convention of the method, the return type of the method, the types of the parameters of the method, and the PInvoke flags. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + IMethodSymbolBuilder DefinePInvokeMethod(string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes, System.Runtime.InteropServices.CallingConvention nativeCallConv, System.Runtime.InteropServices.CharSet nativeCharSet); + + /// + /// Defines a PInvoke method given its name, the name of the DLL in which the method is defined, the name of the entry point, the attributes of the method, the calling convention of the method, the return type of the method, the types of the parameters of the method, the PInvoke flags, and custom modifiers for the parameters and return type. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + IMethodSymbolBuilder DefinePInvokeMethod(string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers, System.Runtime.InteropServices.CallingConvention nativeCallConv, System.Runtime.InteropServices.CharSet nativeCharSet); + + /// + /// Adds a new property to the type, with the given name and property signature. + /// + /// + /// + /// + /// + /// + IPropertySymbolBuilder DefineProperty(string name, PropertyAttributes attributes, ITypeSymbol returnType, ITypeSymbol[]? parameterTypes); + + /// + /// Adds a new property to the type, with the given name, attributes, calling convention, and property signature. + /// + /// + /// + /// + /// + /// + /// + IPropertySymbolBuilder DefineProperty(string name, PropertyAttributes attributes, CallingConventions callingConvention, ITypeSymbol returnType, ITypeSymbol[]? parameterTypes); + + /// + /// Adds a new property to the type, with the given name, property signature, and custom modifiers. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + IPropertySymbolBuilder DefineProperty(string name, PropertyAttributes attributes, ITypeSymbol returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers); + + /// + /// Adds a new property to the type, with the given name, calling convention, property signature, and custom modifiers. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + IPropertySymbolBuilder DefineProperty(string name, PropertyAttributes attributes, CallingConventions callingConvention, ITypeSymbol returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers); + + /// + /// Set a custom attribute using a custom attribute builder. + /// + /// + void SetCustomAttribute(ICustomAttributeBuilder customBuilder); + + /// + /// Sets a custom attribute using a specified custom attribute blob. + /// + /// + /// + void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute); + + /// + /// Finishes the type, updating the associated symbol. + /// + void Finish(); + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IAssemblySymbol.cs b/src/IKVM.CoreLib/Symbols/IAssemblySymbol.cs index 1b0817f28..a87909ae3 100644 --- a/src/IKVM.CoreLib/Symbols/IAssemblySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IAssemblySymbol.cs @@ -4,7 +4,7 @@ namespace IKVM.CoreLib.Symbols { - interface IAssemblySymbol : ISymbol, ICustomAttributeSymbolProvider + interface IAssemblySymbol : ISymbol, ICustomAttributeProvider { IEnumerable DefinedTypes { get; } diff --git a/src/IKVM.CoreLib/Symbols/ICustomAttributeSymbolProvider.cs b/src/IKVM.CoreLib/Symbols/ICustomAttributeProvider.cs similarity index 81% rename from src/IKVM.CoreLib/Symbols/ICustomAttributeSymbolProvider.cs rename to src/IKVM.CoreLib/Symbols/ICustomAttributeProvider.cs index 7659f048f..447839f6a 100644 --- a/src/IKVM.CoreLib/Symbols/ICustomAttributeSymbolProvider.cs +++ b/src/IKVM.CoreLib/Symbols/ICustomAttributeProvider.cs @@ -4,7 +4,7 @@ /// /// Provides custom attributes for reflection objects that support them. /// - interface ICustomAttributeSymbolProvider + interface ICustomAttributeProvider { /// @@ -12,7 +12,7 @@ interface ICustomAttributeSymbolProvider /// /// /// - CustomAttributeSymbol[] GetCustomAttributes(bool inherit = false); + CustomAttribute[] GetCustomAttributes(bool inherit = false); /// /// Returns an array of custom attributes defined on this member, identified by type, or an empty array if there are no custom attributes of that type. @@ -20,7 +20,7 @@ interface ICustomAttributeSymbolProvider /// /// /// - CustomAttributeSymbol[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false); + CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false); /// /// Retrieves a custom attribute of a specified type that is applied to a specified member. @@ -28,7 +28,7 @@ interface ICustomAttributeSymbolProvider /// /// /// - CustomAttributeSymbol? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false); + CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false); /// /// Indicates whether one or more instance of is defined on this member. diff --git a/src/IKVM.CoreLib/Symbols/IMemberSymbol.cs b/src/IKVM.CoreLib/Symbols/IMemberSymbol.cs index 0613ff100..f54d6c3ff 100644 --- a/src/IKVM.CoreLib/Symbols/IMemberSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IMemberSymbol.cs @@ -6,7 +6,7 @@ namespace IKVM.CoreLib.Symbols /// /// Obtains information about the attributes of a member and provides access to member metadata. /// - interface IMemberSymbol : ISymbol, ICustomAttributeSymbolProvider + interface IMemberSymbol : ISymbol, ICustomAttributeProvider { /// diff --git a/src/IKVM.CoreLib/Symbols/IMethodSymbol.cs b/src/IKVM.CoreLib/Symbols/IMethodSymbol.cs index 08d2f8dcb..c3c8d5c9e 100644 --- a/src/IKVM.CoreLib/Symbols/IMethodSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IMethodSymbol.cs @@ -20,7 +20,7 @@ interface IMethodSymbol : IMethodBaseSymbol /// /// Gets the custom attributes for the return type. /// - ICustomAttributeSymbolProvider ReturnTypeCustomAttributes { get; } + ICustomAttributeProvider ReturnTypeCustomAttributes { get; } /// /// When overridden in a derived class, returns the object for the method on the direct or indirect base class in which the method represented by this instance was first declared. diff --git a/src/IKVM.CoreLib/Symbols/IModuleSymbol.cs b/src/IKVM.CoreLib/Symbols/IModuleSymbol.cs index 771d4263c..bcd76ad22 100644 --- a/src/IKVM.CoreLib/Symbols/IModuleSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IModuleSymbol.cs @@ -7,7 +7,7 @@ namespace IKVM.CoreLib.Symbols /// /// Performs reflection on a module. /// - interface IModuleSymbol : ISymbol, ICustomAttributeSymbolProvider + interface IModuleSymbol : ISymbol, ICustomAttributeProvider { /// diff --git a/src/IKVM.CoreLib/Symbols/IParameterSymbol.cs b/src/IKVM.CoreLib/Symbols/IParameterSymbol.cs index 033015ae7..18e855157 100644 --- a/src/IKVM.CoreLib/Symbols/IParameterSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IParameterSymbol.cs @@ -6,7 +6,7 @@ namespace IKVM.CoreLib.Symbols /// /// Discovers the attributes of a parameter and provides access to parameter metadata. /// - interface IParameterSymbol : ISymbol, ICustomAttributeSymbolProvider + interface IParameterSymbol : ISymbol, ICustomAttributeProvider { /// @@ -74,6 +74,18 @@ interface IParameterSymbol : ISymbol, ICustomAttributeSymbolProvider /// int MetadataToken { get; } + /// + /// Returns an array of types representing the optional custom modifiers of the parameter. + /// + /// + ITypeSymbol[] GetOptionalCustomModifiers(); + + /// + /// Returns an array of types representing the required custom modifiers of the parameter. + /// + /// + ITypeSymbol[] GetRequiredCustomModifiers(); + } } diff --git a/src/IKVM.CoreLib/Symbols/ISymbol.cs b/src/IKVM.CoreLib/Symbols/ISymbol.cs index 91abe1639..7fae6f73e 100644 --- a/src/IKVM.CoreLib/Symbols/ISymbol.cs +++ b/src/IKVM.CoreLib/Symbols/ISymbol.cs @@ -12,6 +12,11 @@ interface ISymbol /// bool IsMissing { get; } + /// + /// Returns true if the symbol contains a missing symbol. + /// + bool ContainsMissing { get; } + } } diff --git a/src/IKVM.CoreLib/Symbols/ISymbolResolver.cs b/src/IKVM.CoreLib/Symbols/ISymbolResolver.cs index 5a4815f8d..2976d5bbb 100644 --- a/src/IKVM.CoreLib/Symbols/ISymbolResolver.cs +++ b/src/IKVM.CoreLib/Symbols/ISymbolResolver.cs @@ -2,7 +2,7 @@ { /// - /// Provides an interface to resolve a maaged type symbols. + /// Provides an interface to resolve a managed type symbols. /// interface ISymbolResolver { diff --git a/src/IKVM.CoreLib/Symbols/ITypeSymbol.cs b/src/IKVM.CoreLib/Symbols/ITypeSymbol.cs index 377a82aa6..0df2185f3 100644 --- a/src/IKVM.CoreLib/Symbols/ITypeSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/ITypeSymbol.cs @@ -1,4 +1,5 @@ -using System.Reflection; +using System; +using System.Reflection; namespace IKVM.CoreLib.Symbols { @@ -39,6 +40,11 @@ interface ITypeSymbol : IMemberSymbol /// string? Namespace { get; } + /// + /// Gets the underlying type code of the specified Type. + /// + TypeCode TypeCode { get; } + /// /// Gets the type from which the current directly inherits. /// @@ -70,14 +76,19 @@ interface ITypeSymbol : IMemberSymbol bool IsConstructedGenericType { get; } /// - /// Gets a value indicating whether the current represents a type parameter in the definition of a generic type or method. + /// Gets a value indicating whether the current type is a generic type. /// - bool IsGenericParameter { get; } + bool IsGenericType { get; } /// - /// Gets a value indicating whether the current type is a generic type. + /// Gets a value indicating whether the current Type represents a generic type definition, from which other generic types can be constructed. /// - bool IsGenericType { get; } + bool IsGenericTypeDefinition { get; } + + /// + /// Gets a value indicating whether the current represents a type parameter in the definition of a generic type or method. + /// + bool IsGenericParameter { get; } /// /// Gets a value indicating whether the fields of the current type are laid out automatically by the common language runtime. @@ -119,6 +130,11 @@ interface ITypeSymbol : IMemberSymbol /// bool IsPrimitive { get; } + /// + /// Gets a value that indicates whether the type is an array type that can represent only a single-dimensional array with a zero lower bound. + /// + bool IsSZArray { get; } + /// /// Gets a value that indicates whether the type is an array. /// @@ -134,6 +150,16 @@ interface ITypeSymbol : IMemberSymbol /// bool IsPointer { get; } + /// + /// Gets a value that indicates whether the current is an unmanaged function pointer. + /// + bool IsFunctionPointer { get; } + + /// + /// Gets a value that indicates whether the current is an unmanaged function pointer. + /// + bool IsUnmanagedFunctionPointer { get; } + /// /// Gets a value indicating whether the is passed by reference. /// @@ -204,6 +230,16 @@ interface ITypeSymbol : IMemberSymbol /// bool IsSerializable { get; } + /// + /// Gets a value that indicates whether the type is a signature type. + /// + bool IsSignatureType { get; } + + /// + /// Gets a value indicating whether the type has a name that requires special handling. + /// + bool IsSpecialName { get; } + /// /// Gets the initializer for the type. /// @@ -280,10 +316,10 @@ interface ITypeSymbol : IMemberSymbol ITypeSymbol? GetInterface(string name, bool ignoreCase); /// - /// When overridden in a derived class, gets all the interfaces implemented or inherited by the current . + /// When overridden in a derived class, gets all the interfaces implemented or if specified,inherited by the current . /// /// - ITypeSymbol[] GetInterfaces(); + ITypeSymbol[] GetInterfaces(bool inherit = true); /// /// Returns an interface mapping for the specified interface type. diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs index 987c8af15..19b75b993 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs @@ -43,39 +43,57 @@ internal IkvmReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) return _modules.GetValue(module, _ => new IkvmReflectionModuleSymbol(Context, _)); } + /// + /// Gets the wrapped . + /// internal Assembly ReflectionObject => _assembly; + /// public IEnumerable DefinedTypes => ResolveTypeSymbols(_assembly.DefinedTypes); + /// public IMethodSymbol? EntryPoint => _assembly.EntryPoint is { } m ? ResolveMethodSymbol(m) : null; + /// public IEnumerable ExportedTypes => ResolveTypeSymbols(_assembly.ExportedTypes); + /// public string? FullName => _assembly.FullName; + /// public string ImageRuntimeVersion => _assembly.ImageRuntimeVersion; + /// public IModuleSymbol ManifestModule => ResolveModuleSymbol(_assembly.ManifestModule); + /// public IEnumerable Modules => ResolveModuleSymbols(_assembly.Modules); + /// public override bool IsMissing => _assembly.__IsMissing; + /// + public override bool ContainsMissing => GetModules().Any(i => i.IsMissing || i.ContainsMissing); + + /// public ITypeSymbol[] GetExportedTypes() { return ResolveTypeSymbols(_assembly.GetExportedTypes()); } + /// public IModuleSymbol? GetModule(string name) { return _assembly.GetModule(name) is Module m ? GetOrCreateModuleSymbol(m) : null; } + /// public IModuleSymbol[] GetModules() { return ResolveModuleSymbols(_assembly.GetModules()); } + /// public IModuleSymbol[] GetModules(bool getResourceModules) { return ResolveModuleSymbols(_assembly.GetModules(getResourceModules)); @@ -96,16 +114,19 @@ System.Reflection.AssemblyName ToName(AssemblyName src) #pragma warning restore SYSLIB0037 // Type or member is obsolete } + /// public System.Reflection.AssemblyName GetName() { return _assemblyName ??= ToName(_assembly.GetName()); } + /// public System.Reflection.AssemblyName GetName(bool copiedName) { return ToName(_assembly.GetName()); } + /// public System.Reflection.AssemblyName[] GetReferencedAssemblies() { var l = _assembly.GetReferencedAssemblies(); @@ -116,40 +137,44 @@ public System.Reflection.AssemblyName[] GetReferencedAssemblies() return a; } + /// public ITypeSymbol? GetType(string name, bool throwOnError) { return _assembly.GetType(name, throwOnError) is Type t ? Context.GetOrCreateTypeSymbol(t) : null; } + /// public ITypeSymbol? GetType(string name, bool throwOnError, bool ignoreCase) { return _assembly.GetType(name, throwOnError, ignoreCase) is Type t ? Context.GetOrCreateTypeSymbol(t) : null; } + /// public ITypeSymbol? GetType(string name) { return _assembly.GetType(name) is Type t ? Context.GetOrCreateTypeSymbol(t) : null; } + /// public ITypeSymbol[] GetTypes() { return ResolveTypeSymbols(_assembly.GetTypes()); } /// - public CustomAttributeSymbol[] GetCustomAttributes(bool inherit = false) + public CustomAttribute[] GetCustomAttributes(bool inherit = false) { return ResolveCustomAttributes(_assembly.GetCustomAttributesData()); } /// - public CustomAttributeSymbol[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) + public CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) { return ResolveCustomAttributes(_assembly.__GetCustomAttributes(((IkvmReflectionTypeSymbol)attributeType).ReflectionObject, false)); } /// - public CustomAttributeSymbol? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) + public CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) { return GetCustomAttributes(attributeType, inherit).FirstOrDefault(); } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs index 70fcc692f..c01581bda 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs @@ -48,8 +48,8 @@ static T[] Concat(List? list) readonly IkvmReflectionTypeSymbol? _type; readonly MemberInfo _member; - CustomAttributeSymbol[]? _customAttributes; - CustomAttributeSymbol[]? _inheritedCustomAttributes; + CustomAttribute[]? _customAttributes; + CustomAttribute[]? _inheritedCustomAttributes; /// /// Initializes a new instance. @@ -158,7 +158,9 @@ protected internal override IkvmReflectionEventSymbol ResolveEventSymbol(EventIn return base.ResolveEventSymbol(@event); } - /// + /// + /// Gets the wrapped . + /// internal MemberInfo ReflectionObject => _member; /// @@ -186,7 +188,7 @@ protected internal override IkvmReflectionEventSymbol ResolveEventSymbol(EventIn public override bool IsMissing => _member.__IsMissing; /// - public virtual CustomAttributeSymbol[] GetCustomAttributes(bool inherit = false) + public virtual CustomAttribute[] GetCustomAttributes(bool inherit = false) { if (inherit) { @@ -195,7 +197,7 @@ public virtual CustomAttributeSymbol[] GetCustomAttributes(bool inherit = false) return _inheritedCustomAttributes; var self = _member; - var list = default(List?); + var list = default(List?); for (; ; ) { // get attribute for current member and append to list @@ -237,13 +239,13 @@ public virtual CustomAttributeSymbol[] GetCustomAttributes(bool inherit = false) } /// - public virtual CustomAttributeSymbol[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) + public virtual CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) { return ResolveCustomAttributes(_member.__GetCustomAttributes(((IkvmReflectionTypeSymbol)attributeType).ReflectionObject, inherit)); } /// - public virtual CustomAttributeSymbol? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) + public virtual CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) { return GetCustomAttributes(attributeType, inherit).FirstOrDefault(); } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodBaseSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodBaseSymbol.cs index 644d3f05c..f62f4d444 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodBaseSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodBaseSymbol.cs @@ -71,54 +71,84 @@ internal IkvmReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo return sym; } + /// + /// Gets the wrapped . + /// + internal new MethodBase ReflectionObject => _method; + + /// public System.Reflection.MethodAttributes Attributes => (System.Reflection.MethodAttributes)_method.Attributes; + /// public System.Reflection.CallingConventions CallingConvention => (System.Reflection.CallingConventions)_method.CallingConvention; + /// public bool ContainsGenericParameters => _method.ContainsGenericParameters; + /// public bool IsAbstract => _method.IsAbstract; + /// public bool IsAssembly => _method.IsAssembly; + /// public bool IsConstructor => _method.IsConstructor; + /// public bool IsFamily => _method.IsFamily; + /// public bool IsFamilyAndAssembly => _method.IsFamilyAndAssembly; + /// public bool IsFamilyOrAssembly => _method.IsFamilyOrAssembly; + /// public bool IsFinal => _method.IsFinal; + /// public bool IsGenericMethod => _method.IsGenericMethod; + /// public bool IsGenericMethodDefinition => _method.IsGenericMethodDefinition; + /// public bool IsHideBySig => _method.IsHideBySig; + /// public bool IsPrivate => _method.IsPrivate; + /// public bool IsPublic => _method.IsPublic; + /// public bool IsSpecialName => _method.IsSpecialName; + /// public bool IsStatic => _method.IsStatic; + /// public bool IsVirtual => _method.IsVirtual; + /// public System.Reflection.MethodImplAttributes MethodImplementationFlags => (System.Reflection.MethodImplAttributes)_method.MethodImplementationFlags; + /// + public override bool ContainsMissing => GetGenericArguments().Any(i => i.IsMissing || i.ContainsMissing) || GetParameters().Any(i => i.IsMissing || i.ContainsMissing); + + /// public ITypeSymbol[] GetGenericArguments() { return ResolveTypeSymbols(_method.GetGenericArguments()); } + /// public System.Reflection.MethodImplAttributes GetMethodImplementationFlags() { return (System.Reflection.MethodImplAttributes)_method.GetMethodImplementationFlags(); } + /// public IParameterSymbol[] GetParameters() { return ResolveParameterSymbols(_method.GetParameters()); diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodSymbol.cs index 51fbc6a32..c18969aa2 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodSymbol.cs @@ -109,7 +109,7 @@ internal IkvmReflectionMethodSymbol GetOrCreateGenericTypeSymbol(Type[] genericM public ITypeSymbol ReturnType => ResolveTypeSymbol(_method.ReturnType); - public ICustomAttributeSymbolProvider ReturnTypeCustomAttributes => throw new NotImplementedException(); + public ICustomAttributeProvider ReturnTypeCustomAttributes => throw new NotImplementedException(); public IMethodSymbol GetBaseDefinition() { diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs index f1a88c657..eacc58c3b 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs @@ -177,6 +177,9 @@ IkvmReflectionTypeSymbol GetOrCreateTypeSymbolForSpecification(Type type) /// public override bool IsMissing => _module.__IsMissing; + /// + public override bool ContainsMissing => GetTypes().Any(t => t.IsMissing || t.ContainsMissing); + /// public IFieldSymbol? GetField(string name) { @@ -333,19 +336,19 @@ public ITypeSymbol ResolveType(int metadataToken, ITypeSymbol[]? genericTypeArgu } /// - public CustomAttributeSymbol[] GetCustomAttributes(bool inherit = false) + public CustomAttribute[] GetCustomAttributes(bool inherit = false) { return ResolveCustomAttributes(_module.GetCustomAttributesData()); } /// - public CustomAttributeSymbol[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) + public CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) { return ResolveCustomAttributes(_module.__GetCustomAttributes(((IkvmReflectionTypeSymbol)attributeType).ReflectionObject, false)); } /// - public CustomAttributeSymbol? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) + public CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) { return GetCustomAttributes(attributeType, inherit).FirstOrDefault(); } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterSymbol.cs index 80a558f4b..cc3e18be6 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterSymbol.cs @@ -1,6 +1,5 @@ using System; using System.Linq; -using System.Runtime.InteropServices; using ParameterInfo = IKVM.Reflection.ParameterInfo; @@ -10,64 +9,77 @@ namespace IKVM.CoreLib.Symbols.IkvmReflection class IkvmReflectionParameterSymbol : IkvmReflectionSymbol, IParameterSymbol { + readonly IkvmReflectionMethodBaseSymbol _containingMethod; readonly ParameterInfo _parameter; - readonly IkvmReflectionMethodBaseSymbol _method; /// /// Initializes a new instance. /// /// - /// + /// /// - public IkvmReflectionParameterSymbol(IkvmReflectionSymbolContext context, IkvmReflectionMethodBaseSymbol method, ParameterInfo parameter) : + public IkvmReflectionParameterSymbol(IkvmReflectionSymbolContext context, IkvmReflectionMethodBaseSymbol containingMethod, ParameterInfo parameter) : base(context) { - _method = method ?? throw new ArgumentNullException(nameof(method)); + _containingMethod = containingMethod ?? throw new ArgumentNullException(nameof(containingMethod)); _parameter = parameter ?? throw new ArgumentNullException(nameof(parameter)); } - internal IkvmReflectionMethodBaseSymbol ContainingMethod => _method; + internal IkvmReflectionMethodBaseSymbol ContainingMethod => _containingMethod; + /// public System.Reflection.ParameterAttributes Attributes => (System.Reflection.ParameterAttributes)_parameter.Attributes; + /// public object DefaultValue => _parameter.RawDefaultValue; + /// public bool HasDefaultValue => _parameter.HasDefaultValue; + /// public bool IsIn => _parameter.IsIn; + /// public bool IsLcid => _parameter.IsLcid; + /// public bool IsOptional => _parameter.IsOptional; + /// public bool IsOut => _parameter.IsOut; + /// public bool IsRetval => _parameter.IsRetval; + /// public IMemberSymbol Member => ResolveMemberSymbol(_parameter.Member); + /// public int MetadataToken => _parameter.MetadataToken; + /// public string? Name => _parameter.Name; + /// public ITypeSymbol ParameterType => ResolveTypeSymbol(_parameter.ParameterType); + /// public int Position => _parameter.Position; /// - public CustomAttributeSymbol[] GetCustomAttributes(bool inherit = false) + public CustomAttribute[] GetCustomAttributes(bool inherit = false) { return ResolveCustomAttributes(_parameter.GetCustomAttributesData()); } /// - public virtual CustomAttributeSymbol[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) + public virtual CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) { return ResolveCustomAttributes(_parameter.__GetCustomAttributes(((IkvmReflectionTypeSymbol)attributeType).ReflectionObject, inherit)); } /// - public virtual CustomAttributeSymbol? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) + public virtual CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) { return GetCustomAttributes(attributeType, inherit).FirstOrDefault(); } @@ -77,6 +89,19 @@ public virtual bool IsDefined(ITypeSymbol attributeType, bool inherit = false) { return _parameter.IsDefined(((IkvmReflectionTypeSymbol)attributeType).ReflectionObject, inherit); } + + /// + public ITypeSymbol[] GetOptionalCustomModifiers() + { + return ResolveTypeSymbols(_parameter.GetOptionalCustomModifiers()); + } + + /// + public ITypeSymbol[] GetRequiredCustomModifiers() + { + return ResolveTypeSymbols(_parameter.GetRequiredCustomModifiers()); + } + } } \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs index e1bf81bf8..f0d642b56 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs @@ -40,6 +40,9 @@ public IkvmReflectionSymbol(IkvmReflectionSymbolContext context) /// public virtual bool IsMissing => false; + /// + public virtual bool ContainsMissing => false; + /// /// Resolves the symbol for the specified type. /// @@ -350,9 +353,9 @@ protected internal IkvmReflectionEventSymbol[] ResolveEventSymbols(EventInfo[] e /// /// /// - protected internal CustomAttributeSymbol[] ResolveCustomAttributes(IList attributes) + protected internal CustomAttribute[] ResolveCustomAttributes(IList attributes) { - var a = new CustomAttributeSymbol[attributes.Count]; + var a = new CustomAttribute[attributes.Count]; for (int i = 0; i < attributes.Count; i++) a[i] = ResolveCustomAttribute(attributes[i]); @@ -365,9 +368,9 @@ protected internal CustomAttributeSymbol[] ResolveCustomAttributes(IList /// /// - protected internal CustomAttributeSymbol ResolveCustomAttribute(CustomAttributeData customAttributeData) + protected internal CustomAttribute ResolveCustomAttribute(CustomAttributeData customAttributeData) { - return new CustomAttributeSymbol( + return new CustomAttribute( ResolveTypeSymbol(customAttributeData.AttributeType), ResolveConstructorSymbol(customAttributeData.Constructor), ResolveCustomAttributeTypedArguments(customAttributeData.ConstructorArguments), @@ -375,13 +378,13 @@ protected internal CustomAttributeSymbol ResolveCustomAttribute(CustomAttributeD } /// - /// Transforms a list of values into symbols. + /// Transforms a list of values into symbols. /// /// /// - ImmutableArray ResolveCustomAttributeTypedArguments(IList args) + ImmutableArray ResolveCustomAttributeTypedArguments(IList args) { - var a = new CustomAttributeSymbolTypedArgument[args.Count]; + var a = new CustomAttributeTypedArgument[args.Count]; for (int i = 0; i < args.Count; i++) a[i] = ResolveCustomAttributeTypedArgument(args[i]); @@ -389,23 +392,36 @@ ImmutableArray ResolveCustomAttributeTypedAr } /// - /// Transforms a values into a symbol. + /// Transforms a values into a symbol. /// /// /// - CustomAttributeSymbolTypedArgument ResolveCustomAttributeTypedArgument(CustomAttributeTypedArgument arg) + CustomAttributeTypedArgument ResolveCustomAttributeTypedArgument(IKVM.Reflection.CustomAttributeTypedArgument arg) { - return new CustomAttributeSymbolTypedArgument(ResolveTypeSymbol(arg.ArgumentType), arg.Value); + return new CustomAttributeTypedArgument(ResolveTypeSymbol(arg.ArgumentType), ResolveCustomAttributeTypedValue(arg.Value)); + } + + /// + /// Transforms the type as appropriate. + /// + /// + /// + object? ResolveCustomAttributeTypedValue(object? value) + { + if (value is IKVM.Reflection.Type v) + return ResolveTypeSymbol(v); + + return value; } /// - /// Transforms a list of values into symbols. + /// Transforms a list of values into symbols. /// /// /// - ImmutableArray ResolveCustomAttributeNamedArguments(IList args) + ImmutableArray ResolveCustomAttributeNamedArguments(IList args) { - var a = new CustomAttributeSymbolNamedArgument[args.Count]; + var a = new CustomAttributeNamedArgument[args.Count]; for (int i = 0; i < args.Count; i++) a[i] = ResolveCustomAttributeNamedArgument(args[i]); @@ -413,13 +429,13 @@ ImmutableArray ResolveCustomAttributeNamedAr } /// - /// Transforms a values into a symbol. + /// Transforms a values into a symbol. /// /// /// - CustomAttributeSymbolNamedArgument ResolveCustomAttributeNamedArgument(CustomAttributeNamedArgument arg) + CustomAttributeNamedArgument ResolveCustomAttributeNamedArgument(IKVM.Reflection.CustomAttributeNamedArgument arg) { - return new CustomAttributeSymbolNamedArgument(arg.IsField, ResolveMemberSymbol(arg.MemberInfo), arg.MemberName, ResolveCustomAttributeTypedArgument(arg.TypedValue)); + return new CustomAttributeNamedArgument(arg.IsField, ResolveMemberSymbol(arg.MemberInfo), arg.MemberName, ResolveCustomAttributeTypedArgument(arg.TypedValue)); } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs index 84c73c898..aad2c1979 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs @@ -461,260 +461,363 @@ protected internal override IkvmReflectionEventSymbol ResolveEventSymbol(EventIn /// internal new Type ReflectionObject => _type; + /// public IAssemblySymbol Assembly => Context.GetOrCreateAssemblySymbol(_type.Assembly); + /// public string? AssemblyQualifiedName => _type.AssemblyQualifiedName; + /// public System.Reflection.TypeAttributes Attributes => (System.Reflection.TypeAttributes)(int)_type.Attributes; + /// public ITypeSymbol? BaseType => _type.BaseType != null ? ResolveTypeSymbol(_type.BaseType) : null; + /// public bool ContainsGenericParameters => _type.ContainsGenericParameters; + /// public IMethodBaseSymbol? DeclaringMethod => _type.DeclaringMethod is MethodInfo m ? ResolveMethodSymbol(m) : null; + /// public string? FullName => _type.FullName; + /// + public string? Namespace => _type.Namespace; + + /// public System.Reflection.GenericParameterAttributes GenericParameterAttributes => (System.Reflection.GenericParameterAttributes)(int)_type.GenericParameterAttributes; + /// public int GenericParameterPosition => _type.GenericParameterPosition; + /// public ITypeSymbol[] GenericTypeArguments => ResolveTypeSymbols(_type.GenericTypeArguments); + /// public bool HasElementType => _type.HasElementType; + /// public bool IsAbstract => _type.IsAbstract; + /// + public bool IsSZArray => _type.IsSZArray; + + /// public bool IsArray => _type.IsArray; + /// public bool IsAutoLayout => _type.IsAutoLayout; + /// + public bool IsExplicitLayout => _type.IsExplicitLayout; + + /// public bool IsByRef => _type.IsByRef; + /// public bool IsClass => _type.IsClass; + /// public bool IsConstructedGenericType => _type.IsConstructedGenericType; + /// public bool IsEnum => _type.IsEnum; - public bool IsExplicitLayout => _type.IsExplicitLayout; - + /// public bool IsGenericParameter => _type.IsGenericParameter; + /// public bool IsGenericType => _type.IsGenericType; + /// public bool IsGenericTypeDefinition => _type.IsGenericTypeDefinition; + /// public bool IsInterface => _type.IsInterface; + /// public bool IsLayoutSequential => _type.IsLayoutSequential; + /// public bool IsNested => _type.IsNested; + /// public bool IsNestedAssembly => _type.IsNestedAssembly; + /// public bool IsNestedFamANDAssem => _type.IsNestedFamANDAssem; + /// public bool IsNestedFamORAssem => _type.IsNestedFamORAssem; + /// public bool IsNestedFamily => _type.IsNestedFamily; + /// public bool IsNestedPrivate => _type.IsNestedPrivate; + /// public bool IsNestedPublic => _type.IsNestedPublic; + /// public bool IsNotPublic => _type.IsNotPublic; + /// public bool IsPointer => _type.IsPointer; + /// + public bool IsFunctionPointer => _type.IsFunctionPointer; + + /// + public bool IsUnmanagedFunctionPointer => _type.IsUnmanagedFunctionPointer; + + /// public bool IsPrimitive => _type.IsPrimitive; + /// public bool IsPublic => _type.IsPublic; + /// public bool IsSealed => _type.IsSealed; #pragma warning disable SYSLIB0050 // Type or member is obsolete + /// public bool IsSerializable => _type.IsSerializable; #pragma warning restore SYSLIB0050 // Type or member is obsolete + /// public bool IsValueType => _type.IsValueType; + /// public bool IsVisible => _type.IsVisible; - public string? Namespace => _type.Namespace; + /// + public bool IsSignatureType => throw new NotImplementedException(); + + /// + public bool IsSpecialName => _type.IsSpecialName; + + /// + public TypeCode TypeCode => Type.GetTypeCode(_type); + /// public IConstructorSymbol? TypeInitializer => _type.TypeInitializer is ConstructorInfo ctor ? ResolveConstructorSymbol(ctor) : null; + /// + public override bool IsMissing => _type.__IsMissing; + + /// + public override bool ContainsMissing => _type.__ContainsMissingType; + + /// public int GetArrayRank() { return _type.GetArrayRank(); } + /// public IConstructorSymbol? GetConstructor(System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) { return _type.GetConstructor((BindingFlags)bindingAttr, binder: null, UnpackTypeSymbols(types), modifiers: null) is ConstructorInfo ctor ? ResolveConstructorSymbol(ctor) : null; } + /// public IConstructorSymbol? GetConstructor(ITypeSymbol[] types) { return _type.GetConstructor(UnpackTypeSymbols(types)) is ConstructorInfo ctor ? ResolveConstructorSymbol(ctor) : null; } + /// public IConstructorSymbol[] GetConstructors() { return ResolveConstructorSymbols(_type.GetConstructors()); } + /// public IConstructorSymbol[] GetConstructors(System.Reflection.BindingFlags bindingAttr) { return ResolveConstructorSymbols(_type.GetConstructors((BindingFlags)bindingAttr)); } + /// public IMemberSymbol[] GetDefaultMembers() { return ResolveMemberSymbols(_type.GetDefaultMembers()); } + /// public ITypeSymbol? GetElementType() { return _type.GetElementType() is Type t ? ResolveTypeSymbol(t) : null; } + /// public string? GetEnumName(object value) { return _type.GetEnumName(value); } + /// public string[] GetEnumNames() { return _type.GetEnumNames(); } + /// public ITypeSymbol GetEnumUnderlyingType() { return ResolveTypeSymbol(_type.GetEnumUnderlyingType()); } + /// public IEventSymbol? GetEvent(string name, System.Reflection.BindingFlags bindingAttr) { return _type.GetEvent(name, (BindingFlags)bindingAttr) is { } f ? ResolveEventSymbol(f) : null; } + /// public IEventSymbol? GetEvent(string name) { return _type.GetEvent(name) is { } f ? ResolveEventSymbol(f) : null; } + /// public IEventSymbol[] GetEvents() { return ResolveEventSymbols(_type.GetEvents()); } + /// public IEventSymbol[] GetEvents(System.Reflection.BindingFlags bindingAttr) { return ResolveEventSymbols(_type.GetEvents((BindingFlags)bindingAttr)); } + /// public IFieldSymbol? GetField(string name) { return _type.GetField(name) is FieldInfo f ? ResolveFieldSymbol(f) : null; } + /// public IFieldSymbol? GetField(string name, System.Reflection.BindingFlags bindingAttr) { return _type.GetField(name, (BindingFlags)bindingAttr) is FieldInfo f ? ResolveFieldSymbol(f) : null; } + /// public IFieldSymbol[] GetFields() { return ResolveFieldSymbols(_type.GetFields()); } + /// public IFieldSymbol[] GetFields(System.Reflection.BindingFlags bindingAttr) { return ResolveFieldSymbols(_type.GetFields((BindingFlags)bindingAttr)); } + /// public ITypeSymbol[] GetGenericArguments() { return ResolveTypeSymbols(_type.GetGenericArguments()); } + /// public ITypeSymbol[] GetGenericParameterConstraints() { return ResolveTypeSymbols(_type.GetGenericParameterConstraints()); } + /// public ITypeSymbol GetGenericTypeDefinition() { return ResolveTypeSymbol(_type.GetGenericTypeDefinition()); } + /// public ITypeSymbol? GetInterface(string name) { return _type.GetInterface(name) is { } i ? ResolveTypeSymbol(i) : null; } + /// public ITypeSymbol? GetInterface(string name, bool ignoreCase) { return _type.GetInterface(name, ignoreCase) is { } i ? ResolveTypeSymbol(i) : null; } + /// public InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) { throw new NotImplementedException(); } - public ITypeSymbol[] GetInterfaces() + /// + public ITypeSymbol[] GetInterfaces(bool inherit = true) { - return ResolveTypeSymbols(_type.GetInterfaces()); + if (inherit) + return ResolveTypeSymbols(_type.GetInterfaces()); + else + return ResolveTypeSymbols(_type.__GetDeclaredInterfaces()); } + /// public IMemberSymbol[] GetMember(string name) { return ResolveMemberSymbols(_type.GetMember(name)); } + /// public IMemberSymbol[] GetMember(string name, System.Reflection.BindingFlags bindingAttr) { return ResolveMemberSymbols(_type.GetMember(name, (BindingFlags)bindingAttr)); } + /// public IMemberSymbol[] GetMember(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) { return ResolveMemberSymbols(_type.GetMember(name, (MemberTypes)type, (BindingFlags)bindingAttr)); } + /// public IMemberSymbol[] GetMembers(System.Reflection.BindingFlags bindingAttr) { return ResolveMemberSymbols(_type.GetMembers((BindingFlags)bindingAttr)); } + /// public IMemberSymbol[] GetMembers() { return ResolveMemberSymbols(_type.GetMembers()); } + /// public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr) { return _type.GetMethod(name, (BindingFlags)bindingAttr) is { } m ? ResolveMethodSymbol(m) : null; } + /// public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) { return _type.GetMethod(name, (BindingFlags)bindingAttr, null, UnpackTypeSymbols(types), null) is { } m ? ResolveMethodSymbol(m) : null; } + /// public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) { return _type.GetMethod(name, UnpackTypeSymbols(types)) is { } m ? ResolveMethodSymbol(m) : null; } + /// public IMethodSymbol? GetMethod(string name) { return _type.GetMethod(name) is { } m ? ResolveMethodSymbol(m) : null; } + /// public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { if (modifiers != null) @@ -723,46 +826,55 @@ public IMemberSymbol[] GetMembers() return _type.GetMethod(name, UnpackTypeSymbols(types), null) is { } m ? ResolveMethodSymbol(m) : null; } + /// public IMethodSymbol[] GetMethods(System.Reflection.BindingFlags bindingAttr) { return ResolveMethodSymbols(_type.GetMethods((BindingFlags)bindingAttr)); } + /// public IMethodSymbol[] GetMethods() { return ResolveMethodSymbols(_type.GetMethods()); } + /// public ITypeSymbol? GetNestedType(string name) { return _type.GetNestedType(name) is Type t ? ResolveTypeSymbol(t) : null; } + /// public ITypeSymbol? GetNestedType(string name, System.Reflection.BindingFlags bindingAttr) { return _type.GetNestedType(name, (BindingFlags)bindingAttr) is Type t ? ResolveTypeSymbol(t) : null; } + /// public ITypeSymbol[] GetNestedTypes() { return ResolveTypeSymbols(_type.GetNestedTypes()); } + /// public ITypeSymbol[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr) { return ResolveTypeSymbols(_type.GetNestedTypes((BindingFlags)bindingAttr)); } + /// public IPropertySymbol[] GetProperties() { return ResolvePropertySymbols(_type.GetProperties()); } + /// public IPropertySymbol[] GetProperties(System.Reflection.BindingFlags bindingAttr) { return ResolvePropertySymbols(_type.GetProperties((BindingFlags)bindingAttr)); } + /// public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { if (modifiers != null) @@ -772,27 +884,32 @@ public IPropertySymbol[] GetProperties(System.Reflection.BindingFlags bindingAtt return _type.GetProperty(name, _returnType, UnpackTypeSymbols(types), null) is { } p ? ResolvePropertySymbol(p) : null; } + /// public IPropertySymbol? GetProperty(string name, ITypeSymbol[] types) { return _type.GetProperty(name, UnpackTypeSymbols(types)) is { } p ? ResolvePropertySymbol(p) : null; } + /// public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types) { var _returnType = returnType != null ? ((IkvmReflectionTypeSymbol)returnType).ReflectionObject : null; return _type.GetProperty(name, _returnType, UnpackTypeSymbols(types)) is { } p ? ResolvePropertySymbol(p) : null; } + /// public IPropertySymbol? GetProperty(string name, System.Reflection.BindingFlags bindingAttr) { return _type.GetProperty(name, (BindingFlags)bindingAttr) is { } p ? ResolvePropertySymbol(p) : null; } + /// public IPropertySymbol? GetProperty(string name) { return _type.GetProperty(name) is { } p ? ResolvePropertySymbol(p) : null; } + /// public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) { var _returnType = returnType != null ? ((IkvmReflectionTypeSymbol)returnType).ReflectionObject : null; @@ -800,21 +917,25 @@ public IPropertySymbol[] GetProperties(System.Reflection.BindingFlags bindingAtt return _type.GetProperty(name, _returnType) is { } p ? ResolvePropertySymbol(p) : null; } + /// public bool IsAssignableFrom(ITypeSymbol? c) { return _type.IsAssignableFrom(c != null ? ((IkvmReflectionTypeSymbol)c).ReflectionObject : null); } + /// public bool IsEnumDefined(object value) { return _type.IsEnumDefined(value); } + /// public bool IsSubclassOf(ITypeSymbol c) { return _type.IsSubclassOf(((IkvmReflectionTypeSymbol)c).ReflectionObject); } + /// public ITypeSymbol MakeArrayType() { if (_asSZArray == null) @@ -823,6 +944,7 @@ public ITypeSymbol MakeArrayType() return _asSZArray; } + /// public ITypeSymbol MakeArrayType(int rank) { if (rank == 1) @@ -838,6 +960,7 @@ public ITypeSymbol MakeArrayType(int rank) return asArray; } + /// public ITypeSymbol MakeByRefType() { if (_asByRef == null) @@ -846,11 +969,13 @@ public ITypeSymbol MakeByRefType() return _asByRef; } + /// public ITypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments) { throw new NotImplementedException(); } + /// public ITypeSymbol MakePointerType() { if (_asPointer == null) diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs new file mode 100644 index 000000000..ee8c1f687 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs @@ -0,0 +1,49 @@ +using System; +using System.Reflection.Emit; + +using IKVM.CoreLib.Symbols.Emit; + +namespace IKVM.CoreLib.Symbols.Reflection.Emit +{ + + class ReflectionAssemblySymbolBuilder : ReflectionSymbolBuilder, IAssemblySymbolBuilder + { + + readonly AssemblyBuilder _builder; + ReflectionAssemblySymbol? _symbol; + + /// + /// Initializes a new instance. + /// + /// + /// + public ReflectionAssemblySymbolBuilder(ReflectionSymbolContext context, AssemblyBuilder builder) : + base(context) + { + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + } + + /// + internal sealed override ReflectionAssemblySymbol ReflectionSymbol => _symbol ??= Context.GetOrCreateAssemblySymbol(_builder); + + /// + public IModuleSymbolBuilder DefineModule(string name) + { + return new ReflectionModuleSymbolBuilder(Context, _builder.DefineDynamicModule(name)); + } + + /// + public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) + { + _builder.SetCustomAttribute(con.Unpack(), binaryAttribute); + } + + /// + public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) + { + _builder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).ReflectionBuilder); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionConstructorSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionConstructorSymbolBuilder.cs new file mode 100644 index 000000000..e351e1813 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionConstructorSymbolBuilder.cs @@ -0,0 +1,74 @@ +using System; +using System.Reflection; +using System.Reflection.Emit; + +using IKVM.CoreLib.Symbols.Emit; + +namespace IKVM.CoreLib.Symbols.Reflection.Emit +{ + + class ReflectionConstructorSymbolBuilder : ReflectionMethodBaseSymbolBuilder, IConstructorSymbolBuilder + { + + readonly ConstructorBuilder _builder; + ReflectionConstructorSymbol? _symbol; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + public ReflectionConstructorSymbolBuilder(ReflectionSymbolContext context, ReflectionTypeSymbolBuilder containingTypeBuilder, ConstructorBuilder builder) : + base(context, containingTypeBuilder) + { + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + } + + /// + /// Gets the containing . + /// + protected internal new ReflectionTypeSymbolBuilder ContainingTypeBuilder => base.ContainingTypeBuilder ?? throw new NullReferenceException(); + + /// + internal override ReflectionConstructorSymbol ReflectionSymbol => _symbol ??= Context.GetOrCreateConstructorSymbol(_builder); + + /// + public void SetImplementationFlags(MethodImplAttributes attributes) + { + _builder.SetImplementationFlags(attributes); + } + + /// + public IParameterSymbolBuilder DefineParameter(int iSequence, ParameterAttributes attributes, string? strParamName) + { + return new ReflectionParameterSymbolBuilder(Context, this, _builder.DefineParameter(iSequence, attributes, strParamName)); + } + + /// + public ILGenerator GetILGenerator() + { + throw new NotImplementedException(); + } + + /// + public ILGenerator GetILGenerator(int streamSize) + { + throw new NotImplementedException(); + } + + /// + public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) + { + _builder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).ReflectionBuilder); + } + + /// + public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) + { + _builder.SetCustomAttribute(con.Unpack(), binaryAttribute); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionCustomAttributeBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionCustomAttributeBuilder.cs new file mode 100644 index 000000000..bb1978ec3 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionCustomAttributeBuilder.cs @@ -0,0 +1,29 @@ +using System; +using System.Reflection.Emit; + +using IKVM.CoreLib.Symbols.Emit; + +namespace IKVM.CoreLib.Symbols.Reflection.Emit +{ + + class ReflectionCustomAttributeBuilder : ICustomAttributeBuilder + { + + readonly CustomAttributeBuilder _builder; + + /// + /// Initializes a new instance. + /// + public ReflectionCustomAttributeBuilder(CustomAttributeBuilder builder) + { + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + } + + /// + /// Gets the underlying reflection . + /// + internal CustomAttributeBuilder ReflectionBuilder => _builder; + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionEventBuilderInfo.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionEventBuilderInfo.cs new file mode 100644 index 000000000..771ff9757 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionEventBuilderInfo.cs @@ -0,0 +1,81 @@ +using System; +using System.Reflection; +using System.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.Reflection.Emit +{ + + /// + /// Fake implementation that wraps a , which does not extend . + /// + class ReflectionEventBuilderInfo : EventInfo + { + + readonly EventBuilder _builder; + + /// + /// Initialies a new instance. + /// + /// + /// + public ReflectionEventBuilderInfo(EventBuilder builder) + { + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + } + + public override Module Module => _builder.GetModuleBuilder(); + + /// + public override Type? DeclaringType => _builder.GetTypeBuilder(); + + /// + public override EventAttributes Attributes => _builder.GetEventAttributes(); + + /// + public override string Name => _builder.GetEventName(); + + /// + public override Type? ReflectedType => DeclaringType; + + /// + public override int MetadataToken => _builder.GetMetadataToken(); + + /// + public override MethodInfo? GetAddMethod(bool nonPublic) + { + throw new NotImplementedException(); + } + + /// + public override MethodInfo? GetRemoveMethod(bool nonPublic) + { + throw new NotImplementedException(); + } + + /// + public override MethodInfo? GetRaiseMethod(bool nonPublic) + { + 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 bool IsDefined(Type attributeType, bool inherit) + { + throw new NotImplementedException(); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionEventSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionEventSymbolBuilder.cs new file mode 100644 index 000000000..fbc7ea865 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionEventSymbolBuilder.cs @@ -0,0 +1,72 @@ +using System; +using System.Reflection.Emit; + +using IKVM.CoreLib.Symbols.Emit; + +namespace IKVM.CoreLib.Symbols.Reflection.Emit +{ + + class ReflectionEventSymbolBuilder : ReflectionSymbolBuilder, IEventSymbolBuilder + { + + readonly ReflectionTypeSymbolBuilder _containingTypeBuilder; + readonly EventBuilder _builder; + readonly ReflectionEventBuilderInfo _info; + ReflectionEventSymbol? _symbol; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + public ReflectionEventSymbolBuilder(ReflectionSymbolContext context, ReflectionTypeSymbolBuilder containingTypeBuilder, EventBuilder builder) : + base(context) + { + _containingTypeBuilder = containingTypeBuilder ?? throw new ArgumentNullException(nameof(containingTypeBuilder)); + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + _info = new ReflectionEventBuilderInfo(_builder); + } + + /// + internal override ReflectionEventSymbol ReflectionSymbol => _symbol ??= _containingTypeBuilder.ReflectionSymbol.ResolveEventSymbol(_info); + + /// + public void SetAddOnMethod(IMethodSymbolBuilder mdBuilder) + { + _builder.SetAddOnMethod(((ReflectionMethodSymbolBuilder)mdBuilder).ReflectionBuilder); + } + + /// + public void SetRemoveOnMethod(IMethodSymbolBuilder mdBuilder) + { + _builder.SetRemoveOnMethod(((ReflectionMethodSymbolBuilder)mdBuilder).ReflectionBuilder); + } + + /// + public void SetRaiseMethod(IMethodSymbolBuilder mdBuilder) + { + _builder.SetRaiseMethod(((ReflectionMethodSymbolBuilder)mdBuilder).ReflectionBuilder); + } + + /// + public void AddOtherMethod(IMethodSymbolBuilder mdBuilder) + { + _builder.AddOtherMethod(((ReflectionMethodSymbolBuilder)mdBuilder).ReflectionBuilder); + } + + /// + public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) + { + _builder.SetCustomAttribute(con.Unpack(), binaryAttribute); + } + + /// + public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) + { + _builder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).ReflectionBuilder); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionFieldSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionFieldSymbolBuilder.cs new file mode 100644 index 000000000..241fbf8ed --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionFieldSymbolBuilder.cs @@ -0,0 +1,88 @@ +using System; +using System.Reflection.Emit; + +using IKVM.CoreLib.Symbols.Emit; + +namespace IKVM.CoreLib.Symbols.Reflection.Emit +{ + + class ReflectionFieldSymbolBuilder : ReflectionSymbolBuilder, IFieldSymbolBuilder + { + + readonly ReflectionModuleSymbolBuilder _containingModuleBuilder; + readonly ReflectionTypeSymbolBuilder? _containingTypeBuilder; + readonly FieldBuilder _builder; + ReflectionFieldSymbol? _symbol; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + public ReflectionFieldSymbolBuilder(ReflectionSymbolContext context, ReflectionModuleSymbolBuilder containingModuleBuilder, FieldBuilder builder) : + base(context) + { + _containingModuleBuilder = containingModuleBuilder ?? throw new ArgumentNullException(nameof(containingModuleBuilder)); + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + } + + /// + /// Initializes a new instance. + /// + /// + /// + /// + public ReflectionFieldSymbolBuilder(ReflectionSymbolContext context, ReflectionTypeSymbolBuilder containingTypeBuilder, FieldBuilder builder) : + base(context) + { + _containingTypeBuilder = containingTypeBuilder ?? throw new ArgumentNullException(nameof(containingTypeBuilder)); + _containingModuleBuilder = containingTypeBuilder.ContainingModuleBuilder; + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + } + + /// + /// Gets the containing . + /// + internal ReflectionModuleSymbolBuilder ContainingModuleBuilder => _containingModuleBuilder; + + /// + /// Gets the containing . + /// + internal ReflectionTypeSymbolBuilder? ContainingTypeBuilder => _containingTypeBuilder; + + /// + /// Gets the underlying + /// + internal FieldBuilder ReflectionBuilder => _builder; + + /// + internal override ReflectionFieldSymbol ReflectionSymbol => _symbol ??= Context.GetOrCreateFieldSymbol(_builder); + + /// + public void SetConstant(object? defaultValue) + { + _builder.SetConstant(defaultValue); + } + + /// + public void SetOffset(int iOffset) + { + _builder.SetOffset(iOffset); + } + + /// + public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) + { + _builder.SetCustomAttribute(con.Unpack(), binaryAttribute); + } + + /// + public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) + { + _builder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).ReflectionBuilder); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodBaseSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodBaseSymbolBuilder.cs new file mode 100644 index 000000000..f260f6819 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodBaseSymbolBuilder.cs @@ -0,0 +1,49 @@ +using System; + +namespace IKVM.CoreLib.Symbols.Reflection.Emit +{ + + abstract class ReflectionMethodBaseSymbolBuilder : ReflectionSymbolBuilder + where TSymbol : ISymbol + where TReflectionSymbol : ReflectionSymbol, TSymbol + { + + readonly ReflectionModuleSymbolBuilder _containingModuleBuilder; + readonly ReflectionTypeSymbolBuilder? _containingTypeBuilder; + + /// + /// Initializes a new instance. + /// + /// + /// + protected ReflectionMethodBaseSymbolBuilder(ReflectionSymbolContext context, ReflectionTypeSymbolBuilder containingTypeBuilder) : + base(context) + { + _containingTypeBuilder = containingTypeBuilder ?? throw new ArgumentNullException(nameof(containingTypeBuilder)); + _containingModuleBuilder = containingTypeBuilder.ContainingModuleBuilder; + } + + /// + /// Initializes a new instance. + /// + /// + /// + protected ReflectionMethodBaseSymbolBuilder(ReflectionSymbolContext context, ReflectionModuleSymbolBuilder containingModuleBuilder) : + base(context) + { + _containingModuleBuilder = containingModuleBuilder ?? throw new ArgumentNullException(nameof(containingModuleBuilder)); + } + + /// + /// Gets the containing . + /// + protected internal ReflectionModuleSymbolBuilder ContainingModuleBuilder => _containingModuleBuilder; + + /// + /// Gets the containing . + /// + protected internal ReflectionTypeSymbolBuilder? ContainingTypeBuilder => _containingTypeBuilder; + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs new file mode 100644 index 000000000..ce4b91294 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs @@ -0,0 +1,107 @@ +using System; +using System.Reflection; +using System.Reflection.Emit; + +using IKVM.CoreLib.Symbols.Emit; + +namespace IKVM.CoreLib.Symbols.Reflection.Emit +{ + + class ReflectionMethodSymbolBuilder : ReflectionMethodBaseSymbolBuilder, IMethodSymbolBuilder + { + + readonly MethodBuilder _builder; + ReflectionMethodSymbol? _symbol; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + public ReflectionMethodSymbolBuilder(ReflectionSymbolContext context, ReflectionModuleSymbolBuilder containingModuleBuilder, MethodBuilder builder) : + base(context, containingModuleBuilder) + { + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + } + + /// + /// Initializes a new instance. + /// + /// + /// + /// + public ReflectionMethodSymbolBuilder(ReflectionSymbolContext context, ReflectionTypeSymbolBuilder containingTypeBuilder, MethodBuilder builder) : + base(context, containingTypeBuilder) + { + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + } + + /// + /// Gets the that underlies this instance. + /// + internal MethodBuilder ReflectionBuilder => _builder; + + /// + internal override ReflectionMethodSymbol ReflectionSymbol => _symbol ??= Context.GetOrCreateMethodSymbol(_builder); + + /// + public void SetImplementationFlags(MethodImplAttributes attributes) + { + _builder.SetImplementationFlags(attributes); + } + + /// + public void SetParameters(params ITypeSymbol[] parameterTypes) + { + _builder.SetParameters(parameterTypes.Unpack()); + } + + /// + public void SetReturnType(ITypeSymbol? returnType) + { + _builder.SetReturnType(returnType?.Unpack()); + } + + /// + public void SetSignature(ITypeSymbol? returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers) + { + _builder.SetSignature(returnType?.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack()); + } + + public IGenericTypeParameterSymbolBuilder[] DefineGenericParameters(params string[] names) + { + throw new NotImplementedException(); + } + + /// + public IParameterSymbolBuilder DefineParameter(int position, ParameterAttributes attributes, string? strParamName) + { + return new ReflectionParameterSymbolBuilder(Context, this, _builder.DefineParameter(position, attributes, strParamName)); + } + + public IILGenerator GetILGenerator() + { + throw new NotImplementedException(); + } + + public IILGenerator GetILGenerator(int size) + { + throw new NotImplementedException(); + } + + /// + public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) + { + _builder.SetCustomAttribute(con.Unpack(), binaryAttribute); + } + + /// + public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) + { + _builder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).ReflectionBuilder); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionModuleSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionModuleSymbolBuilder.cs new file mode 100644 index 000000000..83f3a6ea1 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionModuleSymbolBuilder.cs @@ -0,0 +1,86 @@ +using System; +using System.Reflection; +using System.Reflection.Emit; + +using IKVM.CoreLib.Symbols.Emit; + +namespace IKVM.CoreLib.Symbols.Reflection.Emit +{ + + class ReflectionModuleSymbolBuilder : ReflectionSymbolBuilder, IModuleSymbolBuilder + { + + readonly ModuleBuilder _builder; + ReflectionModuleSymbol? _symbol; + + /// + /// Initializes a new instance. + /// + /// + /// + public ReflectionModuleSymbolBuilder(ReflectionSymbolContext context, ModuleBuilder builder) : + base(context) + { + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + } + + /// + internal override ReflectionModuleSymbol ReflectionSymbol => _symbol ??= Context.GetOrCreateModuleSymbol(_builder); + + /// + public ITypeSymbolBuilder DefineType(string name) + { + return new ReflectionTypeSymbolBuilder(Context, this, _builder.DefineType(name)); + } + + /// + public ITypeSymbolBuilder DefineType(string name, TypeAttributes attr, ITypeSymbol? parent, int typesize) + { + return new ReflectionTypeSymbolBuilder(Context, this, _builder.DefineType(name, attr, parent?.Unpack(), typesize)); + } + + /// + public ITypeSymbolBuilder DefineType(string name, TypeAttributes attr, ITypeSymbol? parent) + { + return new ReflectionTypeSymbolBuilder(Context, this, _builder.DefineType(name, attr, parent?.Unpack())); + } + + /// + public ITypeSymbolBuilder DefineType(string name, TypeAttributes attr) + { + return new ReflectionTypeSymbolBuilder(Context, this, _builder.DefineType(name, attr)); + } + + /// + public ITypeSymbolBuilder DefineType(string name, TypeAttributes attr, ITypeSymbol? parent, PackingSize packsize) + { + return new ReflectionTypeSymbolBuilder(Context, this, _builder.DefineType(name, attr, parent?.Unpack(), packsize)); + } + + /// + public ITypeSymbolBuilder DefineType(string name, TypeAttributes attr, ITypeSymbol? parent, PackingSize packingSize, int typesize) + { + return new ReflectionTypeSymbolBuilder(Context, this, _builder.DefineType(name, attr, parent?.Unpack(), packingSize, typesize)); + } + + /// + public ITypeSymbolBuilder DefineType(string name, TypeAttributes attr, ITypeSymbol? parent, ITypeSymbol[]? interfaces) + { + return new ReflectionTypeSymbolBuilder(Context, this, _builder.DefineType(name, attr, parent?.Unpack(), interfaces?.Unpack())); + } + + /// + public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) + { + _builder.SetCustomAttribute(con.Unpack(), binaryAttribute); + } + + /// + public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) + { + _builder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).ReflectionBuilder); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionParameterSymbolBuilder.cs new file mode 100644 index 000000000..fa908dac8 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionParameterSymbolBuilder.cs @@ -0,0 +1,102 @@ +using System; +using System.Reflection.Emit; + +using IKVM.CoreLib.Symbols.Emit; + +namespace IKVM.CoreLib.Symbols.Reflection.Emit +{ + + abstract class ReflectionParameterSymbolBuilder : ReflectionSymbolBuilder, IParameterSymbolBuilder + { + + readonly ParameterBuilder _builder; + readonly ReflectionParameterBuilderInfo _info; + ReflectionParameterSymbol? _symbol; + + object? _constant; + + /// + /// Initializes a new instance. + /// + /// + protected ReflectionParameterSymbolBuilder(ReflectionSymbolContext context, ParameterBuilder builder) : + base(context) + { + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + _info = new ReflectionParameterBuilderInfo(_builder); + } + + /// + /// Gets the wrapped . + /// + internal ParameterBuilder ReflectionBuilder => _builder; + + /// + internal override ReflectionParameterSymbol ReflectionSymbol => _symbol ??= GetOrCreateSymbol(_info); + + /// + /// Gets or creates the . + /// + /// + protected internal abstract ReflectionParameterSymbol GetOrCreateSymbol(ReflectionParameterBuilderInfo info); + + /// + public void SetConstant(object? defaultValue) + { + _builder.SetConstant(_constant = defaultValue); + } + + /// + /// Saves the constant value so it can be retrieved as a symbol. + /// + /// + internal object? GetConstant() + { + return _constant; + } + + /// + public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) + { + _builder.SetCustomAttribute(con.Unpack(), binaryAttribute); + } + + /// + public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) + { + _builder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).ReflectionBuilder); + } + + } + + class ReflectionParameterSymbolBuilder : ReflectionParameterSymbolBuilder + where TContainingSymbol : IMethodBaseSymbol + where TContainingReflectionSymbol : ReflectionMethodBaseSymbol, TContainingSymbol + where TContainingBuilder : ReflectionMethodBaseSymbolBuilder + { + + readonly TContainingBuilder _containingMethodBuilder; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + public ReflectionParameterSymbolBuilder(ReflectionSymbolContext context, TContainingBuilder containingMethodBuilder, ParameterBuilder builder) : + base(context, builder) + { + _containingMethodBuilder = containingMethodBuilder ?? throw new ArgumentNullException(nameof(containingMethodBuilder)); + } + + /// + /// Gets the containing . + /// + internal TContainingBuilder ContainingMethodBuilder => _containingMethodBuilder; + + /// + protected internal override ReflectionParameterSymbol GetOrCreateSymbol(ReflectionParameterBuilderInfo info) => ContainingMethodBuilder.ReflectionSymbol.ResolveParameterSymbol(info); + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionPropertySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionPropertySymbolBuilder.cs new file mode 100644 index 000000000..1d9a57c4b --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionPropertySymbolBuilder.cs @@ -0,0 +1,47 @@ +using System; +using System.Reflection.Emit; + +using IKVM.CoreLib.Symbols.Emit; + +namespace IKVM.CoreLib.Symbols.Reflection.Emit +{ + + class ReflectionPropertySymbolBuilder : ReflectionSymbolBuilder, IPropertySymbolBuilder + { + + readonly ReflectionTypeSymbolBuilder _containingTypeBuilder; + readonly PropertyBuilder _builder; + ReflectionPropertySymbol? _symbol; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + public ReflectionPropertySymbolBuilder(ReflectionSymbolContext context, ReflectionTypeSymbolBuilder containingTypeBuilder, PropertyBuilder builder) : + base(context) + { + _containingTypeBuilder = containingTypeBuilder ?? throw new ArgumentNullException(nameof(containingTypeBuilder)); + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + } + + internal PropertyBuilder ReflectionBuilder => _builder; + + internal override ReflectionPropertySymbol ReflectionSymbol => _symbol ??= _containingTypeBuilder.ReflectionSymbol.ResolvePropertySymbol(_builder); + + /// + public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) + { + _builder.SetCustomAttribute(con.Unpack(), binaryAttribute); + } + + /// + public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) + { + _builder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).ReflectionBuilder); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionSymbolBuilder.cs new file mode 100644 index 000000000..3ff29a8b2 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionSymbolBuilder.cs @@ -0,0 +1,94 @@ +using System; + +using IKVM.CoreLib.Symbols.Emit; + +namespace IKVM.CoreLib.Symbols.Reflection.Emit +{ + + /// + /// Reflection-specific implementation of . + /// + abstract class ReflectionSymbolBuilder : ISymbolBuilder + { + + readonly ReflectionSymbolContext _context; + + /// + /// Initializes a new instance. + /// + /// + protected ReflectionSymbolBuilder(ReflectionSymbolContext context) + { + _context = context ?? throw new ArgumentNullException(nameof(context)); + } + + /// + /// Gets the associated . + /// + public ReflectionSymbolContext Context => _context; + + /// + public ISymbol Symbol => GetSymbol(); + + /// + /// Implement to get the symbol. + /// + /// + protected abstract ISymbol GetSymbol(); + + } + + /// + /// Reflection-specific implementation of . + /// + abstract class ReflectionSymbolBuilder : ReflectionSymbolBuilder, ISymbolBuilder + where TSymbol : ISymbol + { + + /// + /// Initializes a new instance. + /// + /// + protected ReflectionSymbolBuilder(ReflectionSymbolContext context) : + base(context) + { + + } + + /// + public abstract new TSymbol Symbol { get; } + + /// + protected sealed override ISymbol GetSymbol() => Symbol; + + } + + /// + /// Base implementation for reflection symbol builders. + /// + abstract class ReflectionSymbolBuilder : ReflectionSymbolBuilder + where TSymbol : ISymbol + where TReflectionSymbol : ReflectionSymbol, TSymbol + { + + /// + /// Initializes a new instance. + /// + /// + protected ReflectionSymbolBuilder(ReflectionSymbolContext context) : + base(context) + { + + } + + /// + public sealed override TSymbol Symbol => ReflectionSymbol; + + /// + /// Gets the that is currently being built. Portions of this interface will be non-functional until the build is completed. + /// + internal abstract TReflectionSymbol ReflectionSymbol { get; } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs new file mode 100644 index 000000000..197211f65 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs @@ -0,0 +1,238 @@ +using System; +using System.Reflection; +using System.Reflection.Emit; +using System.Runtime.InteropServices; + +using IKVM.CoreLib.Symbols.Emit; + +namespace IKVM.CoreLib.Symbols.Reflection.Emit +{ + + class ReflectionTypeSymbolBuilder : ReflectionSymbolBuilder, ITypeSymbolBuilder + { + + readonly ReflectionModuleSymbolBuilder _containingModuleBuilder; + readonly TypeBuilder _builder; + ReflectionTypeSymbol? _symbol; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + public ReflectionTypeSymbolBuilder(ReflectionSymbolContext context, ReflectionModuleSymbolBuilder containingModuleBuilder, TypeBuilder builder) : + base(context) + { + _containingModuleBuilder = containingModuleBuilder ?? throw new ArgumentNullException(nameof(containingModuleBuilder)); + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + } + + /// + /// Gets the containing . + /// + internal ReflectionModuleSymbolBuilder ContainingModuleBuilder => _containingModuleBuilder; + + /// + /// Gets the underlying . + /// + internal TypeBuilder ReflectionBuilder => _builder; + + /// + internal override ReflectionTypeSymbol ReflectionSymbol => _symbol ??= Context.GetOrCreateTypeSymbol(_builder); + + /// + public void SetParent(ITypeSymbol? parent) + { + _builder.SetParent(parent?.Unpack()); + } + + /// + public IGenericTypeParameterSymbolBuilder[] DefineGenericParameters(params string[] names) + { + throw new NotImplementedException(); + } + + /// + public void AddInterfaceImplementation(ITypeSymbol interfaceType) + { + _builder.AddInterfaceImplementation(interfaceType.Unpack()); + } + + /// + public IConstructorSymbolBuilder DefineConstructor(MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol[]? parameterTypes) + { + return new ReflectionConstructorSymbolBuilder(Context, this, _builder.DefineConstructor(attributes, callingConvention, parameterTypes?.Unpack())); + } + + /// + public IConstructorSymbolBuilder DefineConstructor(MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? requiredCustomModifiers, ITypeSymbol[][]? optionalCustomModifiers) + { + return new ReflectionConstructorSymbolBuilder(Context, this, _builder.DefineConstructor(attributes, callingConvention, parameterTypes?.Unpack(), requiredCustomModifiers?.Unpack(), optionalCustomModifiers?.Unpack())); + } + + /// + public IConstructorSymbolBuilder DefineDefaultConstructor(MethodAttributes attributes) + { + return new ReflectionConstructorSymbolBuilder(Context, this, _builder.DefineDefaultConstructor(attributes)); + } + + /// + public IEventSymbolBuilder DefineEvent(string name, EventAttributes attributes, ITypeSymbol eventtype) + { + return new ReflectionEventSymbolBuilder(Context, this, _builder.DefineEvent(name, attributes, eventtype.Unpack())); + } + + /// + public IFieldSymbolBuilder DefineField(string fieldName, ITypeSymbol type, FieldAttributes attributes) + { + return new ReflectionFieldSymbolBuilder(Context, this, _builder.DefineField(fieldName, type.Unpack(), attributes)); + } + + /// + public IFieldSymbolBuilder DefineField(string fieldName, ITypeSymbol type, ITypeSymbol[]? requiredCustomModifiers, ITypeSymbol[]? optionalCustomModifiers, FieldAttributes attributes) + { + return new ReflectionFieldSymbolBuilder(Context, this, _builder.DefineField(fieldName, type.Unpack(), requiredCustomModifiers?.Unpack(), optionalCustomModifiers?.Unpack(), attributes)); + } + + /// + public IMethodSymbolBuilder DefineMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers) + { + return new ReflectionMethodSymbolBuilder(Context, this, _builder.DefineMethod(name, attributes, callingConvention, returnType?.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack())); + } + + /// + public IMethodSymbolBuilder DefineMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes) + { + return new ReflectionMethodSymbolBuilder(Context, this, _builder.DefineMethod(name, attributes, callingConvention, returnType?.Unpack(), parameterTypes?.Unpack())); + } + + /// + public IMethodSymbolBuilder DefineMethod(string name, MethodAttributes attributes, CallingConventions callingConvention) + { + return new ReflectionMethodSymbolBuilder(Context, this, _builder.DefineMethod(name, attributes, callingConvention)); + } + + /// + public IMethodSymbolBuilder DefineMethod(string name, MethodAttributes attributes) + { + return new ReflectionMethodSymbolBuilder(Context, this, _builder.DefineMethod(name, attributes)); + } + + /// + public IMethodSymbolBuilder DefineMethod(string name, MethodAttributes attributes, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes) + { + return new ReflectionMethodSymbolBuilder(Context, this, _builder.DefineMethod(name, attributes, returnType?.Unpack(), parameterTypes?.Unpack())); + } + + /// + public ITypeSymbolBuilder DefineNestedType(string name, TypeAttributes attr, ITypeSymbol? parent, ITypeSymbol[]? interfaces) + { + return new ReflectionTypeSymbolBuilder(Context, ContainingModuleBuilder, _builder.DefineNestedType(name, attr, parent?.Unpack(), interfaces?.Unpack())); + } + + /// + public ITypeSymbolBuilder DefineNestedType(string name, TypeAttributes attr, ITypeSymbol? parent, PackingSize packSize, int typeSize) + { + return new ReflectionTypeSymbolBuilder(Context, ContainingModuleBuilder, _builder.DefineNestedType(name, attr, parent?.Unpack(), packSize, typeSize)); + } + + /// + public ITypeSymbolBuilder DefineNestedType(string name, TypeAttributes attr, ITypeSymbol? parent, PackingSize packSize) + { + return new ReflectionTypeSymbolBuilder(Context, ContainingModuleBuilder, _builder.DefineNestedType(name, attr, parent?.Unpack(), packSize)); + } + + /// + public ITypeSymbolBuilder DefineNestedType(string name) + { + return new ReflectionTypeSymbolBuilder(Context, ContainingModuleBuilder, _builder.DefineNestedType(name)); + } + + /// + public ITypeSymbolBuilder DefineNestedType(string name, TypeAttributes attr, ITypeSymbol? parent) + { + return new ReflectionTypeSymbolBuilder(Context, ContainingModuleBuilder, _builder.DefineNestedType(name, attr, parent?.Unpack())); + } + + /// + public ITypeSymbolBuilder DefineNestedType(string name, TypeAttributes attr) + { + return new ReflectionTypeSymbolBuilder(Context, ContainingModuleBuilder, _builder.DefineNestedType(name, attr)); + } + + /// + public ITypeSymbolBuilder DefineNestedType(string name, TypeAttributes attr, ITypeSymbol? parent, int typeSize) + { + return new ReflectionTypeSymbolBuilder(Context, ContainingModuleBuilder, _builder.DefineNestedType(name, attr, parent?.Unpack(), typeSize)); + } + + /// + public IMethodSymbolBuilder DefinePInvokeMethod(string name, string dllName, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet) + { + return new ReflectionMethodSymbolBuilder(Context, ContainingModuleBuilder, _builder.DefinePInvokeMethod(name, dllName, attributes, callingConvention, returnType?.Unpack(), parameterTypes?.Unpack(), nativeCallConv, nativeCharSet)); + } + + /// + public IMethodSymbolBuilder DefinePInvokeMethod(string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet) + { + return new ReflectionMethodSymbolBuilder(Context, ContainingModuleBuilder, _builder.DefinePInvokeMethod(name, dllName, entryName, attributes, callingConvention, returnType?.Unpack(), parameterTypes?.Unpack(), nativeCallConv, nativeCharSet)); + } + + /// + public IMethodSymbolBuilder DefinePInvokeMethod(string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers, CallingConvention nativeCallConv, CharSet nativeCharSet) + { + return new ReflectionMethodSymbolBuilder(Context, ContainingModuleBuilder, _builder.DefinePInvokeMethod(name, dllName, entryName, attributes, callingConvention, returnType?.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack(), nativeCallConv, nativeCharSet)); + } + + /// + public IPropertySymbolBuilder DefineProperty(string name, PropertyAttributes attributes, ITypeSymbol returnType, ITypeSymbol[]? parameterTypes) + { + return new ReflectionPropertySymbolBuilder(Context, this, _builder.DefineProperty(name, attributes, returnType.Unpack(), parameterTypes?.Unpack())); + } + + /// + public IPropertySymbolBuilder DefineProperty(string name, PropertyAttributes attributes, CallingConventions callingConvention, ITypeSymbol returnType, ITypeSymbol[]? parameterTypes) + { + return new ReflectionPropertySymbolBuilder(Context, this, _builder.DefineProperty(name, attributes, callingConvention, returnType.Unpack(), parameterTypes?.Unpack())); + } + + /// + public IPropertySymbolBuilder DefineProperty(string name, PropertyAttributes attributes, ITypeSymbol returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers) + { + return new ReflectionPropertySymbolBuilder(Context, this, _builder.DefineProperty(name, attributes, returnType.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack())); + } + + /// + public IPropertySymbolBuilder DefineProperty(string name, PropertyAttributes attributes, CallingConventions callingConvention, ITypeSymbol returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers) + { + return new ReflectionPropertySymbolBuilder(Context, this, _builder.DefineProperty(name, attributes, callingConvention, returnType.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack())); + } + + /// + public IConstructorSymbolBuilder DefineTypeInitializer() + { + return new ReflectionConstructorSymbolBuilder(Context, this, _builder.DefineTypeInitializer()); + } + /// + public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) + { + _builder.SetCustomAttribute(con.Unpack(), binaryAttribute); + } + + /// + public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) + { + _builder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).ReflectionBuilder); + } + + /// + public void Finish() + { + var sym = ReflectionSymbol; + sym.FinishType(_builder.CreateType()); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs index bd5721750..8f5120253 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs @@ -5,6 +5,8 @@ using System.Reflection; using System.Runtime.CompilerServices; +using IKVM.CoreLib.Symbols.Reflection.Emit; + namespace IKVM.CoreLib.Symbols.Reflection { @@ -35,10 +37,26 @@ public ReflectionAssemblySymbol(ReflectionSymbolContext context, Assembly assemb /// internal ReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) { + if (module is null) + throw new ArgumentNullException(nameof(module)); + Debug.Assert(module.Assembly == _assembly); return _modules.GetValue(module, _ => new ReflectionModuleSymbol(Context, _)); } + /// + /// Gets or creates the cached for the module. + /// + /// + /// + internal ReflectionModuleSymbol GetOrCreateModuleSymbol(ReflectionModuleSymbolBuilder module) + { + if (module is null) + throw new ArgumentNullException(nameof(module)); + + throw new NotImplementedException(); + } + /// public IEnumerable DefinedTypes => ResolveTypeSymbols(_assembly.DefinedTypes); @@ -127,19 +145,19 @@ public ITypeSymbol[] GetTypes() } /// - public CustomAttributeSymbol[] GetCustomAttributes(bool inherit = false) + public CustomAttribute[] GetCustomAttributes(bool inherit = false) { return ResolveCustomAttributes(_assembly.GetCustomAttributesData()); } /// - public CustomAttributeSymbol[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) + public CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) { return ResolveCustomAttributes(_assembly.GetCustomAttributesData().Where(i => i.AttributeType == ((ReflectionTypeSymbol)attributeType).ReflectionObject)); } /// - public CustomAttributeSymbol? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) + public CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) { return GetCustomAttributes(attributeType, inherit).FirstOrDefault(); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionEventSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionEventSymbol.cs index 7c4a37a7b..080785635 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionEventSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionEventSymbol.cs @@ -16,7 +16,7 @@ class ReflectionEventSymbol : ReflectionMemberSymbol, IEventSymbol /// /// public ReflectionEventSymbol(ReflectionSymbolContext context, ReflectionTypeSymbol type, EventInfo @event) : - base(context, type.ContainingModule, type, @event) + base(context, type, @event) { _event = @event ?? throw new ArgumentNullException(nameof(@event)); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionFieldSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionFieldSymbol.cs index 8ba9a0eb6..61bfb5476 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionFieldSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionFieldSymbol.cs @@ -13,10 +13,22 @@ class ReflectionFieldSymbol : ReflectionMemberSymbol, IFieldSymbol /// Initializes a new instance. /// /// - /// + /// /// - public ReflectionFieldSymbol(ReflectionSymbolContext context, ReflectionTypeSymbol type, FieldInfo field) : - base(context, type.ContainingModule, type, field) + public ReflectionFieldSymbol(ReflectionSymbolContext context, ReflectionModuleSymbol containingModule, FieldInfo field) : + base(context, containingModule, field) + { + _field = field ?? throw new ArgumentNullException(nameof(field)); + } + + /// + /// Initializes a new instance. + /// + /// + /// + /// + public ReflectionFieldSymbol(ReflectionSymbolContext context, ReflectionTypeSymbol containingType, FieldInfo field) : + base(context, containingType, field) { _field = field ?? throw new ArgumentNullException(nameof(field)); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs index 850276ccf..f4bbd6c78 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs @@ -44,24 +44,34 @@ static T[] Concat(List? list) readonly ReflectionTypeSymbol? _containingType; readonly MemberInfo _member; - CustomAttributeSymbol[]? _customAttributes; - CustomAttributeSymbol[]? _inheritedCustomAttributes; + CustomAttribute[]? _customAttributes; + CustomAttribute[]? _inheritedCustomAttributes; /// /// Initializes a new instance. /// /// /// - /// /// - public ReflectionMemberSymbol(ReflectionSymbolContext context, ReflectionModuleSymbol containingModule, ReflectionTypeSymbol? containingType, MemberInfo member) : + public ReflectionMemberSymbol(ReflectionSymbolContext context, ReflectionModuleSymbol containingModule, MemberInfo member) : base(context) { _containingModule = containingModule ?? throw new ArgumentNullException(nameof(containingModule)); - _containingType = containingType; _member = member ?? throw new ArgumentNullException(nameof(member)); } + /// + /// Initializes a new instance. + /// + /// + /// + /// + public ReflectionMemberSymbol(ReflectionSymbolContext context, ReflectionTypeSymbol containingType, MemberInfo member) : + this(context, containingType.ContainingModule, member) + { + _containingType = containingType ?? throw new ArgumentNullException(nameof(containingType)); + } + /// /// Resolves the symbol for the specified type. /// @@ -84,10 +94,8 @@ protected internal override ReflectionTypeSymbol ResolveTypeSymbol(Type type) /// protected internal override ReflectionConstructorSymbol ResolveConstructorSymbol(ConstructorInfo ctor) { - if (_containingType != null && ctor.DeclaringType == _containingType.ReflectionObject) - return _containingType.GetOrCreateConstructorSymbol(ctor); - else if (ctor.DeclaringType != null && ctor.Module == _member.Module) - return _containingModule.GetOrCreateTypeSymbol(ctor.DeclaringType).GetOrCreateConstructorSymbol(ctor); + if (ctor.Module == _member.Module) + return _containingModule.GetOrCreateConstructorSymbol(ctor); else return base.ResolveConstructorSymbol(ctor); } @@ -99,10 +107,8 @@ protected internal override ReflectionConstructorSymbol ResolveConstructorSymbol /// protected internal override ReflectionMethodSymbol ResolveMethodSymbol(MethodInfo method) { - if (_containingType != null && method.DeclaringType == _containingType.ReflectionObject) - return _containingType.GetOrCreateMethodSymbol(method); - else if (method.DeclaringType != null && method.Module == _member.Module) - return _containingModule.GetOrCreateTypeSymbol(method.DeclaringType).GetOrCreateMethodSymbol(method); + if (method.Module == _member.Module) + return _containingModule.GetOrCreateMethodSymbol(method); else return base.ResolveMethodSymbol(method); } @@ -114,10 +120,8 @@ protected internal override ReflectionMethodSymbol ResolveMethodSymbol(MethodInf /// protected internal override ReflectionFieldSymbol ResolveFieldSymbol(FieldInfo field) { - if (_containingType != null && field.DeclaringType == _containingType.ReflectionObject) - return _containingType.GetOrCreateFieldSymbol(field); - else if (field.DeclaringType != null && field.Module == _member.Module) - return _containingModule.GetOrCreateTypeSymbol(field.DeclaringType).GetOrCreateFieldSymbol(field); + if (field.Module == _member.Module) + return _containingModule.GetOrCreateFieldSymbol(field); else return base.ResolveFieldSymbol(field); } @@ -130,11 +134,8 @@ protected internal override ReflectionFieldSymbol ResolveFieldSymbol(FieldInfo f /// protected internal override ReflectionPropertySymbol ResolvePropertySymbol(PropertyInfo property) { - - if (_containingType != null && property.DeclaringType == _containingType.ReflectionObject) - return _containingType.GetOrCreatePropertySymbol(property); - else if (property.DeclaringType != null && property.Module == _member.Module) - return _containingModule.GetOrCreateTypeSymbol(property.DeclaringType).GetOrCreatePropertySymbol(property); + if (property.Module == _member.Module) + return _containingModule.GetOrCreatePropertySymbol(property); else return base.ResolvePropertySymbol(property); } @@ -146,10 +147,8 @@ protected internal override ReflectionPropertySymbol ResolvePropertySymbol(Prope /// protected internal override ReflectionEventSymbol ResolveEventSymbol(EventInfo @event) { - if (_containingType != null && @event.DeclaringType == _containingType.ReflectionObject) - return _containingType.GetOrCreateEventSymbol(@event); - else if (@event.DeclaringType != null && @event.Module == _member.Module) - return _containingModule.GetOrCreateTypeSymbol(@event.DeclaringType).GetOrCreateEventSymbol(@event); + if (@event.Module == _member.Module) + return _containingModule.GetOrCreateEventSymbol(@event); else return base.ResolveEventSymbol(@event); } @@ -185,7 +184,7 @@ protected internal override ReflectionEventSymbol ResolveEventSymbol(EventInfo @ public virtual string Name => _member.Name; /// - public virtual CustomAttributeSymbol[] GetCustomAttributes(bool inherit = false) + public virtual CustomAttribute[] GetCustomAttributes(bool inherit = false) { if (inherit) { @@ -194,7 +193,7 @@ public virtual CustomAttributeSymbol[] GetCustomAttributes(bool inherit = false) return _inheritedCustomAttributes; var self = _member; - var list = default(List?); + var list = default(List?); for (; ; ) { // get attribute for current member and append to list @@ -236,13 +235,13 @@ public virtual CustomAttributeSymbol[] GetCustomAttributes(bool inherit = false) } /// - public virtual CustomAttributeSymbol[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) + public virtual CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) { return GetCustomAttributes(inherit).Where(i => i.AttributeType == attributeType).ToArray(); } /// - public virtual CustomAttributeSymbol? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) + public virtual CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) { return GetCustomAttributes(attributeType, inherit).FirstOrDefault(); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodBaseSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodBaseSymbol.cs index 5f1aaa9aa..8bd357f1d 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodBaseSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodBaseSymbol.cs @@ -1,8 +1,5 @@ using System; -using System.Diagnostics; -using System.Linq; using System.Reflection; -using System.Threading; namespace IKVM.CoreLib.Symbols.Reflection { @@ -12,61 +9,29 @@ abstract class ReflectionMethodBaseSymbol : ReflectionMemberSymbol, IMethodBaseS readonly MethodBase _method; - ParameterInfo[]? _parametersSource; - ReflectionParameterSymbol?[]? _parameters; - ReflectionParameterSymbol? _returnParameter; - /// /// Initializes a new instance. /// /// /// - /// /// - public ReflectionMethodBaseSymbol(ReflectionSymbolContext context, ReflectionModuleSymbol module, ReflectionTypeSymbol? type, MethodBase method) : - base(context, module, type, method) + public ReflectionMethodBaseSymbol(ReflectionSymbolContext context, ReflectionModuleSymbol module, MethodBase method) : + base(context, module, method) { _method = method ?? throw new ArgumentNullException(nameof(method)); } /// - /// Gets or creates the cached for the type by method. + /// Initializes a new instance. /// - /// - /// - internal ReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) + /// + /// + /// + /// + public ReflectionMethodBaseSymbol(ReflectionSymbolContext context, ReflectionTypeSymbol type, MethodBase method) : + this(context, type.ContainingModule, method) { - if (parameter is null) - throw new ArgumentNullException(nameof(parameter)); - - Debug.Assert(parameter.Member == _method); - - if (_parametersSource == null) - Interlocked.CompareExchange(ref _parametersSource, _method.GetParameters().OrderBy(i => i.Position).ToArray(), null); - if (_parameters == null) - Interlocked.CompareExchange(ref _parameters, new ReflectionParameterSymbol?[_parametersSource.Length], null); - - // index of current record - var idx = parameter.Position; - Debug.Assert(idx >= -1); - Debug.Assert(idx < _parametersSource.Length); - - // check that our list is long enough to contain the entire table - if (idx >= 0 && _parameters.Length < idx) - throw new IndexOutOfRangeException(); - - // if not yet created, create, allow multiple instances, but only one is eventually inserted - ref var rec = ref _returnParameter; - if (idx >= 0) - rec = ref _parameters[idx]; - if (rec == null) - Interlocked.CompareExchange(ref rec, new ReflectionParameterSymbol(Context, this, parameter), null); - - // this should never happen - if (rec is not ReflectionParameterSymbol sym) - throw new InvalidOperationException(); - return sym; } /// @@ -151,4 +116,4 @@ public IParameterSymbol[] GetParameters() } -} \ No newline at end of file +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs index fdbb45b38..56030a0d7 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs @@ -24,12 +24,24 @@ class ReflectionMethodSymbol : ReflectionMethodBaseSymbol, IMethodSymbol /// /// /// - public ReflectionMethodSymbol(ReflectionSymbolContext context, ReflectionModuleSymbol module, ReflectionTypeSymbol? type, MethodInfo method) : - base(context, module, type, method) + public ReflectionMethodSymbol(ReflectionSymbolContext context, ReflectionModuleSymbol module, MethodInfo method) : + base(context, module, method) { _method = method ?? throw new ArgumentNullException(nameof(method)); } + /// + /// Initializes a new instance. + /// + /// + /// + /// + public ReflectionMethodSymbol(ReflectionSymbolContext context, ReflectionTypeSymbol type, MethodInfo method) : + this(context, type.ContainingModule, method) + { + + } + /// /// Gets or creates the cached for the generic parameter type. /// @@ -98,7 +110,12 @@ internal ReflectionMethodSymbol GetOrCreateGenericTypeSymbol(Type[] genericMetho return i.Symbol; // generate new symbol - var sym = new ReflectionMethodSymbol(Context, ContainingModule, ContainingType, _method.MakeGenericMethod(genericMethodArguments)); + ReflectionMethodSymbol sym; + if (ContainingType != null) + sym = new ReflectionMethodSymbol(Context, ContainingType, _method.MakeGenericMethod(genericMethodArguments)); + else + sym = new ReflectionMethodSymbol(Context, ContainingModule, _method.MakeGenericMethod(genericMethodArguments)); + _genericTypes.Add((genericMethodArguments, sym)); return sym; } @@ -116,7 +133,7 @@ internal ReflectionMethodSymbol GetOrCreateGenericTypeSymbol(Type[] genericMetho public ITypeSymbol ReturnType => ResolveTypeSymbol(_method.ReturnType); /// - public ICustomAttributeSymbolProvider ReturnTypeCustomAttributes => throw new NotImplementedException(); + public ICustomAttributeProvider ReturnTypeCustomAttributes => throw new NotImplementedException(); /// public IMethodSymbol GetBaseDefinition() @@ -133,7 +150,7 @@ public IMethodSymbol GetGenericMethodDefinition() /// public IMethodSymbol MakeGenericMethod(params ITypeSymbol[] typeArguments) { - return ResolveMethodSymbol(_method.MakeGenericMethod(UnpackTypeSymbols(typeArguments))); + return ResolveMethodSymbol(_method.MakeGenericMethod(typeArguments.Unpack())); } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs index 0e8bc370f..2f7a1cff7 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs @@ -2,10 +2,11 @@ using System.Diagnostics; using System.Linq; using System.Reflection; -using System.Reflection.Metadata.Ecma335; -using System.Runtime.InteropServices; using System.Threading; +using IKVM.CoreLib.Collections; +using IKVM.CoreLib.Threading; + namespace IKVM.CoreLib.Symbols.Reflection { @@ -23,17 +24,41 @@ class ReflectionModuleSymbol : ReflectionSymbol, IModuleSymbol static bool IsTypeDefinition(Type type) { #if NET - return type.IsTypeDefinition; + return type.IsTypeDefinition; #else return type.HasElementType == false && type.IsConstructedGenericType == false && type.IsGenericParameter == false; #endif } + const int MAX_CAPACITY = 65536 * 2; + + const BindingFlags DefaultBindingFlags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance; + readonly Module _module; - Type[]? _typesSource; - int _typesBaseRow; - ReflectionTypeSymbol?[]? _types; + IndexRangeDictionary _typeTable = new(maxCapacity: MAX_CAPACITY); + IndexRangeDictionary _typeSymbols = new(maxCapacity: MAX_CAPACITY); + ReaderWriterLockSlim? _typeLock; + + IndexRangeDictionary _methodTable = new(maxCapacity: MAX_CAPACITY); + IndexRangeDictionary _methodSymbols = new(maxCapacity: MAX_CAPACITY); + ReaderWriterLockSlim? _methodLock; + + IndexRangeDictionary _fieldTable = new(maxCapacity: MAX_CAPACITY); + IndexRangeDictionary _fieldSymbols = new(maxCapacity: MAX_CAPACITY); + ReaderWriterLockSlim? _fieldLock; + + IndexRangeDictionary _propertyTable = new(maxCapacity: MAX_CAPACITY); + IndexRangeDictionary _propertySymbols = new(maxCapacity: MAX_CAPACITY); + ReaderWriterLockSlim? _propertyLock; + + IndexRangeDictionary _eventTable = new(maxCapacity: MAX_CAPACITY); + IndexRangeDictionary _eventSymbols = new(maxCapacity: MAX_CAPACITY); + ReaderWriterLockSlim? _eventLock; + + IndexRangeDictionary _parameterTable = new(); + IndexRangeDictionary _parameterSymbols = new(); + ReaderWriterLockSlim? _parameterLock; /// /// Initializes a new instance. @@ -50,7 +75,7 @@ public ReflectionModuleSymbol(ReflectionSymbolContext context, Module module) : /// /// Gets the wrapped . /// - internal Module ReflectionModule => _module; + internal Module ReflectionObject => _module; /// /// Gets or creates the cached for the module by type. @@ -69,46 +94,33 @@ internal ReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) if (IsTypeDefinition(type) == false) return GetOrCreateTypeSymbolForSpecification(type); - // look up handle and row - var hnd = MetadataTokens.TypeDefinitionHandle(type.MetadataToken); - var row = MetadataTokens.GetRowNumber(hnd); + // create lock on demand + if (_typeLock == null) + lock (this) + _typeLock ??= new ReaderWriterLockSlim(); - // initialize source table - if (_typesSource == null) + using (_typeLock.CreateUpgradeableReadLock()) { - Interlocked.CompareExchange(ref _typesSource, _module.GetTypes().OrderBy(i => i.MetadataToken).ToArray(), null); - _typesBaseRow = _typesSource.Length != 0 ? MetadataTokens.GetRowNumber(MetadataTokens.MethodDefinitionHandle(_typesSource[0].MetadataToken)) : 0; + var row = type.GetMetadataTokenRowNumberSafe(); + if (_typeTable[row] != type) + using (_typeLock.CreateWriteLock()) + _typeTable[row] = type; + + if (_typeSymbols[row] == null) + using (_typeLock.CreateWriteLock()) + return _typeSymbols[row] ??= new ReflectionTypeSymbol(Context, this, type); + else + return _typeSymbols[row] ?? throw new InvalidOperationException(); } - - // initialize cache table - if (_types == null) - Interlocked.CompareExchange(ref _types, new ReflectionTypeSymbol?[_typesSource.Length], null); - - // index of current record is specified row - base - var idx = row - _typesBaseRow - 1; - Debug.Assert(idx >= 0); - Debug.Assert(idx < _typesSource.Length); - - // check that our type list is long enough to contain the entire table - if (_types.Length < idx) - throw new IndexOutOfRangeException(); - - // if not yet created, create, allow multiple instances, but only one is eventually inserted - if (_types[idx] == null) - Interlocked.CompareExchange(ref _types[idx], new ReflectionTypeSymbol(Context, this, type), null); - - // this should never happen - if (_types[idx] is not ReflectionTypeSymbol sym) - throw new InvalidOperationException(); - - return sym; } /// - /// For a given + /// Gets or creates a for the specification type: array, pointer, etc. /// /// - /// + /// + /// + /// ReflectionTypeSymbol GetOrCreateTypeSymbolForSpecification(Type type) { if (type is null) @@ -118,7 +130,7 @@ ReflectionTypeSymbol GetOrCreateTypeSymbolForSpecification(Type type) if (type.GetElementType() is { } elementType) { - var elementTypeSymbol = GetOrCreateTypeSymbol(elementType); + var elementTypeSymbol = ResolveTypeSymbol(elementType); // handles both SZ arrays and normal arrays if (type.IsArray) @@ -135,28 +147,221 @@ ReflectionTypeSymbol GetOrCreateTypeSymbolForSpecification(Type type) if (type.IsGenericType) { - var definitionType = type.GetGenericTypeDefinition(); - var definitionTypeSymbol = GetOrCreateTypeSymbol(definitionType); + var definitionTypeSymbol = ResolveTypeSymbol(type.GetGenericTypeDefinition()); return definitionTypeSymbol.GetOrCreateGenericTypeSymbol(type.GetGenericArguments()); } // generic type parameter if (type.IsGenericParameter && type.DeclaringMethod is null && type.DeclaringType is not null) { - var declaringType = GetOrCreateTypeSymbol(type.DeclaringType); + var declaringType = ResolveTypeSymbol(type.DeclaringType); return declaringType.GetOrCreateGenericParameterSymbol(type); } // generic method parameter if (type.IsGenericParameter && type.DeclaringMethod is not null && type.DeclaringMethod.DeclaringType is not null) { - var declaringMethod = GetOrCreateTypeSymbol(type.DeclaringMethod.DeclaringType); + var declaringMethod = ResolveTypeSymbol(type.DeclaringMethod.DeclaringType); return declaringMethod.GetOrCreateGenericParameterSymbol(type); } throw new InvalidOperationException(); } + /// + /// Gets or creates the cached fqor the type by method. + /// + /// + /// + internal ReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method) + { + if (method is null) + throw new ArgumentNullException(nameof(method)); + + Debug.Assert(method.Module == _module); + + // create lock on demand + if (_methodLock == null) + lock (this) + _methodLock ??= new ReaderWriterLockSlim(); + + using (_methodLock.CreateUpgradeableReadLock()) + { + var row = method.GetMetadataTokenRowNumberSafe(); + if (_methodTable[row] != method) + using (_methodLock.CreateWriteLock()) + _methodTable[row] = method; + + if (_methodSymbols[row] == null) + using (_methodLock.CreateWriteLock()) + if (method is ConstructorInfo c) + return _methodSymbols[row] ??= new ReflectionConstructorSymbol(Context, ResolveTypeSymbol(c.DeclaringType ?? throw new InvalidOperationException()), c); + else if (method is MethodInfo m) + if (method.DeclaringType is { } dt) + return _methodSymbols[row] ??= new ReflectionMethodSymbol(Context, ResolveTypeSymbol(dt), m); + else + return _methodSymbols[row] ??= new ReflectionMethodSymbol(Context, this, m); + else + throw new InvalidOperationException(); + else + return _methodSymbols[row] ?? throw new InvalidOperationException(); + } + } + + /// + /// Gets or creates the cached for the type by ctor. + /// + /// + /// + internal ReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) + { + return (ReflectionConstructorSymbol)GetOrCreateMethodBaseSymbol(ctor); + } + + /// + /// Gets or creates the cached for the type by method. + /// + /// + /// + internal ReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) + { + return (ReflectionMethodSymbol)GetOrCreateMethodBaseSymbol(method); + } + + /// + /// Gets or creates the cached for the type by field. + /// + /// + /// + /// + internal ReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) + { + if (field is null) + throw new ArgumentNullException(nameof(field)); + + Debug.Assert(field.Module == _module); + + // create lock on demand + if (_fieldLock == null) + lock (this) + _fieldLock ??= new ReaderWriterLockSlim(); + + using (_fieldLock.CreateUpgradeableReadLock()) + { + var row = field.GetMetadataTokenRowNumberSafe(); + if (_fieldTable[row] != field) + using (_fieldLock.CreateWriteLock()) + _fieldTable[row] = field; + + if (_fieldSymbols[row] == null) + using (_fieldLock.CreateWriteLock()) + if (field.DeclaringType is { } dt) + return _fieldSymbols[row] ??= new ReflectionFieldSymbol(Context, ResolveTypeSymbol(dt), field); + else + return _fieldSymbols[row] ??= new ReflectionFieldSymbol(Context, this, field); + else + return _fieldSymbols[row] ?? throw new InvalidOperationException(); + } + } + + /// + /// Gets or creates the cached for the type by property. + /// + /// + /// + /// + internal ReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) + { + if (property is null) + throw new ArgumentNullException(nameof(property)); + + Debug.Assert(property.Module == _module); + + // create lock on demand + if (_propertyLock == null) + lock (this) + _propertyLock ??= new ReaderWriterLockSlim(); + + using (_propertyLock.CreateUpgradeableReadLock()) + { + var row = property.GetMetadataTokenRowNumberSafe(); + if (_propertyTable[row] != property) + using (_propertyLock.CreateWriteLock()) + _propertyTable[row] = property; + + if (_propertySymbols[row] == null) + using (_propertyLock.CreateWriteLock()) + return _propertySymbols[row] ??= new ReflectionPropertySymbol(Context, ResolveTypeSymbol(property.DeclaringType!), property); + else + return _propertySymbols[row] ?? throw new InvalidOperationException(); + } + } + + /// + /// Gets or creates the cached for the type by event. + /// + /// + /// + /// + internal ReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) + { + if (@event is null) + throw new ArgumentNullException(nameof(@event)); + + Debug.Assert(@event.Module == _module); + + // create lock on demand + if (_eventLock == null) + lock (this) + _eventLock ??= new ReaderWriterLockSlim(); + + using (_eventLock.CreateUpgradeableReadLock()) + { + var row = @event.GetMetadataTokenRowNumberSafe(); + if (_eventTable[row] is not EventInfo i || i != @event) + using (_eventLock.CreateWriteLock()) + _eventTable[row] = @event; + + if (_eventSymbols[row] == null) + using (_eventLock.CreateWriteLock()) + return _eventSymbols[row] ??= new ReflectionEventSymbol(Context, ResolveTypeSymbol(@event.DeclaringType!), @event); + else + return _eventSymbols[row] ?? throw new InvalidOperationException(); + } + } + + /// + /// Gets or creates the cached for the type by method. + /// + /// + /// + internal ReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) + { + if (parameter is null) + throw new ArgumentNullException(nameof(parameter)); + + Debug.Assert(parameter.Member.Module == _module); + + // create lock on demand + if (_parameterLock == null) + lock (this) + _parameterLock ??= new ReaderWriterLockSlim(); + + using (_parameterLock.CreateUpgradeableReadLock()) + { + var position = parameter.Position; + if (_parameterTable[position] != parameter) + using (_parameterLock.CreateWriteLock()) + _parameterTable[position] = parameter; + + if (_parameterSymbols[position] == null) + using (_parameterLock.CreateWriteLock()) + return _parameterSymbols[position] ??= new ReflectionParameterSymbol(Context, ResolveMethodBaseSymbol((MethodBase)parameter.Member), parameter); + else + return _parameterSymbols[position] ?? throw new InvalidOperationException(); + } + } + /// public IAssemblySymbol Assembly => Context.GetOrCreateAssemblySymbol(_module.Assembly); @@ -208,13 +413,13 @@ public IFieldSymbol[] GetFields() /// public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) { - return _module.GetMethod(name, UnpackTypeSymbols(types)) is { } m ? ResolveMethodSymbol(m) : null; + return _module.GetMethod(name, types.Unpack()) is { } m ? ResolveMethodSymbol(m) : null; } /// public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers) { - return _module.GetMethod(name, bindingAttr, null, callConvention, UnpackTypeSymbols(types), modifiers) is { } m ? ResolveMethodSymbol(m) : null; + return _module.GetMethod(name, bindingAttr, null, callConvention, types.Unpack(), modifiers) is { } m ? ResolveMethodSymbol(m) : null; } /// @@ -268,9 +473,7 @@ public bool IsResource() /// public IFieldSymbol? ResolveField(int metadataToken, ITypeSymbol[]? genericTypeArguments, ITypeSymbol[]? genericMethodArguments) { - var _genericTypeArguments = genericTypeArguments != null ? UnpackTypeSymbols(genericTypeArguments) : null; - var _genericMethodArguments = genericMethodArguments != null ? UnpackTypeSymbols(genericMethodArguments) : null; - return _module.ResolveField(metadataToken, _genericTypeArguments, _genericMethodArguments) is { } f ? ResolveFieldSymbol(f) : null; + return _module.ResolveField(metadataToken, genericTypeArguments?.Unpack(), genericMethodArguments?.Unpack()) is { } f ? ResolveFieldSymbol(f) : null; } /// @@ -282,17 +485,13 @@ public bool IsResource() /// public IMemberSymbol? ResolveMember(int metadataToken, ITypeSymbol[]? genericTypeArguments, ITypeSymbol[]? genericMethodArguments) { - var _genericTypeArguments = genericTypeArguments != null ? UnpackTypeSymbols(genericTypeArguments) : null; - var _genericMethodArguments = genericMethodArguments != null ? UnpackTypeSymbols(genericMethodArguments) : null; - return _module.ResolveMember(metadataToken, _genericTypeArguments, _genericMethodArguments) is { } m ? ResolveMemberSymbol(m) : null; + return _module.ResolveMember(metadataToken, genericTypeArguments?.Unpack(), genericMethodArguments?.Unpack()) is { } m ? ResolveMemberSymbol(m) : null; } /// public IMethodBaseSymbol? ResolveMethod(int metadataToken, ITypeSymbol[]? genericTypeArguments, ITypeSymbol[]? genericMethodArguments) { - var _genericTypeArguments = genericTypeArguments != null ? UnpackTypeSymbols(genericTypeArguments) : null; - var _genericMethodArguments = genericMethodArguments != null ? UnpackTypeSymbols(genericMethodArguments) : null; - return _module.ResolveMethod(metadataToken, _genericTypeArguments, _genericMethodArguments) is { } m ? ResolveMethodBaseSymbol(m) : null; + return _module.ResolveMethod(metadataToken, genericTypeArguments?.Unpack(), genericMethodArguments?.Unpack()) is { } m ? ResolveMethodBaseSymbol(m) : null; } /// @@ -322,25 +521,23 @@ public ITypeSymbol ResolveType(int metadataToken) /// public ITypeSymbol ResolveType(int metadataToken, ITypeSymbol[]? genericTypeArguments, ITypeSymbol[]? genericMethodArguments) { - var _genericTypeArguments = genericTypeArguments != null ? UnpackTypeSymbols(genericTypeArguments) : null; - var _genericMethodArguments = genericMethodArguments != null ? UnpackTypeSymbols(genericMethodArguments) : null; - return ResolveTypeSymbol(_module.ResolveType(metadataToken, _genericTypeArguments, _genericMethodArguments)); + return ResolveTypeSymbol(_module.ResolveType(metadataToken, genericTypeArguments?.Unpack(), genericMethodArguments?.Unpack())); } /// - public CustomAttributeSymbol[] GetCustomAttributes(bool inherit = false) + public CustomAttribute[] GetCustomAttributes(bool inherit = false) { return ResolveCustomAttributes(_module.GetCustomAttributesData()); } /// - public CustomAttributeSymbol[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) + public CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) { return ResolveCustomAttributes(_module.GetCustomAttributesData().Where(i => i.AttributeType == ((ReflectionTypeSymbol)attributeType).ReflectionObject)); } /// - public CustomAttributeSymbol? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) + public CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) { return GetCustomAttributes(attributeType, inherit).FirstOrDefault(); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterSymbol.cs index 2ad73f260..d891bd548 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterSymbol.cs @@ -2,72 +2,113 @@ using System.Linq; using System.Reflection; +using IKVM.CoreLib.Symbols.Reflection.Emit; + namespace IKVM.CoreLib.Symbols.Reflection { class ReflectionParameterSymbol : ReflectionSymbol, IParameterSymbol { - readonly ParameterInfo _parameter; - readonly ReflectionMethodBaseSymbol _method; + readonly ReflectionMethodBaseSymbol _containingMethod; + ParameterInfo? _parameter; + ReflectionParameterSymbolBuilder? _builder; - CustomAttributeSymbol[]? _customAttributes; + CustomAttribute[]? _customAttributes; /// /// Initializes a new instance. /// /// - /// + /// /// - public ReflectionParameterSymbol(ReflectionSymbolContext context, ReflectionMethodBaseSymbol method, ParameterInfo parameter) : + public ReflectionParameterSymbol(ReflectionSymbolContext context, ReflectionMethodBaseSymbol containingMethod, ParameterInfo parameter) : base(context) { - _method = method ?? throw new ArgumentNullException(nameof(method)); + _containingMethod = containingMethod ?? throw new ArgumentNullException(nameof(containingMethod)); _parameter = parameter ?? throw new ArgumentNullException(nameof(parameter)); } - internal ReflectionMethodBaseSymbol ContainingMethod => _method; + /// + /// Initializes a new instance. + /// + /// + /// + /// + public ReflectionParameterSymbol(ReflectionSymbolContext context, ReflectionMethodBaseSymbol containingMethod, ReflectionParameterSymbolBuilder builder) : + base(context) + { + _containingMethod = containingMethod ?? throw new ArgumentNullException(nameof(containingMethod)); + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + } - public ParameterAttributes Attributes => _parameter.Attributes; + internal ReflectionMethodBaseSymbol ContainingMethod => _containingMethod; - public object? DefaultValue => _parameter.DefaultValue; + /// + public ParameterAttributes Attributes => _parameter is { } p ? p.Attributes : _builder is { } b ? (ParameterAttributes)b.ReflectionBuilder.Attributes : throw new InvalidOperationException(); - public bool HasDefaultValue => _parameter.HasDefaultValue; + /// + public object? DefaultValue => _parameter is { } p ? p.DefaultValue : _builder is { } b ? b.GetConstant() : throw new InvalidOperationException(); - public bool IsIn => _parameter.IsIn; + /// + public bool HasDefaultValue => (Attributes & ParameterAttributes.HasDefault) != 0; - public bool IsLcid => _parameter.IsLcid; + /// + public bool IsIn => (Attributes & ParameterAttributes.In) != 0; - public bool IsOptional => _parameter.IsOptional; + /// + public bool IsLcid => (Attributes & ParameterAttributes.Lcid) != 0; + + /// + public bool IsOptional => (Attributes & ParameterAttributes.Optional) != 0; - public bool IsOut => _parameter.IsOut; + /// + public bool IsOut => (Attributes & ParameterAttributes.Out) != 0; + + /// + public bool IsRetval => (Attributes & ParameterAttributes.Retval) != 0; + + /// + public IMemberSymbol Member => _parameter is { } p ? ResolveMemberSymbol(p.Member) : _containingMethod; + +#if NETFRAMEWORK + + /// + public int MetadataToken => _parameter is { } p ? p.MetadataToken : _builder is { } b ? b.ReflectionBuilder.GetToken().Token : throw new InvalidOperationException(); - public bool IsRetval => _parameter.IsRetval; +#else - public IMemberSymbol Member => ResolveMemberSymbol(_parameter.Member); + /// + public int MetadataToken => _parameter is { } p ? p.MetadataToken : _builder is { } b ? throw new NotSupportedException() : throw new InvalidOperationException(); - public int MetadataToken => _parameter.MetadataToken; +#endif - public string? Name => _parameter.Name; + /// + public string? Name => _parameter is { } p ? p.Name : _builder is { } b ? b.ReflectionBuilder.Name : throw new InvalidOperationException(); - public ITypeSymbol ParameterType => ResolveTypeSymbol(_parameter.ParameterType); + /// + public ITypeSymbol ParameterType => _parameter is { } p ? ResolveTypeSymbol(p.ParameterType) : _builder is { } b ? throw new NotSupportedException() : throw new InvalidOperationException(); - public int Position => _parameter.Position; + /// + public int Position => _parameter is { } p ? p.Position : _builder is { } b ? b.ReflectionBuilder.Position : throw new InvalidOperationException(); /// - public CustomAttributeSymbol[] GetCustomAttributes(bool inherit = false) + public CustomAttribute[] GetCustomAttributes(bool inherit = false) { - return _customAttributes ??= ResolveCustomAttributes(_parameter.GetCustomAttributesData()); + if (_parameter is not null) + return _customAttributes ??= ResolveCustomAttributes(_parameter.GetCustomAttributesData()); + + throw new NotSupportedException(); } /// - public virtual CustomAttributeSymbol[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) + public virtual CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) { return GetCustomAttributes(inherit).Where(i => i.AttributeType == attributeType).ToArray(); } /// - public virtual CustomAttributeSymbol? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) + public virtual CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) { return GetCustomAttributes(attributeType, inherit).FirstOrDefault(); } @@ -75,9 +116,41 @@ public virtual CustomAttributeSymbol[] GetCustomAttributes(ITypeSymbol attribute /// public virtual bool IsDefined(ITypeSymbol attributeType, bool inherit = false) { - return _parameter.IsDefined(((ReflectionTypeSymbol)attributeType).ReflectionObject, inherit); + if (_parameter is not null) + return _parameter.IsDefined(((ReflectionTypeSymbol)attributeType).ReflectionObject, inherit); + + throw new NotSupportedException(); + } + + /// + public ITypeSymbol[] GetOptionalCustomModifiers() + { + if (_parameter is not null) + return ResolveTypeSymbols(_parameter.GetOptionalCustomModifiers()); + + throw new NotSupportedException(); + } + + /// + public ITypeSymbol[] GetRequiredCustomModifiers() + { + if (_parameter is not null) + return ResolveTypeSymbols(_parameter.GetRequiredCustomModifiers()); + + throw new NotSupportedException(); + } + + /// + /// Finishes the symbol by replacing the builder. + /// + /// + /// + internal void Finish(ParameterInfo parameter) + { + _parameter = parameter ?? throw new ArgumentNullException(nameof(parameter)); + _builder = null; } } -} \ No newline at end of file +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbol.cs index f0aa2a89a..8ee7be109 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbol.cs @@ -29,7 +29,10 @@ public ReflectionSymbol(ReflectionSymbolContext context) protected ReflectionSymbolContext Context => _context; /// - public virtual bool IsMissing => false; + public bool IsMissing => false; + + /// + public bool ContainsMissing => false; /// /// Resolves the symbol for the specified type. @@ -66,20 +69,6 @@ protected internal IEnumerable ResolveModuleSymbols(IEnu yield return ResolveModuleSymbol(module); } - /// - /// Unpacks the symbols into their original type. - /// - /// - /// - protected internal Module[] UnpackModuleSymbols(IModuleSymbol[] modules) - { - var a = new Module[modules.Length]; - for (int i = 0; i < modules.Length; i++) - a[i] = ((ReflectionModuleSymbol)modules[i]).ReflectionModule; - - return a; - } - /// /// Resolves the symbol for the specified type. /// @@ -116,20 +105,6 @@ protected internal ReflectionMemberSymbol[] ResolveMemberSymbols(MemberInfo[] ty return a; } - /// - /// Unpacks the symbols into their original type. - /// - /// - /// - protected internal MemberInfo[] UnpackMemberSymbols(IMemberSymbol[] members) - { - var a = new MemberInfo[members.Length]; - for (int i = 0; i < members.Length; i++) - a[i] = ((ReflectionMemberSymbol)members[i]).ReflectionObject; - - return a; - } - /// /// Resolves the symbol for the specified type. /// @@ -165,20 +140,6 @@ protected internal IEnumerable ResolveTypeSymbols(IEnumera yield return ResolveTypeSymbol(type); } - /// - /// Unpacks the symbols into their original type. - /// - /// - /// - protected internal Type[] UnpackTypeSymbols(ITypeSymbol[] types) - { - var a = new Type[types.Length]; - for (int i = 0; i < types.Length; i++) - a[i] = ((ReflectionTypeSymbol)types[i]).ReflectionObject; - - return a; - } - /// /// Resolves the symbol for the specified method. /// @@ -240,30 +201,6 @@ protected internal ReflectionMethodSymbol[] ResolveMethodSymbols(MethodInfo[] me return a; } - /// - /// Resolves the symbol for the specified parameter. - /// - /// - /// - protected virtual internal ReflectionParameterSymbol ResolveParameterSymbol(ParameterInfo parameter) - { - return _context.GetOrCreateParameterSymbol(parameter); - } - - /// - /// Resolves the symbols for the specified parameters. - /// - /// - /// - protected internal ReflectionParameterSymbol[] ResolveParameterSymbols(ParameterInfo[] parameters) - { - var a = new ReflectionParameterSymbol[parameters.Length]; - for (int i = 0; i < parameters.Length; i++) - a[i] = ResolveParameterSymbol(parameters[i]); - - return a; - } - /// /// Resolves the symbol for the specified field. /// @@ -336,14 +273,38 @@ protected internal ReflectionEventSymbol[] ResolveEventSymbols(EventInfo[] event return a; } + /// + /// Resolves the symbol for the specified parameter. + /// + /// + /// + protected virtual internal ReflectionParameterSymbol ResolveParameterSymbol(ParameterInfo parameter) + { + return _context.GetOrCreateParameterSymbol(parameter); + } + + /// + /// Resolves the symbols for the specified parameters. + /// + /// + /// + protected internal ReflectionParameterSymbol[] ResolveParameterSymbols(ParameterInfo[] parameters) + { + var a = new ReflectionParameterSymbol[parameters.Length]; + for (int i = 0; i < parameters.Length; i++) + a[i] = ResolveParameterSymbol(parameters[i]); + + return a; + } + /// /// Transforms a custom set of custom attribute data records to a symbol record. /// /// /// - protected internal CustomAttributeSymbol[] ResolveCustomAttributes(IList attributes) + protected internal CustomAttribute[] ResolveCustomAttributes(IList attributes) { - var a = new CustomAttributeSymbol[attributes.Count]; + var a = new CustomAttribute[attributes.Count]; for (int i = 0; i < attributes.Count; i++) a[i] = ResolveCustomAttribute(attributes[i]); @@ -355,9 +316,9 @@ protected internal CustomAttributeSymbol[] ResolveCustomAttributes(IList /// /// - protected internal CustomAttributeSymbol[] ResolveCustomAttributes(IEnumerable attributes) + protected internal CustomAttribute[] ResolveCustomAttributes(IEnumerable attributes) { - var a = new List(); + var a = new List(); foreach (var i in attributes) a.Add(ResolveCustomAttribute(i)); @@ -370,9 +331,9 @@ protected internal CustomAttributeSymbol[] ResolveCustomAttributes(IEnumerable /// /// - protected internal CustomAttributeSymbol ResolveCustomAttribute(CustomAttributeData customAttributeData) + protected internal CustomAttribute ResolveCustomAttribute(CustomAttributeData customAttributeData) { - return new CustomAttributeSymbol( + return new CustomAttribute( ResolveTypeSymbol(customAttributeData.AttributeType), ResolveConstructorSymbol(customAttributeData.Constructor), ResolveCustomAttributeTypedArguments(customAttributeData.ConstructorArguments), @@ -380,13 +341,13 @@ protected internal CustomAttributeSymbol ResolveCustomAttribute(CustomAttributeD } /// - /// Transforms a list of values into symbols. + /// Transforms a list of values into symbols. /// /// /// - ImmutableArray ResolveCustomAttributeTypedArguments(IList args) + ImmutableArray ResolveCustomAttributeTypedArguments(IList args) { - var a = new CustomAttributeSymbolTypedArgument[args.Count]; + var a = new CustomAttributeTypedArgument[args.Count]; for (int i = 0; i < args.Count; i++) a[i] = ResolveCustomAttributeTypedArgument(args[i]); @@ -394,23 +355,36 @@ ImmutableArray ResolveCustomAttributeTypedAr } /// - /// Transforms a values into a symbol. + /// Transforms a values into a symbol. /// /// /// - CustomAttributeSymbolTypedArgument ResolveCustomAttributeTypedArgument(CustomAttributeTypedArgument arg) + CustomAttributeTypedArgument ResolveCustomAttributeTypedArgument(System.Reflection.CustomAttributeTypedArgument arg) + { + return new CustomAttributeTypedArgument(ResolveTypeSymbol(arg.ArgumentType), ResolveCustomAttributeTypedValue(arg.Value)); + } + + /// + /// Transforms the type as appropriate. + /// + /// + /// + object? ResolveCustomAttributeTypedValue(object? value) { - return new CustomAttributeSymbolTypedArgument(ResolveTypeSymbol(arg.ArgumentType), arg.Value); + if (value is System.Type v) + return ResolveTypeSymbol(v); + + return value; } /// - /// Transforms a list of values into symbols. + /// Transforms a list of values into symbols. /// /// /// - ImmutableArray ResolveCustomAttributeNamedArguments(IList args) + ImmutableArray ResolveCustomAttributeNamedArguments(IList args) { - var a = new CustomAttributeSymbolNamedArgument[args.Count]; + var a = new CustomAttributeNamedArgument[args.Count]; for (int i = 0; i < args.Count; i++) a[i] = ResolveCustomAttributeNamedArgument(args[i]); @@ -418,13 +392,13 @@ ImmutableArray ResolveCustomAttributeNamedAr } /// - /// Transforms a values into a symbol. + /// Transforms a values into a symbol. /// /// /// - CustomAttributeSymbolNamedArgument ResolveCustomAttributeNamedArgument(CustomAttributeNamedArgument arg) + CustomAttributeNamedArgument ResolveCustomAttributeNamedArgument(System.Reflection.CustomAttributeNamedArgument arg) { - return new CustomAttributeSymbolNamedArgument(arg.IsField, ResolveMemberSymbol(arg.MemberInfo), arg.MemberName, ResolveCustomAttributeTypedArgument(arg.TypedValue)); + return new CustomAttributeNamedArgument(arg.IsField, ResolveMemberSymbol(arg.MemberInfo), arg.MemberName, ResolveCustomAttributeTypedArgument(arg.TypedValue)); } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs index b88ecdf06..6a65e9547 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs @@ -1,7 +1,10 @@ using System; using System.Reflection; +using System.Reflection.Emit; using System.Runtime.CompilerServices; +using IKVM.CoreLib.Symbols.Reflection.Emit; + namespace IKVM.CoreLib.Symbols.Reflection { @@ -51,6 +54,19 @@ public ReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) return GetOrCreateModuleSymbol(type.Module).GetOrCreateTypeSymbol(type); } + /// + /// Gets or creates a for the specified . + /// + /// + /// + public ReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method) + { + if (method is ConstructorInfo ctor) + return GetOrCreateConstructorSymbol(ctor); + else + return GetOrCreateMethodSymbol((MethodInfo)method); + } + /// /// Gets or creates a for the specified . /// @@ -58,17 +74,17 @@ public ReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) /// public ReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) { - return GetOrCreateAssemblySymbol(ctor.Module.Assembly).GetOrCreateModuleSymbol(ctor.Module).GetOrCreateTypeSymbol(ctor.DeclaringType!).GetOrCreateConstructorSymbol(ctor); + return GetOrCreateModuleSymbol(ctor.Module).GetOrCreateConstructorSymbol(ctor); } /// - /// Gets or creates a for the specified . + /// Gets or creates a for the specified . /// /// /// public ReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) { - return GetOrCreateAssemblySymbol(method.Module.Assembly).GetOrCreateModuleSymbol(method.Module).GetOrCreateTypeSymbol(method.DeclaringType!).GetOrCreateMethodSymbol(method); + return GetOrCreateModuleSymbol(method.Module).GetOrCreateMethodSymbol(method); } /// @@ -78,7 +94,7 @@ public ReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) /// public ReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) { - return GetOrCreateAssemblySymbol(parameter.Member.Module.Assembly).GetOrCreateModuleSymbol(parameter.Member.Module).GetOrCreateTypeSymbol(parameter.Member.DeclaringType!).GetOrCreateMethodBaseSymbol((MethodBase)parameter.Member).GetOrCreateParameterSymbol(parameter); + return GetOrCreateModuleSymbol(parameter.Member.Module).GetOrCreateParameterSymbol(parameter); } /// @@ -88,7 +104,7 @@ public ReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parame /// public ReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) { - return GetOrCreateAssemblySymbol(field.Module.Assembly).GetOrCreateModuleSymbol(field.Module).GetOrCreateTypeSymbol(field.DeclaringType!).GetOrCreateFieldSymbol(field); + return GetOrCreateModuleSymbol(field.Module).GetOrCreateFieldSymbol(field); } /// @@ -98,7 +114,7 @@ public ReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) /// public ReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) { - return GetOrCreateAssemblySymbol(property.Module.Assembly).GetOrCreateModuleSymbol(property.Module).GetOrCreateTypeSymbol(property.DeclaringType!).GetOrCreatePropertySymbol(property); + return GetOrCreateModuleSymbol(property.Module).GetOrCreatePropertySymbol(property); } /// @@ -108,7 +124,27 @@ public ReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) /// public ReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) { - return GetOrCreateAssemblySymbol(@event.Module.Assembly).GetOrCreateModuleSymbol(@event.Module).GetOrCreateTypeSymbol(@event.DeclaringType!).GetOrCreateEventSymbol(@event); + return GetOrCreateModuleSymbol(@event.Module).GetOrCreateEventSymbol(@event); + } + + /// + /// Gets or creates a for the specified . + /// + /// + /// + public ReflectionEventSymbol GetOrCreateEventSymbol(EventBuilder @event) + { + return GetOrCreateEventSymbol(new ReflectionEventBuilderInfo(@event)); + } + + /// + /// Gets or creates a for the specified . + /// + /// + /// + public ReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterBuilder parameter) + { + return GetOrCreateParameterSymbol(new ReflectionParameterBuilderInfo(parameter)); } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbol.cs index df9b1ffe7..b49dbe028 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbol.cs @@ -3,46 +3,30 @@ using System.Diagnostics; using System.Linq; using System.Reflection; -using System.Reflection.Metadata.Ecma335; using System.Threading; -using IKVM.CoreLib.Symbols.IkvmReflection; - namespace IKVM.CoreLib.Symbols.Reflection { class ReflectionTypeSymbol : ReflectionMemberSymbol, ITypeSymbol { - const BindingFlags DefaultBindingFlags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance; - - readonly Type _type; - - MethodBase[]? _methodsSource; - int _methodsBaseRow; - ReflectionMethodBaseSymbol?[]? _methods; + const int MAX_CAPACITY = 65536 * 2; - FieldInfo[]? _fieldsSource; - int _fieldsBaseRow; - ReflectionFieldSymbol?[]? _fields; - - PropertyInfo[]? _propertiesSource; - int _propertiesBaseRow; - ReflectionPropertySymbol?[]? _properties; + const BindingFlags DefaultBindingFlags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance; - EventInfo[]? _eventsSource; - int _eventsBaseRow; - ReflectionEventSymbol?[]? _events; + Type _type; ReflectionTypeSymbol?[]? _asArray; ReflectionTypeSymbol? _asSZArray; ReflectionTypeSymbol? _asPointer; ReflectionTypeSymbol? _asByRef; - Type[]? _genericParametersSource; - ReflectionTypeSymbol?[]? _genericParameters; - List<(Type[] Arguments, ReflectionTypeSymbol Symbol)>? _genericTypes; - ReaderWriterLockSlim? _genericTypesLock; + Type[]? _genericParameterList; + ReflectionTypeSymbol?[]? _genericParameterSymbols; + + List<(Type[] Arguments, ReflectionTypeSymbol Symbol)>? _genericTypeSymbols; + ReaderWriterLockSlim? _genericTypeLock; /// /// Initializes a new instance. @@ -51,233 +35,12 @@ class ReflectionTypeSymbol : ReflectionMemberSymbol, ITypeSymbol /// /// public ReflectionTypeSymbol(ReflectionSymbolContext context, ReflectionModuleSymbol module, Type type) : - base(context, module, null, type) + base(context, module, type) { - Debug.Assert(module.ReflectionModule == type.Module); + Debug.Assert(module.ReflectionObject == type.Module); _type = type ?? throw new ArgumentNullException(nameof(type)); } - /// - /// Gets or creates the cached for the type by method. - /// - /// - /// - internal ReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) - { - return (ReflectionMethodSymbol)GetOrCreateMethodBaseSymbol(method); - } - - /// - /// Gets or creates the cached for the type by ctor. - /// - /// - /// - internal ReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) - { - return (ReflectionConstructorSymbol)GetOrCreateMethodBaseSymbol(ctor); - } - - /// - /// Gets or creates the cached for the type by method. - /// - /// - /// - internal ReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method) - { - if (method is null) - throw new ArgumentNullException(nameof(method)); - - Debug.Assert(method.DeclaringType == _type); - - var hnd = MetadataTokens.MethodDefinitionHandle(method.MetadataToken); - var row = MetadataTokens.GetRowNumber(hnd); - - // initialize source table - if (_methodsSource == null) - { - Interlocked.CompareExchange(ref _methodsSource, _type.GetConstructors(DefaultBindingFlags).Cast().Concat(_type.GetMethods(DefaultBindingFlags)).OrderBy(i => i.MetadataToken).ToArray(), null); - _methodsBaseRow = _methodsSource.Length != 0 ? MetadataTokens.GetRowNumber(MetadataTokens.MethodDefinitionHandle(_methodsSource[0].MetadataToken)) : 0; - } - - // initialize cache table - if (_methods == null) - Interlocked.CompareExchange(ref _methods, new ReflectionMethodBaseSymbol?[_methodsSource.Length], null); - - // index of current record is specified row - base - var idx = row - _methodsBaseRow; - Debug.Assert(idx >= 0); - Debug.Assert(idx < _methodsSource.Length); - - // check that our list is long enough to contain the entire table - if (_methods.Length < idx) - throw new IndexOutOfRangeException(); - - // if not yet created, create, allow multiple instances, but only one is eventually inserted - ref var rec = ref _methods[idx]; - if (rec == null) - { - switch (method) - { - case ConstructorInfo c: - Interlocked.CompareExchange(ref rec, new ReflectionConstructorSymbol(Context, ContainingModule, this, c), null); - break; - case MethodInfo m: - Interlocked.CompareExchange(ref rec, new ReflectionMethodSymbol(Context, ContainingModule, this, m), null); - break; - } - } - - // this should never happen - if (rec is not ReflectionMethodBaseSymbol sym) - throw new InvalidOperationException(); - - return sym; - } - - /// - /// Gets or creates the cached for the type by field. - /// - /// - /// - /// - internal ReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) - { - if (field is null) - throw new ArgumentNullException(nameof(field)); - - Debug.Assert(field.DeclaringType == _type); - - var hnd = MetadataTokens.FieldDefinitionHandle(field.MetadataToken); - var row = MetadataTokens.GetRowNumber(hnd); - - // initialize source table - if (_fieldsSource == null) - { - Interlocked.CompareExchange(ref _fieldsSource, _type.GetFields(DefaultBindingFlags).OrderBy(i => i.MetadataToken).ToArray(), null); - _fieldsBaseRow = _fieldsSource.Length != 0 ? MetadataTokens.GetRowNumber(MetadataTokens.MethodDefinitionHandle(_fieldsSource[0].MetadataToken)) : 0; - } - - // initialize cache table - if (_fields == null) - Interlocked.CompareExchange(ref _fields, new ReflectionFieldSymbol?[_fieldsSource.Length], null); - - // index of current field is specified row - base - var idx = row - _fieldsBaseRow; - Debug.Assert(idx >= 0); - Debug.Assert(idx < _fieldsSource.Length); - - // check that our list is long enough to contain the entire table - if (_fields.Length < idx) - throw new IndexOutOfRangeException(); - - // if not yet created, create, allow multiple instances, but only one is eventually inserted - ref var rec = ref _fields[idx]; - if (rec == null) - Interlocked.CompareExchange(ref rec, new ReflectionFieldSymbol(Context, this, field), null); - - // this should never happen - if (rec is not ReflectionFieldSymbol sym) - throw new InvalidOperationException(); - - return sym; - } - - /// - /// Gets or creates the cached for the type by property. - /// - /// - /// - /// - internal ReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) - { - if (property is null) - throw new ArgumentNullException(nameof(property)); - - Debug.Assert(property.DeclaringType == _type); - - var hnd = MetadataTokens.PropertyDefinitionHandle(property.MetadataToken); - var row = MetadataTokens.GetRowNumber(hnd); - - // initialize source table - if (_propertiesSource == null) - { - Interlocked.CompareExchange(ref _propertiesSource, _type.GetProperties(DefaultBindingFlags).OrderBy(i => i.MetadataToken).ToArray(), null); - _propertiesBaseRow = _propertiesSource.Length != 0 ? MetadataTokens.GetRowNumber(MetadataTokens.MethodDefinitionHandle(_propertiesSource[0].MetadataToken)) : 0; - } - - // initialize cache table - if (_properties == null) - Interlocked.CompareExchange(ref _properties, new ReflectionPropertySymbol?[_propertiesSource.Length], null); - - // index of current property is specified row - base - var idx = row - _propertiesBaseRow; - Debug.Assert(idx >= 0); - Debug.Assert(idx < _propertiesSource.Length); - - // check that our list is long enough to contain the entire table - if (_properties.Length < idx) - throw new IndexOutOfRangeException(); - - // if not yet created, create, allow multiple instances, but only one is eventually inserted - ref var rec = ref _properties[idx]; - if (rec == null) - Interlocked.CompareExchange(ref rec, new ReflectionPropertySymbol(Context, this, property), null); - - // this should never happen - if (rec is not ReflectionPropertySymbol sym) - throw new InvalidOperationException(); - - return sym; - } - - /// - /// Gets or creates the cached for the type by event. - /// - /// - /// - /// - internal ReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) - { - if (@event is null) - throw new ArgumentNullException(nameof(@event)); - - Debug.Assert(@event.DeclaringType == _type); - - var hnd = MetadataTokens.PropertyDefinitionHandle(@event.MetadataToken); - var row = MetadataTokens.GetRowNumber(hnd); - - // initialize source events - if (_eventsSource == null) - { - Interlocked.CompareExchange(ref _eventsSource, _type.GetEvents(DefaultBindingFlags).OrderBy(i => i.MetadataToken).ToArray(), null); - _eventsBaseRow = _eventsSource.Length != 0 ? MetadataTokens.GetRowNumber(MetadataTokens.EventDefinitionHandle(_eventsSource[0].MetadataToken)) : 0; - } - - // initialize cache table - if (_events == null) - Interlocked.CompareExchange(ref _events, new ReflectionEventSymbol?[_eventsSource.Length], null); - - // index of current event is specified row - base - var idx = row - _eventsBaseRow; - Debug.Assert(idx >= 0); - Debug.Assert(idx < _eventsSource.Length); - - // check that our list is long enough to contain the entire table - if (_events.Length < idx) - throw new IndexOutOfRangeException(); - - // if not yet created, create, allow multiple instances, but only one is eventually inserted - ref var rec = ref _events[idx]; - if (rec == null) - Interlocked.CompareExchange(ref rec, new ReflectionEventSymbol(Context, this, @event), null); - - // this should never happen - if (rec is not ReflectionEventSymbol sym) - throw new InvalidOperationException(); - - return sym; - } - /// /// Gets or creates the cached for the generic parameter type. /// @@ -292,20 +55,20 @@ internal ReflectionTypeSymbol GetOrCreateGenericParameterSymbol(Type genericType Debug.Assert(genericTypeParameterType.DeclaringType == _type); // initialize tables - if (_genericParametersSource == null) - Interlocked.CompareExchange(ref _genericParametersSource, _type.GetGenericArguments(), null); - if (_genericParameters == null) - Interlocked.CompareExchange(ref _genericParameters, new ReflectionTypeSymbol?[_genericParametersSource.Length], null); + if (_genericParameterList == null) + Interlocked.CompareExchange(ref _genericParameterList, _type.GetGenericArguments(), null); + if (_genericParameterSymbols == null) + Interlocked.CompareExchange(ref _genericParameterSymbols, new ReflectionTypeSymbol?[_genericParameterList.Length], null); // position of the parameter in the list var idx = genericTypeParameterType.GenericParameterPosition; // check that our list is long enough to contain the entire table - if (_genericParameters.Length < idx) + if (_genericParameterSymbols.Length < idx) throw new IndexOutOfRangeException(); // if not yet created, create, allow multiple instances, but only one is eventually inserted - ref var rec = ref _genericParameters[idx]; + ref var rec = ref _genericParameterSymbols[idx]; if (rec == null) Interlocked.CompareExchange(ref rec, new ReflectionTypeSymbol(Context, ContainingModule, genericTypeParameterType), null); @@ -331,43 +94,43 @@ internal ReflectionTypeSymbol GetOrCreateGenericTypeSymbol(Type[] genericTypeArg throw new InvalidOperationException(); // initialize the available parameters - if (_genericParametersSource == null) - Interlocked.CompareExchange(ref _genericParametersSource, _type.GetGenericArguments(), null); - if (_genericParametersSource.Length != genericTypeArguments.Length) + if (_genericParameterList == null) + Interlocked.CompareExchange(ref _genericParameterList, _type.GetGenericArguments(), null); + if (_genericParameterList.Length != genericTypeArguments.Length) throw new InvalidOperationException(); // initialize generic type map, and lock on it since we're potentially adding items - if (_genericTypes == null) - Interlocked.CompareExchange(ref _genericTypes, [], null); - if (_genericTypesLock == null) - Interlocked.CompareExchange(ref _genericTypesLock, new(), null); + if (_genericTypeSymbols == null) + Interlocked.CompareExchange(ref _genericTypeSymbols, [], null); + if (_genericTypeLock == null) + Interlocked.CompareExchange(ref _genericTypeLock, new(), null); try { - _genericTypesLock.EnterUpgradeableReadLock(); + _genericTypeLock.EnterUpgradeableReadLock(); // find existing entry - foreach (var i in _genericTypes) + foreach (var i in _genericTypeSymbols) if (i.Arguments.SequenceEqual(genericTypeArguments)) return i.Symbol; try { - _genericTypesLock.EnterWriteLock(); + _genericTypeLock.EnterWriteLock(); // generate new symbol var sym = new ReflectionTypeSymbol(Context, ContainingModule, _type.MakeGenericType(genericTypeArguments)); - _genericTypes.Add((genericTypeArguments, sym)); + _genericTypeSymbols.Add((genericTypeArguments, sym)); return sym; } finally { - _genericTypesLock.ExitWriteLock(); + _genericTypeLock.ExitWriteLock(); } } finally { - _genericTypesLock.ExitUpgradeableReadLock(); + _genericTypeLock.ExitUpgradeableReadLock(); } } @@ -384,418 +147,499 @@ protected internal override ReflectionTypeSymbol ResolveTypeSymbol(Type type) return base.ResolveTypeSymbol(type); } - /// - /// Resolves the symbol for the specified constructor. - /// - /// - /// - protected internal override ReflectionConstructorSymbol ResolveConstructorSymbol(ConstructorInfo ctor) - { - if (ctor.DeclaringType == _type) - return GetOrCreateConstructorSymbol(ctor); - else - return base.ResolveConstructorSymbol(ctor); - } - - /// - /// Resolves the symbol for the specified method. - /// - /// - /// - protected internal override ReflectionMethodSymbol ResolveMethodSymbol(MethodInfo method) - { - if (method.DeclaringType == _type) - return GetOrCreateMethodSymbol(method); - else - return base.ResolveMethodSymbol(method); - } - - /// - /// Resolves the symbol for the specified field. - /// - /// - /// - protected internal override ReflectionFieldSymbol ResolveFieldSymbol(FieldInfo field) - { - if (field.DeclaringType == _type) - return GetOrCreateFieldSymbol(field); - else - return base.ResolveFieldSymbol(field); - } - - /// - /// Resolves the symbol for the specified field. - /// - /// - /// - protected internal override ReflectionPropertySymbol ResolvePropertySymbol(PropertyInfo property) - { - if (property.DeclaringType == _type) - return GetOrCreatePropertySymbol(property); - else - return base.ResolvePropertySymbol(property); - } - - /// - /// Resolves the symbol for the specified event. - /// - /// - /// - protected internal override ReflectionEventSymbol ResolveEventSymbol(EventInfo @event) - { - if (@event.DeclaringType == _type) - return GetOrCreateEventSymbol(@event); - else - return base.ResolveEventSymbol(@event); - } - /// /// Gets the wrapped . /// internal new Type ReflectionObject => _type; + /// public IAssemblySymbol Assembly => Context.GetOrCreateAssemblySymbol(_type.Assembly); + /// public string? AssemblyQualifiedName => _type.AssemblyQualifiedName; + /// public TypeAttributes Attributes => _type.Attributes; + /// public ITypeSymbol? BaseType => _type.BaseType != null ? ResolveTypeSymbol(_type.BaseType) : null; + /// public bool ContainsGenericParameters => _type.ContainsGenericParameters; + /// public IMethodBaseSymbol? DeclaringMethod => _type.DeclaringMethod is MethodInfo m ? ResolveMethodSymbol(m) : null; + /// public string? FullName => _type.FullName; + /// + public string? Namespace => _type.Namespace; + + /// public GenericParameterAttributes GenericParameterAttributes => _type.GenericParameterAttributes; + /// public int GenericParameterPosition => _type.GenericParameterPosition; + /// public ITypeSymbol[] GenericTypeArguments => ResolveTypeSymbols(_type.GenericTypeArguments); + /// public bool HasElementType => _type.HasElementType; + /// + public TypeCode TypeCode => Type.GetTypeCode(_type); + + /// public bool IsAbstract => _type.IsAbstract; +#if NETFRAMEWORK + + /// + /// + /// There's no API to distinguish an array of rank 1 from a vector, + /// so we check if the type name ends in [], which indicates it's a vector + /// (non-vectors will have [*] or [,]). + /// + public bool IsSZArray => _type.IsArray && _type.Name.EndsWith("[]"); + +#else + + /// + public bool IsSZArray => _type.IsSZArray; + +#endif + + /// public bool IsArray => _type.IsArray; + /// public bool IsAutoLayout => _type.IsAutoLayout; + /// + public bool IsExplicitLayout => _type.IsExplicitLayout; + + /// public bool IsByRef => _type.IsByRef; + /// public bool IsClass => _type.IsClass; - public bool IsConstructedGenericType => _type.IsConstructedGenericType; - + /// public bool IsEnum => _type.IsEnum; - public bool IsExplicitLayout => _type.IsExplicitLayout; + /// + public bool IsInterface => _type.IsInterface; + /// + public bool IsConstructedGenericType => _type.IsConstructedGenericType; + + /// public bool IsGenericParameter => _type.IsGenericParameter; + /// public bool IsGenericType => _type.IsGenericType; + /// public bool IsGenericTypeDefinition => _type.IsGenericTypeDefinition; - public bool IsInterface => _type.IsInterface; - + /// public bool IsLayoutSequential => _type.IsLayoutSequential; + /// public bool IsNested => _type.IsNested; + /// public bool IsNestedAssembly => _type.IsNestedAssembly; + /// public bool IsNestedFamANDAssem => _type.IsNestedFamANDAssem; + /// public bool IsNestedFamORAssem => _type.IsNestedFamORAssem; + /// public bool IsNestedFamily => _type.IsNestedFamily; + /// public bool IsNestedPrivate => _type.IsNestedPrivate; + /// public bool IsNestedPublic => _type.IsNestedPublic; + /// public bool IsNotPublic => _type.IsNotPublic; + /// public bool IsPointer => _type.IsPointer; +#if NET8_0_OR_GREATER + + /// + public bool IsFunctionPointer => _type.IsFunctionPointer; + + /// + public bool IsUnmanagedFunctionPointer => _type.IsUnmanagedFunctionPointer; + +#else + + /// + public bool IsFunctionPointer => throw new NotImplementedException(); + + /// + public bool IsUnmanagedFunctionPointer => throw new NotImplementedException(); + +#endif + + /// public bool IsPrimitive => _type.IsPrimitive; + /// public bool IsPublic => _type.IsPublic; + /// public bool IsSealed => _type.IsSealed; #pragma warning disable SYSLIB0050 // Type or member is obsolete + /// public bool IsSerializable => _type.IsSerializable; #pragma warning restore SYSLIB0050 // Type or member is obsolete + /// public bool IsValueType => _type.IsValueType; + /// public bool IsVisible => _type.IsVisible; - public string? Namespace => _type.Namespace; +#if NET6_0_OR_GREATER + + /// + public bool IsSignatureType => _type.IsSignatureType; +#else + + /// + public bool IsSignatureType => throw new NotImplementedException(); + +#endif + + /// + public bool IsSpecialName => _type.IsSpecialName; + + /// public IConstructorSymbol? TypeInitializer => _type.TypeInitializer is ConstructorInfo ctor ? ResolveConstructorSymbol(ctor) : null; + /// public int GetArrayRank() { return _type.GetArrayRank(); } + /// public IConstructorSymbol? GetConstructor(BindingFlags bindingAttr, ITypeSymbol[] types) { - return _type.GetConstructor(bindingAttr, binder: null, UnpackTypeSymbols(types), modifiers: null) is ConstructorInfo ctor ? ResolveConstructorSymbol(ctor) : null; + return _type.GetConstructor(bindingAttr, binder: null, types.Unpack(), modifiers: null) is ConstructorInfo ctor ? ResolveConstructorSymbol(ctor) : null; } + /// public IConstructorSymbol? GetConstructor(ITypeSymbol[] types) { - return _type.GetConstructor(UnpackTypeSymbols(types)) is ConstructorInfo ctor ? ResolveConstructorSymbol(ctor) : null; + return _type.GetConstructor(types.Unpack()) is ConstructorInfo ctor ? ResolveConstructorSymbol(ctor) : null; } + /// public IConstructorSymbol[] GetConstructors() { return ResolveConstructorSymbols(_type.GetConstructors()); } + /// public IConstructorSymbol[] GetConstructors(BindingFlags bindingAttr) { return ResolveConstructorSymbols(_type.GetConstructors(bindingAttr)); } + /// public IMemberSymbol[] GetDefaultMembers() { return ResolveMemberSymbols(_type.GetDefaultMembers()); } + /// public ITypeSymbol? GetElementType() { return _type.GetElementType() is Type t ? ResolveTypeSymbol(t) : null; } + /// public string? GetEnumName(object value) { return _type.GetEnumName(value); } + /// public string[] GetEnumNames() { return _type.GetEnumNames(); } + /// public ITypeSymbol GetEnumUnderlyingType() { return ResolveTypeSymbol(_type.GetEnumUnderlyingType()); } + /// public Array GetEnumValues() { return _type.GetEnumValues(); } + /// public IEventSymbol? GetEvent(string name, BindingFlags bindingAttr) { throw new NotImplementedException(); } + /// public IEventSymbol? GetEvent(string name) { return _type.GetEvent(name) is { } f ? ResolveEventSymbol(f) : null; } + /// public IEventSymbol[] GetEvents() { return ResolveEventSymbols(_type.GetEvents()); } + /// public IEventSymbol[] GetEvents(BindingFlags bindingAttr) { return ResolveEventSymbols(_type.GetEvents(bindingAttr)); } + /// public IFieldSymbol? GetField(string name) { return _type.GetField(name) is FieldInfo f ? ResolveFieldSymbol(f) : null; } + /// public IFieldSymbol? GetField(string name, BindingFlags bindingAttr) { return _type.GetField(name, bindingAttr) is FieldInfo f ? ResolveFieldSymbol(f) : null; } + /// public IFieldSymbol[] GetFields() { return ResolveFieldSymbols(_type.GetFields()); } + /// public IFieldSymbol[] GetFields(BindingFlags bindingAttr) { return ResolveFieldSymbols(_type.GetFields(bindingAttr)); } + /// public ITypeSymbol[] GetGenericArguments() { return ResolveTypeSymbols(_type.GetGenericArguments()); } + /// public ITypeSymbol[] GetGenericParameterConstraints() { return ResolveTypeSymbols(_type.GetGenericParameterConstraints()); } + /// public ITypeSymbol GetGenericTypeDefinition() { return ResolveTypeSymbol(_type.GetGenericTypeDefinition()); } + /// public ITypeSymbol? GetInterface(string name) { return _type.GetInterface(name) is { } i ? ResolveTypeSymbol(i) : null; } + /// public ITypeSymbol? GetInterface(string name, bool ignoreCase) { return _type.GetInterface(name, ignoreCase) is { } i ? ResolveTypeSymbol(i) : null; } + /// public InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) { throw new NotImplementedException(); } - public ITypeSymbol[] GetInterfaces() + /// + public ITypeSymbol[] GetInterfaces(bool inherit = true) { - return ResolveTypeSymbols(_type.GetInterfaces()); + if (inherit) + return ResolveTypeSymbols(_type.GetInterfaces()); + else + throw new NotImplementedException(); } + /// public IMemberSymbol[] GetMember(string name) { return ResolveMemberSymbols(_type.GetMember(name)); } + /// public IMemberSymbol[] GetMember(string name, BindingFlags bindingAttr) { return ResolveMemberSymbols(_type.GetMember(name, bindingAttr)); } + /// public IMemberSymbol[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) { return ResolveMemberSymbols(_type.GetMember(name, type, bindingAttr)); } + /// public IMemberSymbol[] GetMembers(BindingFlags bindingAttr) { return ResolveMemberSymbols(_type.GetMembers(bindingAttr)); } + /// public IMemberSymbol[] GetMembers() { return ResolveMemberSymbols(_type.GetMembers()); } + /// public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr) { return _type.GetMethod(name, bindingAttr) is { } m ? ResolveMethodSymbol(m) : null; } + /// public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) { - return _type.GetMethod(name, UnpackTypeSymbols(types)) is { } m ? ResolveMethodSymbol(m) : null; + return _type.GetMethod(name, types.Unpack()) is { } m ? ResolveMethodSymbol(m) : null; } + /// public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types) { - return _type.GetMethod(name, bindingAttr, null, UnpackTypeSymbols(types), null) is { } m ? ResolveMethodSymbol(m) : null; + return _type.GetMethod(name, bindingAttr, null, types.Unpack(), null) is { } m ? ResolveMethodSymbol(m) : null; } + /// public IMethodSymbol? GetMethod(string name) { return _type.GetMethod(name) is { } m ? ResolveMethodSymbol(m) : null; } + /// public IMethodSymbol[] GetMethods(BindingFlags bindingAttr) { return ResolveMethodSymbols(_type.GetMethods(bindingAttr)); } + /// public IMethodSymbol[] GetMethods() { return ResolveMethodSymbols(_type.GetMethods()); } + /// public ITypeSymbol? GetNestedType(string name) { return _type.GetNestedType(name) is Type t ? ResolveTypeSymbol(t) : null; } + /// public ITypeSymbol? GetNestedType(string name, BindingFlags bindingAttr) { return _type.GetNestedType(name, bindingAttr) is Type t ? ResolveTypeSymbol(t) : null; } + /// public ITypeSymbol[] GetNestedTypes() { return ResolveTypeSymbols(_type.GetNestedTypes()); } + /// public ITypeSymbol[] GetNestedTypes(BindingFlags bindingAttr) { return ResolveTypeSymbols(_type.GetNestedTypes(bindingAttr)); } + /// public IPropertySymbol[] GetProperties() { return ResolvePropertySymbols(_type.GetProperties()); } + /// public IPropertySymbol[] GetProperties(BindingFlags bindingAttr) { return ResolvePropertySymbols(_type.GetProperties(bindingAttr)); } + /// public IPropertySymbol? GetProperty(string name, ITypeSymbol[] types) { - return _type.GetProperty(name, UnpackTypeSymbols(types)) is { } p ? ResolvePropertySymbol(p) : null; + return _type.GetProperty(name, types.Unpack()) is { } p ? ResolvePropertySymbol(p) : null; } + /// public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types) { - var _returnType = returnType != null ? ((ReflectionTypeSymbol)returnType).ReflectionObject : null; - return _type.GetProperty(name, _returnType, UnpackTypeSymbols(types)) is { } p ? ResolvePropertySymbol(p) : null; + return _type.GetProperty(name, returnType?.Unpack(), types.Unpack()) is { } p ? ResolvePropertySymbol(p) : null; } + /// public IPropertySymbol? GetProperty(string name, BindingFlags bindingAttr) { return _type.GetProperty(name, bindingAttr) is { } p ? ResolvePropertySymbol(p) : null; } + /// public IPropertySymbol? GetProperty(string name) { return _type.GetProperty(name) is { } p ? ResolvePropertySymbol(p) : null; } + /// public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) { - var _returnType = returnType != null ? ((ReflectionTypeSymbol)returnType).ReflectionObject : null; - - return _type.GetProperty(name, _returnType) is { } p ? ResolvePropertySymbol(p) : null; + return _type.GetProperty(name, returnType?.Unpack()) is { } p ? ResolvePropertySymbol(p) : null; } + /// public bool IsAssignableFrom(ITypeSymbol? c) { - return _type.IsAssignableFrom(c != null ? ((ReflectionTypeSymbol)c).ReflectionObject : null); + return _type.IsAssignableFrom(c?.Unpack()); } + /// public bool IsEnumDefined(object value) { return _type.IsEnumDefined(value); } + /// public bool IsSubclassOf(ITypeSymbol c) { - return _type.IsSubclassOf(((ReflectionTypeSymbol)c).ReflectionObject); + return _type.IsSubclassOf(c.Unpack()); } + /// public ITypeSymbol MakeArrayType() { if (_asSZArray == null) @@ -804,6 +648,7 @@ public ITypeSymbol MakeArrayType() return _asSZArray; } + /// public ITypeSymbol MakeArrayType(int rank) { if (rank == 1) @@ -819,6 +664,7 @@ public ITypeSymbol MakeArrayType(int rank) return asArray; } + /// public ITypeSymbol MakeByRefType() { if (_asByRef == null) @@ -827,11 +673,13 @@ public ITypeSymbol MakeByRefType() return _asByRef; } + /// public ITypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments) { throw new NotImplementedException(); } + /// public ITypeSymbol MakePointerType() { if (_asPointer == null) @@ -840,6 +688,16 @@ public ITypeSymbol MakePointerType() return _asPointer; } + /// + /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. + /// + /// + /// + internal void FinishType(Type type) + { + _type = type; + } + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionUtil.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionUtil.cs new file mode 100644 index 000000000..30d988167 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionUtil.cs @@ -0,0 +1,146 @@ +using System; +using System.Reflection; + +namespace IKVM.CoreLib.Symbols.Reflection +{ + + static class ReflectionUtil + { + + /// + /// Unpacks the symbol into their original type. + /// + /// + /// + public static Module Unpack(this IModuleSymbol module) + { + return ((ReflectionModuleSymbol)module).ReflectionObject; + } + + /// + /// Unpacks the symbols into their original type. + /// + /// + /// + public static Module[] Unpack(this IModuleSymbol[] modules) + { + var a = new Module[modules.Length]; + for (int i = 0; i < modules.Length; i++) + a[i] = modules[i].Unpack(); + + return a; + } + + /// + /// Unpacks the symbol into their original type. + /// + /// + /// + public static Type Unpack(this ITypeSymbol type) + { + return ((ReflectionTypeSymbol)type).ReflectionObject; + } + + /// + /// Unpacks the symbols into their original type. + /// + /// + /// + public static Type[] Unpack(this ITypeSymbol[] types) + { + var a = new Type[types.Length]; + for (int i = 0; i < types.Length; i++) + a[i] = types[i].Unpack(); + + return a; + } + + /// + /// Unpacks the symbols into their original type. + /// + /// + /// + public static Type[][] Unpack(this ITypeSymbol[][] types) + { + var a = new Type[types.Length][]; + for (int i = 0; i < types.Length; i++) + a[i] = types[i].Unpack(); + + return a; + } + + /// + /// Unpacks the symbol into their original type. + /// + /// + /// + public static MemberInfo Unpack(this IMemberSymbol member) + { + return ((ReflectionMemberSymbol)member).ReflectionObject; + } + + /// + /// Unpacks the symbols into their original type. + /// + /// + /// + public static MemberInfo[] Unpack(this IMemberSymbol[] members) + { + var a = new MemberInfo[members.Length]; + for (int i = 0; i < members.Length; i++) + a[i] = members[i].Unpack(); + + return a; + } + + /// + /// Unpacks the symbol into their original type. + /// + /// + /// + public static ConstructorInfo Unpack(this IConstructorSymbol ctor) + { + return ((ReflectionConstructorSymbol)ctor).ReflectionObject; + } + + /// + /// Unpacks the symbols into their original type. + /// + /// + /// + public static ConstructorInfo[] Unpack(this IConstructorSymbol[] ctor) + { + var a = new ConstructorInfo[ctor.Length]; + for (int i = 0; i < ctor.Length; i++) + a[i] = ctor[i].Unpack(); + + return a; + } + + /// + /// Unpacks the symbol into their original type. + /// + /// + /// + public static MethodInfo Unpack(this IMethodSymbol ctor) + { + return ((ReflectionMethodSymbol)ctor).ReflectionObject; + } + + /// + /// Unpacks the symbols into their original type. + /// + /// + /// + public static MethodInfo[] Unpack(this IMethodSymbol[] ctor) + { + var a = new MethodInfo[ctor.Length]; + for (int i = 0; i < ctor.Length; i++) + a[i] = ctor[i].Unpack(); + + return a; + } + + } + +} diff --git a/src/IKVM.CoreLib/System/TypeExtensions.cs b/src/IKVM.CoreLib/System/TypeExtensions.cs new file mode 100644 index 000000000..1abd007c2 --- /dev/null +++ b/src/IKVM.CoreLib/System/TypeExtensions.cs @@ -0,0 +1,450 @@ +using System.Linq.Expressions; +using System.Reflection; +using System.Reflection.Emit; +using System.Reflection.Metadata.Ecma335; + +using IKVM.CoreLib.Symbols.Reflection.Emit; + +namespace System +{ + + static class TypeExtensions + { + + static readonly ParameterExpression _propertyBuilderParameter = Expression.Parameter(typeof(PropertyBuilder), "p"); + static readonly ParameterExpression _eventBuilderParameter = Expression.Parameter(typeof(EventBuilder), "p"); + static readonly ParameterExpression _parameterBuilderParameter = Expression.Parameter(typeof(ParameterBuilder), "p"); + +#if NET + + static readonly Type _propertyBuilderType = typeof(PropertyBuilder).Assembly.GetType("System.Reflection.Emit.RuntimePropertyBuilder", true)!; + static readonly Type _eventBuilderType = typeof(EventBuilder).Assembly.GetType("System.Reflection.Emit.RuntimeEventBuilder", true)!; + static readonly Type _parameterBuilderType = typeof(ParameterBuilder).Assembly.GetType("System.Reflection.Emit.RuntimeParameterBuilder", true)!; + + static readonly Func _getPropertyMetadataTokenFunc = Expression.Lambda>( + Expression.Field( + Expression.ConvertChecked(_propertyBuilderParameter, _propertyBuilderType), + _propertyBuilderType.GetField("m_tkProperty", BindingFlags.NonPublic | BindingFlags.Instance) ?? throw new InvalidOperationException()), + _propertyBuilderParameter) + .Compile(); + + + static readonly Func _getEventMetadataTokenFunc = Expression.Lambda>( + Expression.Field( + Expression.ConvertChecked(_eventBuilderParameter, _eventBuilderType), + _eventBuilderType.GetField("m_evToken", BindingFlags.NonPublic | BindingFlags.Instance) ?? throw new InvalidOperationException()), + _eventBuilderParameter) + .Compile(); + + static readonly Func _getParameterMethodBuilderFunc = Expression.Lambda>( + Expression.Field( + Expression.ConvertChecked(_parameterBuilderParameter, _parameterBuilderType), + _parameterBuilderType.GetField("_methodBuilder", BindingFlags.NonPublic | BindingFlags.Instance) ?? throw new InvalidOperationException()), + _parameterBuilderParameter) + .Compile(); + + static readonly Func _getParameterMetadataTokenFunc = Expression.Lambda>( + Expression.Field( + Expression.ConvertChecked(_parameterBuilderParameter, _parameterBuilderType), + _parameterBuilderType.GetField("_token", BindingFlags.NonPublic | BindingFlags.Instance) ?? throw new InvalidOperationException()), + _parameterBuilderParameter) + .Compile(); + +#else + + static readonly Type _eventBuilderType = typeof(EventBuilder).Assembly.GetType("System.Reflection.Emit.EventBuilder", true)!; + static readonly Type _parameterBuilderType = typeof(ParameterBuilder).Assembly.GetType("System.Reflection.Emit.ParameterBuilder", true)!; + + static readonly Func _getParameterMethodBuilderFunc = Expression.Lambda>( + Expression.Field( + Expression.ConvertChecked(_parameterBuilderParameter, _parameterBuilderType), + _parameterBuilderType.GetField("m_methodBuilder", BindingFlags.NonPublic | BindingFlags.Instance) ?? throw new InvalidOperationException()), + _parameterBuilderParameter) + .Compile(); + +#endif + + static readonly Func _getEventModuleBuilderFunc = Expression.Lambda>( + Expression.Field( + Expression.ConvertChecked(_eventBuilderParameter, _eventBuilderType), + _eventBuilderType.GetField("m_module", BindingFlags.NonPublic | BindingFlags.Instance) ?? throw new InvalidOperationException()), + _eventBuilderParameter) + .Compile(); + + static readonly Func _getEventTypeBuilderFunc = Expression.Lambda>( + Expression.Field( + Expression.ConvertChecked(_eventBuilderParameter, _eventBuilderType), + _eventBuilderType.GetField("m_type", BindingFlags.NonPublic | BindingFlags.Instance) ?? throw new InvalidOperationException()), + _eventBuilderParameter) + .Compile(); + + static readonly Func _getEventNameFunc = Expression.Lambda>( + Expression.Field( + Expression.ConvertChecked(_eventBuilderParameter, _eventBuilderType), + _eventBuilderType.GetField("m_name", BindingFlags.NonPublic | BindingFlags.Instance) ?? throw new InvalidOperationException()), + _eventBuilderParameter) + .Compile(); + + static readonly Func _getEventAttributesFunc = Expression.Lambda>( + Expression.ConvertChecked( + Expression.Field( + Expression.ConvertChecked(_eventBuilderParameter, _eventBuilderType), + _eventBuilderType.GetField("m_attributes", BindingFlags.NonPublic | BindingFlags.Instance) ?? throw new InvalidOperationException()), + typeof(EventAttributes)), + _eventBuilderParameter) + .Compile(); + + /// + /// Gets the metadata token for the specified . + /// + /// + /// + public static int GetMetadataTokenSafe(this Type type) + { +#if NETFRAMEWORK + if (type is TypeBuilder b) + { + var t = b.TypeToken.Token; + if (t == 0) + throw new InvalidOperationException(); + + return t; + } +#endif + + return type.GetMetadataToken(); + } + + /// + /// Gets the metadata row number for the specified . + /// + /// + /// + public static int GetMetadataTokenRowNumberSafe(this Type type) + { + return MetadataTokens.GetRowNumber(MetadataTokens.TypeDefinitionHandle(type.GetMetadataTokenSafe())); + } + + /// + /// Gets the metadata token for the specified . + /// + /// + /// + public static int GetMetadataTokenSafe(this FieldInfo field) + { +#if NETFRAMEWORK + if (field is FieldBuilder b) + { + var t = b.GetToken().Token; + if (t == 0) + throw new InvalidOperationException(); + + return t; + } +#endif + + return field.GetMetadataToken(); + } + + /// + /// Gets the metadata row number for the specified . + /// + /// + /// + public static int GetMetadataTokenRowNumberSafe(this FieldInfo field) + { + return MetadataTokens.GetRowNumber(MetadataTokens.FieldDefinitionHandle(field.GetMetadataTokenSafe())); + } + + /// + /// Gets the metadata token for the specified . + /// + /// + /// + /// + public static int GetMetadataTokenSafe(this MethodBase method) + { + return method switch + { + ConstructorInfo c => c.GetMetadataTokenSafe(), + MethodInfo m => m.GetMetadataTokenSafe(), + _ => throw new InvalidOperationException(), + }; + } + + /// + /// Gets the metadata row number for the specified . + /// + /// + /// + /// + public static int GetMetadataTokenRowNumberSafe(this MethodBase method) + { + return method switch + { + ConstructorInfo c => c.GetMetadataTokenRowNumberSafe(), + MethodInfo m => m.GetMetadataTokenRowNumberSafe(), + _ => throw new InvalidOperationException(), + }; + } + + /// + /// Gets the metadata token for the specified . + /// + /// + /// + public static int GetMetadataTokenSafe(this ConstructorInfo ctor) + { +#if NETFRAMEWORK + if (ctor is ConstructorBuilder b) + { + var t = b.GetToken().Token; + if (t == 0) + throw new InvalidOperationException(); + + return t; + } +#endif + + return ctor.GetMetadataToken(); + } + + /// + /// Gets the metadata row number for the specified . + /// + /// + /// + public static int GetMetadataTokenRowNumberSafe(this ConstructorInfo ctor) + { + return MetadataTokens.GetRowNumber(MetadataTokens.MethodDefinitionHandle(ctor.GetMetadataTokenSafe())); + } + + /// + /// Gets the metadata token for the specified . + /// + /// + /// + public static int GetMetadataTokenSafe(this MethodInfo method) + { +#if NETFRAMEWORK + if (method is MethodBuilder b) + { + var t = b.GetToken().Token; + if (t == 0) + throw new InvalidOperationException(); + + return t; + } +#endif + + return method.GetMetadataToken(); + } + + /// + /// Gets the metadata row number for the specified . + /// + /// + /// + public static int GetMetadataTokenRowNumberSafe(this MethodInfo ctor) + { + return MetadataTokens.GetRowNumber(MetadataTokens.MethodDefinitionHandle(ctor.GetMetadataTokenSafe())); + } + + /// + /// Gets the metadata token for the specified . + /// + /// + /// + /// + public static int GetMetadataTokenSafe(this PropertyInfo property) + { + if (property is PropertyBuilder b) + { +#if NETFRAMEWORK + var t = b.PropertyToken.Token; +#else + var t = _getPropertyMetadataTokenFunc(b); +#endif + if (t == 0) + throw new InvalidOperationException(); + + return t; + } + + return property.GetMetadataToken(); + } + + /// + /// Gets the metadata row number for the specified . + /// + /// + /// + public static int GetMetadataTokenRowNumberSafe(this PropertyInfo property) + { + return MetadataTokens.GetRowNumber(MetadataTokens.PropertyDefinitionHandle(property.GetMetadataTokenSafe())); + } + + /// + /// Gets the metadata token for the specified . + /// + /// + /// + /// + public static int GetMetadataTokenSafe(this EventInfo @event) + { + if (@event is ReflectionEventBuilderInfo b) + { + var t = b.GetMetadataToken(); + if (t == 0) + throw new InvalidOperationException(); + } + + return @event.GetMetadataToken(); + } + + /// + /// Gets the metadata row number for the specified . + /// + /// + /// + public static int GetMetadataTokenRowNumberSafe(this EventInfo @event) + { + return MetadataTokens.GetRowNumber(MetadataTokens.EventDefinitionHandle(@event.GetMetadataTokenSafe())); + } + + /// + /// Gets the metadata token for the specified . + /// + /// + /// + /// + /// + public static int GetMetadataToken(this EventBuilder @event) + { +#if NETFRAMEWORK + return @event.GetEventToken().Token; +#else + return _getEventMetadataTokenFunc(@event); +#endif + } + + /// + /// Gets the metadata token for the specified . + /// + /// + /// + /// + /// + public static int GetMetadataTokenSafe(this EventBuilder @event) + { + var t = GetMetadataToken(@event); + if (t == 0) + throw new InvalidOperationException(); + + return t; + } + + /// + /// Gets the metadata row number for the specified . + /// + /// + /// + public static int GetMetadataTokenRowNumberSafe(this EventBuilder @event) + { + return MetadataTokens.GetRowNumber(MetadataTokens.EventDefinitionHandle(@event.GetMetadataTokenSafe())); + } + + /// + /// Gets the metadata token for the specified . + /// + /// + /// + /// + public static int GetMetadataTokenSafe(this ParameterInfo parameter) + { + var t = parameter.MetadataToken; + if (t == 0) + throw new InvalidOperationException(); + + return t; + } + + /// + /// Gets the metadata row number for the specified . + /// + /// + /// + public static int GetMetadataTokenRowNumberSafe(this ParameterInfo parameter) + { + return MetadataTokens.GetRowNumber(MetadataTokens.ParameterHandle(parameter.GetMetadataTokenSafe())); + } + + /// + /// Gets the metadata token for the specified . + /// + /// + /// + /// + /// + public static int GetMetadataToken(this ParameterBuilder parameter) + { +#if NETFRAMEWORK + return parameter.GetToken().Token; +#else + return _getParameterMetadataTokenFunc(parameter); +#endif + } + + /// + /// Gets the associated with a . + /// + /// + /// + public static ModuleBuilder GetModuleBuilder(this EventBuilder @event) + { + return _getEventModuleBuilderFunc(@event); + } + + /// + /// Gets the associated with a . + /// + /// + /// + public static TypeBuilder GetTypeBuilder(this EventBuilder @event) + { + return _getEventTypeBuilderFunc(@event); + } + + /// + /// Gets the name associated with a . + /// + /// + /// + public static string GetEventName(this EventBuilder @event) + { + return _getEventNameFunc(@event); + } + + /// + /// Gets the attributes associated with a . + /// + /// + /// + public static EventAttributes GetEventAttributes(this EventBuilder @event) + { + return _getEventAttributesFunc(@event); + } + + /// + /// Gets the associated with a . + /// + /// + /// + public static MemberInfo GetMethodBuilder(this ParameterBuilder parameter) + { + return _getParameterMethodBuilderFunc(parameter); + } + + } + +} \ No newline at end of file diff --git a/src/IKVM.CoreLib/Threading/ReaderWriterLockSlimExtensions.cs b/src/IKVM.CoreLib/Threading/ReaderWriterLockSlimExtensions.cs new file mode 100644 index 000000000..4d41fc658 --- /dev/null +++ b/src/IKVM.CoreLib/Threading/ReaderWriterLockSlimExtensions.cs @@ -0,0 +1,99 @@ +using System; +using System.Threading; + +namespace IKVM.CoreLib.Threading +{ + + static class ReaderWriterLockSlimExtensions + { + + public readonly struct ReaderWriterLockSlimReadLock : IDisposable + { + + readonly ReaderWriterLockSlim @lock; + + /// + /// Initializes a new instance. + /// + /// + /// + public ReaderWriterLockSlimReadLock(ReaderWriterLockSlim @lock) + { + this.@lock = @lock ?? throw new ArgumentNullException(nameof(@lock)); + @lock.EnterReadLock(); + } + + /// + public readonly void Dispose() + { + @lock.ExitReadLock(); + } + + } + + public readonly struct ReaderWriterLockSlimUpradeableReadLock : IDisposable + { + + readonly ReaderWriterLockSlim @lock; + + /// + /// Initializes a new instance. + /// + /// + /// + public ReaderWriterLockSlimUpradeableReadLock(ReaderWriterLockSlim @lock) + { + this.@lock = @lock ?? throw new ArgumentNullException(nameof(@lock)); + @lock.EnterUpgradeableReadLock(); + } + + /// + public readonly void Dispose() + { + @lock.ExitUpgradeableReadLock(); + } + + } + + public readonly struct ReaderWriterLockSlimWriteLock : IDisposable + { + + readonly ReaderWriterLockSlim @lock; + + /// + /// Initializes a new instance. + /// + /// + /// + public ReaderWriterLockSlimWriteLock(ReaderWriterLockSlim @lock) + { + this.@lock = @lock ?? throw new ArgumentNullException(nameof(@lock)); + @lock.EnterWriteLock(); + } + + /// + public readonly void Dispose() + { + @lock.ExitWriteLock(); + } + + } + + public static ReaderWriterLockSlimReadLock CreateReadLock(this ReaderWriterLockSlim @lock) + { + return new ReaderWriterLockSlimReadLock(@lock); + } + + public static ReaderWriterLockSlimUpradeableReadLock CreateUpgradeableReadLock(this ReaderWriterLockSlim @lock) + { + return new ReaderWriterLockSlimUpradeableReadLock(@lock); + } + + public static ReaderWriterLockSlimWriteLock CreateWriteLock(this ReaderWriterLockSlim @lock) + { + return new ReaderWriterLockSlimWriteLock(@lock); + } + + } + +} diff --git a/src/IKVM.Reflection/ArrayType.cs b/src/IKVM.Reflection/ArrayType.cs index 78f02ab4f..e53eafac8 100644 --- a/src/IKVM.Reflection/ArrayType.cs +++ b/src/IKVM.Reflection/ArrayType.cs @@ -69,7 +69,7 @@ public override MethodBase[] __GetDeclaredMethods() list.Add(new BuiltinArrayMethod(Module, this, "Get", CallingConventions.Standard | CallingConventions.HasThis, elementType, int32)); list.Add(new ConstructorInfoImpl(new BuiltinArrayMethod(Module, this, ".ctor", CallingConventions.Standard | CallingConventions.HasThis, Module.Universe.System_Void, int32))); - for (var type = elementType; type.__IsVector; type = type.GetElementType()) + for (var type = elementType; type.IsSZArray; type = type.GetElementType()) { Array.Resize(ref int32, int32.Length + 1); int32[int32.Length - 1] = int32[0]; diff --git a/src/IKVM.Reflection/CustomAttributeData.cs b/src/IKVM.Reflection/CustomAttributeData.cs index 7ac1afeb9..fa7754c62 100644 --- a/src/IKVM.Reflection/CustomAttributeData.cs +++ b/src/IKVM.Reflection/CustomAttributeData.cs @@ -435,11 +435,9 @@ static Type ReadType(Module context, ByteReader br) if (typeName == null) return null; + // there are broken compilers that emit an extra NUL character after the type name if (typeName.Length > 0 && typeName[typeName.Length - 1] == 0) - { - // there are broken compilers that emit an extra NUL character after the type name typeName = typeName.Substring(0, typeName.Length - 1); - } return TypeNameParser.Parse(typeName, true).GetType(context.Universe, context, true, typeName, true, false); } diff --git a/src/IKVM.Reflection/Emit/ModuleBuilder.cs b/src/IKVM.Reflection/Emit/ModuleBuilder.cs index d00b52c81..2f540520e 100644 --- a/src/IKVM.Reflection/Emit/ModuleBuilder.cs +++ b/src/IKVM.Reflection/Emit/ModuleBuilder.cs @@ -978,7 +978,7 @@ internal int ImportType(Type type) { if (typeTokens.TryGetValue(type, out var token) == false) { - if (type.HasElementType || type.IsConstructedGenericType || type.__IsFunctionPointer) + if (type.HasElementType || type.IsConstructedGenericType || type.IsFunctionPointer) { var spec = new ByteBuffer(5); Signature.WriteTypeSpec(this, spec, type); diff --git a/src/IKVM.Reflection/Signature.cs b/src/IKVM.Reflection/Signature.cs index 2af7852d2..7f1e3dd74 100644 --- a/src/IKVM.Reflection/Signature.cs +++ b/src/IKVM.Reflection/Signature.cs @@ -378,7 +378,7 @@ protected static void WriteType(ModuleBuilder module, ByteBuffer bb, Type type) { WriteGenericSignature(module, bb, type); } - else if (type.__IsFunctionPointer) + else if (type.IsFunctionPointer) { bb.Write(ELEMENT_TYPE_FNPTR); WriteStandAloneMethodSig(module, bb, type.__MethodSignature); diff --git a/src/IKVM.Reflection/Type.cs b/src/IKVM.Reflection/Type.cs index 839e48e33..4d90961cf 100644 --- a/src/IKVM.Reflection/Type.cs +++ b/src/IKVM.Reflection/Type.cs @@ -200,7 +200,7 @@ public bool IsArray get { return sigElementType == Signature.ELEMENT_TYPE_ARRAY || sigElementType == Signature.ELEMENT_TYPE_SZARRAY; } } - public bool __IsVector + public bool IsSZArray { get { return sigElementType == Signature.ELEMENT_TYPE_SZARRAY; } } @@ -215,11 +215,16 @@ public bool IsPointer get { return sigElementType == Signature.ELEMENT_TYPE_PTR; } } - public bool __IsFunctionPointer + public bool IsFunctionPointer { get { return sigElementType == Signature.ELEMENT_TYPE_FNPTR; } } + public bool IsUnmanagedFunctionPointer + { + get { throw new NotSupportedException(); } + } + public bool IsValueType { get @@ -1173,7 +1178,7 @@ internal byte SigElementType get { // this property can only be called after __IsBuiltIn, HasElementType, __IsFunctionPointer or IsGenericParameter returned true - System.Diagnostics.Debug.Assert((typeFlags & TypeFlags.BuiltIn) != 0 || HasElementType || __IsFunctionPointer || IsGenericParameter); + System.Diagnostics.Debug.Assert((typeFlags & TypeFlags.BuiltIn) != 0 || HasElementType || IsFunctionPointer || IsGenericParameter); return sigElementType; } } @@ -1642,7 +1647,7 @@ public bool IsAssignableFrom(Type type) { return false; } - else if (this.__IsVector && !type.__IsVector) + else if (this.IsSZArray && !type.IsSZArray) { return false; } diff --git a/src/IKVM.Runtime/Annotation.cs b/src/IKVM.Runtime/Annotation.cs index 5ceea4735..9a53b8cb6 100644 --- a/src/IKVM.Runtime/Annotation.cs +++ b/src/IKVM.Runtime/Annotation.cs @@ -25,27 +25,15 @@ Jeroen Frijters using System.Diagnostics; using IKVM.Attributes; - - +using IKVM.CoreLib.Symbols; #if IMPORTER || EXPORTER -using IKVM.Reflection; using IKVM.Reflection.Emit; - -using Type = IKVM.Reflection.Type; - -using System.Collections; -using System.Collections.Generic; - #else using System.Reflection; using System.Reflection.Emit; #endif -#if IMPORTER -using IKVM.Tools.Importer; -#endif - namespace IKVM.Runtime { @@ -119,49 +107,47 @@ internal static Annotation Load(RuntimeJavaType owner, object[] def) #endif - private static object LookupEnumValue(RuntimeContext context, Type enumType, string value) + static object LookupEnumValue(RuntimeContext context, ITypeSymbol enumType, string value) { - FieldInfo field = enumType.GetField(value, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); + var field = enumType.GetField(value, System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic); if (field != null) - { return field.GetRawConstantValue(); - } + // both __unspecified and missing values end up here - return EnumHelper.GetPrimitiveValue(context, EnumHelper.GetUnderlyingType(enumType), 0); + return EnumHelper.GetPrimitiveValue(context, enumType.GetEnumUnderlyingType(), 0); } - protected static object ConvertValue(RuntimeClassLoader loader, Type targetType, object obj) + protected static object ConvertValue(RuntimeClassLoader loader, ITypeSymbol targetType, object obj) { if (targetType.IsEnum) { // TODO check the obj descriptor matches the type we expect if (((object[])obj)[0].Equals(AnnotationDefaultAttribute.TAG_ARRAY)) { - object[] arr = (object[])obj; + var arr = (object[])obj; + object value = null; for (int i = 1; i < arr.Length; i++) { // TODO check the obj descriptor matches the type we expect - string s = ((object[])arr[i])[2].ToString(); - object newval = LookupEnumValue(loader.Context, targetType, s); + var s = ((object[])arr[i])[2].ToString(); + var newval = LookupEnumValue(loader.Context, targetType, s); if (value == null) - { value = newval; - } else - { value = EnumHelper.OrBoxedIntegrals(loader.Context, value, newval); - } } + return value; } else { - string s = ((object[])obj)[2].ToString(); + var s = ((object[])obj)[2].ToString(); if (s == "__unspecified") { // TODO we should probably return null and handle that } + return LookupEnumValue(loader.Context, targetType, s); } } @@ -173,13 +159,12 @@ protected static object ConvertValue(RuntimeClassLoader loader, Type targetType, else if (targetType.IsArray) { // TODO check the obj descriptor matches the type we expect - object[] arr = (object[])obj; - Type elementType = targetType.GetElementType(); - object[] targetArray = new object[arr.Length - 1]; + var arr = (object[])obj; + var elementType = targetType.GetElementType(); + var targetArray = new object[arr.Length - 1]; for (int i = 1; i < arr.Length; i++) - { targetArray[i - 1] = ConvertValue(loader, elementType, arr[i]); - } + return targetArray; } else diff --git a/src/IKVM.Runtime/AttributeHelper.cs b/src/IKVM.Runtime/AttributeHelper.cs index ea8b43bab..12e0e0bbc 100644 --- a/src/IKVM.Runtime/AttributeHelper.cs +++ b/src/IKVM.Runtime/AttributeHelper.cs @@ -32,6 +32,7 @@ Jeroen Frijters using IKVM.ByteCode.Buffers; using IKVM.ByteCode.Decoding; using IKVM.ByteCode.Encoding; +using IKVM.CoreLib.Symbols; #if IMPORTER || EXPORTER using IKVM.Reflection; @@ -60,125 +61,125 @@ class AttributeHelper #if IMPORTER - CustomAttributeBuilder compilerGeneratedAttribute; - CustomAttributeBuilder ghostInterfaceAttribute; - CustomAttributeBuilder deprecatedAttribute; - CustomAttributeBuilder editorBrowsableNever; - ConstructorInfo implementsAttribute; - ConstructorInfo throwsAttribute; - ConstructorInfo sourceFileAttribute; - ConstructorInfo lineNumberTableAttribute1; - ConstructorInfo lineNumberTableAttribute2; - ConstructorInfo enclosingMethodAttribute; - ConstructorInfo signatureAttribute; - ConstructorInfo methodParametersAttribute; - ConstructorInfo runtimeVisibleTypeAnnotationsAttribute; - ConstructorInfo constantPoolAttribute; - CustomAttributeBuilder paramArrayAttribute; - ConstructorInfo nonNestedInnerClassAttribute; - ConstructorInfo nonNestedOuterClassAttribute; - - Type typeofModifiers; - Type typeofSourceFileAttribute; - Type typeofLineNumberTableAttribute; + CustomAttributeBuilder compilerGeneratedAttribute; + CustomAttributeBuilder ghostInterfaceAttribute; + CustomAttributeBuilder deprecatedAttribute; + CustomAttributeBuilder editorBrowsableNever; + IConstructorSymbol implementsAttribute; + IConstructorSymbol throwsAttribute; + IConstructorSymbol sourceFileAttribute; + IConstructorSymbol lineNumberTableAttribute1; + IConstructorSymbol lineNumberTableAttribute2; + IConstructorSymbol enclosingMethodAttribute; + IConstructorSymbol signatureAttribute; + IConstructorSymbol methodParametersAttribute; + IConstructorSymbol runtimeVisibleTypeAnnotationsAttribute; + IConstructorSymbol constantPoolAttribute; + CustomAttributeBuilder paramArrayAttribute; + IConstructorSymbol nonNestedInnerClassAttribute; + IConstructorSymbol nonNestedOuterClassAttribute; + + ITypeSymbol typeofModifiers; + ITypeSymbol typeofSourceFileAttribute; + ITypeSymbol typeofLineNumberTableAttribute; #endif - Type typeofRemappedClassAttribute; - Type typeofRemappedTypeAttribute; - Type typeofModifiersAttribute; - Type typeofRemappedInterfaceMethodAttribute; - Type typeofNameSigAttribute; - Type typeofJavaModuleAttribute; - Type typeofSignatureAttribute; - Type typeofInnerClassAttribute; - Type typeofImplementsAttribute; - Type typeofGhostInterfaceAttribute; - Type typeofExceptionIsUnsafeForMappingAttribute; - Type typeofThrowsAttribute; - Type typeofHideFromJavaAttribute; - Type typeofHideFromJavaFlags; - Type typeofNoPackagePrefixAttribute; - Type typeofAnnotationAttributeAttribute; - Type typeofNonNestedInnerClassAttribute; - Type typeofNonNestedOuterClassAttribute; - Type typeofEnclosingMethodAttribute; - Type typeofMethodParametersAttribute; - Type typeofRuntimeVisibleTypeAnnotationsAttribute; - Type typeofConstantPoolAttribute; - Type typeofDebuggableAttribute; + ITypeSymbol typeofRemappedClassAttribute; + ITypeSymbol typeofRemappedTypeAttribute; + ITypeSymbol typeofModifiersAttribute; + ITypeSymbol typeofRemappedInterfaceMethodAttribute; + ITypeSymbol typeofNameSigAttribute; + ITypeSymbol typeofJavaModuleAttribute; + ITypeSymbol typeofSignatureAttribute; + ITypeSymbol typeofInnerClassAttribute; + ITypeSymbol typeofImplementsAttribute; + ITypeSymbol typeofGhostInterfaceAttribute; + ITypeSymbol typeofExceptionIsUnsafeForMappingAttribute; + ITypeSymbol typeofThrowsAttribute; + ITypeSymbol typeofHideFromJavaAttribute; + ITypeSymbol typeofHideFromJavaFlags; + ITypeSymbol typeofNoPackagePrefixAttribute; + ITypeSymbol typeofAnnotationAttributeAttribute; + ITypeSymbol typeofNonNestedInnerClassAttribute; + ITypeSymbol typeofNonNestedOuterClassAttribute; + ITypeSymbol typeofEnclosingMethodAttribute; + ITypeSymbol typeofMethodParametersAttribute; + ITypeSymbol typeofRuntimeVisibleTypeAnnotationsAttribute; + ITypeSymbol typeofConstantPoolAttribute; + ITypeSymbol typeofDebuggableAttribute; CustomAttributeBuilder hideFromJavaAttribute; CustomAttributeBuilder hideFromReflection; - ConstructorInfo debuggableAttribute; + IConstructorSymbol debuggableAttribute; #if IMPORTER - Type TypeOfModifiers => typeofModifiers ??= LoadType(typeof(Modifiers)); + ITypeSymbol TypeOfModifiers => typeofModifiers ??= LoadType(typeof(Modifiers)); - Type TypeOfSourceFileAttribute => typeofSourceFileAttribute ??= LoadType(typeof(IKVM.Attributes.SourceFileAttribute)); + ITypeSymbol TypeOfSourceFileAttribute => typeofSourceFileAttribute ??= LoadType(typeof(IKVM.Attributes.SourceFileAttribute)); - Type TypeOfLineNumberTableAttribute => typeofLineNumberTableAttribute ??= LoadType(typeof(IKVM.Attributes.LineNumberTableAttribute)); + ITypeSymbol TypeOfLineNumberTableAttribute => typeofLineNumberTableAttribute ??= LoadType(typeof(IKVM.Attributes.LineNumberTableAttribute)); #endif - Type TypeOfRemappedClassAttribute => typeofRemappedClassAttribute ??= LoadType(typeof(RemappedClassAttribute)); + ITypeSymbol TypeOfRemappedClassAttribute => typeofRemappedClassAttribute ??= LoadType(typeof(RemappedClassAttribute)); - Type TypeOfRemappedTypeAttribute => typeofRemappedTypeAttribute ??= LoadType(typeof(RemappedTypeAttribute)); + ITypeSymbol TypeOfRemappedTypeAttribute => typeofRemappedTypeAttribute ??= LoadType(typeof(RemappedTypeAttribute)); - Type TypeOfModifiersAttribute => typeofModifiersAttribute ??= LoadType(typeof(ModifiersAttribute)); + ITypeSymbol TypeOfModifiersAttribute => typeofModifiersAttribute ??= LoadType(typeof(ModifiersAttribute)); - Type TypeOfRemappedInterfaceMethodAttribute => typeofRemappedInterfaceMethodAttribute ??= LoadType(typeof(RemappedInterfaceMethodAttribute)); + ITypeSymbol TypeOfRemappedInterfaceMethodAttribute => typeofRemappedInterfaceMethodAttribute ??= LoadType(typeof(RemappedInterfaceMethodAttribute)); - Type TypeOfNameSigAttribute => typeofNameSigAttribute ??= LoadType(typeof(NameSigAttribute)); + ITypeSymbol TypeOfNameSigAttribute => typeofNameSigAttribute ??= LoadType(typeof(NameSigAttribute)); - Type TypeOfJavaModuleAttribute => typeofJavaModuleAttribute ??= LoadType(typeof(JavaModuleAttribute)); + ITypeSymbol TypeOfJavaModuleAttribute => typeofJavaModuleAttribute ??= LoadType(typeof(JavaModuleAttribute)); - Type TypeOfSignatureAttribute => typeofSignatureAttribute ??= LoadType(typeof(IKVM.Attributes.SignatureAttribute)); + ITypeSymbol TypeOfSignatureAttribute => typeofSignatureAttribute ??= LoadType(typeof(IKVM.Attributes.SignatureAttribute)); - Type TypeOfInnerClassAttribute => typeofInnerClassAttribute ??= LoadType(typeof(InnerClassAttribute)); + ITypeSymbol TypeOfInnerClassAttribute => typeofInnerClassAttribute ??= LoadType(typeof(InnerClassAttribute)); - Type TypeOfImplementsAttribute => typeofImplementsAttribute ??= LoadType(typeof(ImplementsAttribute)); + ITypeSymbol TypeOfImplementsAttribute => typeofImplementsAttribute ??= LoadType(typeof(ImplementsAttribute)); - Type TypeOfGhostInterfaceAttribute => typeofGhostInterfaceAttribute ??= LoadType(typeof(GhostInterfaceAttribute)); + ITypeSymbol TypeOfGhostInterfaceAttribute => typeofGhostInterfaceAttribute ??= LoadType(typeof(GhostInterfaceAttribute)); - Type TypeOfExceptionIsUnsafeForMappingAttribute => typeofExceptionIsUnsafeForMappingAttribute ??= LoadType(typeof(ExceptionIsUnsafeForMappingAttribute)); + ITypeSymbol TypeOfExceptionIsUnsafeForMappingAttribute => typeofExceptionIsUnsafeForMappingAttribute ??= LoadType(typeof(ExceptionIsUnsafeForMappingAttribute)); - Type TypeOfThrowsAttribute => typeofThrowsAttribute ??= LoadType(typeof(ThrowsAttribute)); + ITypeSymbol TypeOfThrowsAttribute => typeofThrowsAttribute ??= LoadType(typeof(ThrowsAttribute)); - Type TypeOfHideFromJavaAttribute => typeofHideFromJavaAttribute ??= LoadType(typeof(HideFromJavaAttribute)); + ITypeSymbol TypeOfHideFromJavaAttribute => typeofHideFromJavaAttribute ??= LoadType(typeof(HideFromJavaAttribute)); - Type TypeOfHideFromJavaFlags => typeofHideFromJavaFlags ??= LoadType(typeof(HideFromJavaFlags)); + ITypeSymbol TypeOfHideFromJavaFlags => typeofHideFromJavaFlags ??= LoadType(typeof(HideFromJavaFlags)); - Type TypeOfNoPackagePrefixAttribute => typeofNoPackagePrefixAttribute ??= LoadType(typeof(NoPackagePrefixAttribute)); + ITypeSymbol TypeOfNoPackagePrefixAttribute => typeofNoPackagePrefixAttribute ??= LoadType(typeof(NoPackagePrefixAttribute)); - Type TypeOfAnnotationAttributeAttribute => typeofAnnotationAttributeAttribute ??= LoadType(typeof(AnnotationAttributeAttribute)); + ITypeSymbol TypeOfAnnotationAttributeAttribute => typeofAnnotationAttributeAttribute ??= LoadType(typeof(AnnotationAttributeAttribute)); - Type TypeOfNonNestedInnerClassAttribute => typeofNonNestedInnerClassAttribute ??= LoadType(typeof(NonNestedInnerClassAttribute)); + ITypeSymbol TypeOfNonNestedInnerClassAttribute => typeofNonNestedInnerClassAttribute ??= LoadType(typeof(NonNestedInnerClassAttribute)); - Type TypeOfNonNestedOuterClassAttribute => typeofNonNestedOuterClassAttribute ??= LoadType(typeof(NonNestedOuterClassAttribute)); + ITypeSymbol TypeOfNonNestedOuterClassAttribute => typeofNonNestedOuterClassAttribute ??= LoadType(typeof(NonNestedOuterClassAttribute)); - Type TypeOfEnclosingMethodAttribute => typeofEnclosingMethodAttribute ??= LoadType(typeof(IKVM.Attributes.EnclosingMethodAttribute)); + ITypeSymbol TypeOfEnclosingMethodAttribute => typeofEnclosingMethodAttribute ??= LoadType(typeof(IKVM.Attributes.EnclosingMethodAttribute)); - Type TypeOfMethodParametersAttribute => typeofMethodParametersAttribute ??= LoadType(typeof(IKVM.Attributes.MethodParametersAttribute)); + ITypeSymbol TypeOfMethodParametersAttribute => typeofMethodParametersAttribute ??= LoadType(typeof(IKVM.Attributes.MethodParametersAttribute)); - Type TypeOfRuntimeVisibleTypeAnnotationsAttribute => typeofRuntimeVisibleTypeAnnotationsAttribute ??= LoadType(typeof(IKVM.Attributes.RuntimeVisibleTypeAnnotationsAttribute)); + ITypeSymbol TypeOfRuntimeVisibleTypeAnnotationsAttribute => typeofRuntimeVisibleTypeAnnotationsAttribute ??= LoadType(typeof(IKVM.Attributes.RuntimeVisibleTypeAnnotationsAttribute)); - Type TypeOfConstantPoolAttribute => typeofConstantPoolAttribute ??= LoadType(typeof(ConstantPoolAttribute)); + ITypeSymbol TypeOfConstantPoolAttribute => typeofConstantPoolAttribute ??= LoadType(typeof(ConstantPoolAttribute)); - Type TypeOfDebuggableAttribute => typeofDebuggableAttribute ??= context.Resolver.ResolveCoreType(typeof(DebuggableAttribute).FullName).AsReflection(); + ITypeSymbol TypeOfDebuggableAttribute => typeofDebuggableAttribute ??= context.Resolver.ResolveCoreType(typeof(DebuggableAttribute).FullName); - CustomAttributeBuilder HideFromJavaAttributeBuilder => hideFromJavaAttribute ??= new CustomAttributeBuilder(TypeOfHideFromJavaAttribute.GetConstructor(Type.EmptyTypes), Array.Empty()); + CustomAttributeBuilder HideFromJavaAttributeBuilder => hideFromJavaAttribute ??= new CustomAttributeBuilder(TypeOfHideFromJavaAttribute.GetConstructor([]).AsReflection(), []); - CustomAttributeBuilder HideFromReflectionBuilder => hideFromReflection ??= new CustomAttributeBuilder(TypeOfHideFromJavaAttribute.GetConstructor(new[] { TypeOfHideFromJavaFlags }), new object[] { HideFromJavaFlags.Reflection | HideFromJavaFlags.StackTrace | HideFromJavaFlags.StackWalk }); + CustomAttributeBuilder HideFromReflectionBuilder => hideFromReflection ??= new CustomAttributeBuilder(TypeOfHideFromJavaAttribute.GetConstructor([TypeOfHideFromJavaFlags]).AsReflection(), [HideFromJavaFlags.Reflection | HideFromJavaFlags.StackTrace | HideFromJavaFlags.StackWalk]); /// /// Loads the given managed type from the runtime assembly. /// /// /// - Type LoadType(System.Type t) + ITypeSymbol LoadType(System.Type t) { - return context.Resolver.ResolveRuntimeType(t.FullName).AsReflection(); + return context.Resolver.ResolveRuntimeType(t.FullName); } /// @@ -192,314 +193,302 @@ public AttributeHelper(RuntimeContext context) #if IMPORTER - object ParseValue(RuntimeClassLoader loader, RuntimeJavaType tw, string val) - { - if (tw == context.JavaBase.TypeOfJavaLangString) - { - return val; - } - else if (tw.IsUnloadable) - { - throw new FatalCompilerErrorException(DiagnosticEvent.MapFileTypeNotFound(tw.Name)); - } - else if (tw.TypeAsTBD.IsEnum) - { - return EnumHelper.Parse(context, tw.TypeAsTBD, val); - } - else if (tw.TypeAsTBD == context.Types.Type) - { - var valtw = loader.TryLoadClassByName(val); - if (valtw != null) - return valtw.TypeAsBaseType; - - return context.StaticCompiler.Universe.GetType(val, true); - } - else if (tw == context.PrimitiveJavaTypeFactory.BOOLEAN) - { - return bool.Parse(val); - } - else if (tw == context.PrimitiveJavaTypeFactory.BYTE) - { - return (byte)sbyte.Parse(val); - } - else if (tw == context.PrimitiveJavaTypeFactory.CHAR) - { - return char.Parse(val); - } - else if (tw == context.PrimitiveJavaTypeFactory.SHORT) - { - return short.Parse(val); - } - else if (tw == context.PrimitiveJavaTypeFactory.INT) - { - return int.Parse(val); - } - else if (tw == context.PrimitiveJavaTypeFactory.FLOAT) - { - return float.Parse(val); - } - else if (tw == context.PrimitiveJavaTypeFactory.LONG) - { - return long.Parse(val); - } - else if (tw == context.PrimitiveJavaTypeFactory.DOUBLE) - { - return double.Parse(val); - } - else - { - throw new NotImplementedException(); - } - } - - internal void SetCustomAttribute(RuntimeClassLoader loader, TypeBuilder tb, IKVM.Tools.Importer.MapXml.Attribute attr) - { - tb.SetCustomAttribute(CreateCustomAttribute(loader, attr)); - } - - internal void SetCustomAttribute(RuntimeClassLoader loader, FieldBuilder fb, IKVM.Tools.Importer.MapXml.Attribute attr) - { - fb.SetCustomAttribute(CreateCustomAttribute(loader, attr)); - } - - internal void SetCustomAttribute(RuntimeClassLoader loader, ParameterBuilder pb, IKVM.Tools.Importer.MapXml.Attribute attr) - { - pb.SetCustomAttribute(CreateCustomAttribute(loader, attr)); - } - - internal void SetCustomAttribute(RuntimeClassLoader loader, MethodBuilder mb, IKVM.Tools.Importer.MapXml.Attribute attr) - { - mb.SetCustomAttribute(CreateCustomAttribute(loader, attr)); - } - - internal void SetCustomAttribute(RuntimeClassLoader loader, PropertyBuilder pb, IKVM.Tools.Importer.MapXml.Attribute attr) - { - pb.SetCustomAttribute(CreateCustomAttribute(loader, attr)); - } - - internal void SetCustomAttribute(RuntimeClassLoader loader, AssemblyBuilder ab, IKVM.Tools.Importer.MapXml.Attribute attr) - { - ab.SetCustomAttribute(CreateCustomAttribute(loader, attr)); - } - - void GetAttributeArgsAndTypes(RuntimeClassLoader loader, IKVM.Tools.Importer.MapXml.Attribute attr, out Type[] argTypes, out object[] args) - { - // TODO add error handling - var twargs = loader.ArgJavaTypeListFromSig(attr.Sig, LoadMode.Link); - argTypes = new Type[twargs.Length]; - args = new object[argTypes.Length]; - for (int i = 0; i < twargs.Length; i++) - { - argTypes[i] = twargs[i].TypeAsSignatureType; - RuntimeJavaType tw = twargs[i]; - if (tw == context.JavaBase.TypeOfJavaLangObject) - { - tw = loader.FieldTypeWrapperFromSig(attr.Params[i].Sig, LoadMode.Link); - } - if (tw.IsArray) - { - Array arr = Array.CreateInstance(Type.__GetSystemType(Type.GetTypeCode(tw.ElementTypeWrapper.TypeAsArrayType)), attr.Params[i].Elements.Length); - for (int j = 0; j < arr.Length; j++) - { - arr.SetValue(ParseValue(loader, tw.ElementTypeWrapper, attr.Params[i].Elements[j].Value), j); - } - args[i] = arr; - } - else - { - args[i] = ParseValue(loader, tw, attr.Params[i].Value); - } - } - } - - CustomAttributeBuilder CreateCustomAttribute(RuntimeClassLoader loader, IKVM.Tools.Importer.MapXml.Attribute attr) - { - // TODO add error handling - Type[] argTypes; - object[] args; - GetAttributeArgsAndTypes(loader, attr, out argTypes, out args); - if (attr.Type != null) - { - var t = context.Resolver.ResolveCoreType(attr.Type).AsReflection(); - var ci = t.GetConstructor(argTypes); - if (ci == null) - throw new InvalidOperationException($"Constructor missing: {attr.Type}::{attr.Sig}"); - - PropertyInfo[] namedProperties; - object[] propertyValues; - if (attr.Properties != null) - { - namedProperties = new PropertyInfo[attr.Properties.Length]; - propertyValues = new object[attr.Properties.Length]; - for (int i = 0; i < namedProperties.Length; i++) - { - namedProperties[i] = t.GetProperty(attr.Properties[i].Name); - propertyValues[i] = ParseValue(loader, loader.FieldTypeWrapperFromSig(attr.Properties[i].Sig, LoadMode.Link), attr.Properties[i].Value); - } - } - else - { - namedProperties = new PropertyInfo[0]; - propertyValues = new object[0]; - } - FieldInfo[] namedFields; - object[] fieldValues; - if (attr.Fields != null) - { - namedFields = new FieldInfo[attr.Fields.Length]; - fieldValues = new object[attr.Fields.Length]; - for (int i = 0; i < namedFields.Length; i++) - { - namedFields[i] = t.GetField(attr.Fields[i].Name); - fieldValues[i] = ParseValue(loader, loader.FieldTypeWrapperFromSig(attr.Fields[i].Sig, LoadMode.Link), attr.Fields[i].Value); - } - } - else - { - namedFields = new FieldInfo[0]; - fieldValues = new object[0]; - } - return new CustomAttributeBuilder(ci, args, namedProperties, propertyValues, namedFields, fieldValues); - } - else - { - if (attr.Properties != null) - { - throw new NotImplementedException("Setting property values on Java attributes is not implemented"); - } - RuntimeJavaType t = loader.LoadClassByName(attr.Class); - FieldInfo[] namedFields; - object[] fieldValues; - if (attr.Fields != null) - { - namedFields = new FieldInfo[attr.Fields.Length]; - fieldValues = new object[attr.Fields.Length]; - for (int i = 0; i < namedFields.Length; i++) - { - RuntimeJavaField fw = t.GetFieldWrapper(attr.Fields[i].Name, attr.Fields[i].Sig); - fw.Link(); - namedFields[i] = fw.GetField(); - fieldValues[i] = ParseValue(loader, loader.FieldTypeWrapperFromSig(attr.Fields[i].Sig, LoadMode.Link), attr.Fields[i].Value); - } - } - else - { - namedFields = new FieldInfo[0]; - fieldValues = new object[0]; - } - var mw = t.GetMethodWrapper("", attr.Sig, false); - if (mw == null) - { - throw new InvalidOperationException(string.Format("Constructor missing: {0}::{1}", attr.Class, attr.Sig)); - } - mw.Link(); - ConstructorInfo ci = (mw.GetMethod() as ConstructorInfo) ?? ((MethodInfo)mw.GetMethod()).__AsConstructorInfo(); - return new CustomAttributeBuilder(ci, args, namedFields, fieldValues); - } - } - - CustomAttributeBuilder GetEditorBrowsableNever() - { - if (editorBrowsableNever == null) - { - var typeofEditorBrowsableAttribute = context.Resolver.ResolveCoreType(typeof(EditorBrowsableAttribute).FullName).AsReflection(); - var typeofEditorBrowsableState = context.Resolver.ResolveCoreType(typeof(EditorBrowsableState).FullName).AsReflection(); - var ctor = (ConstructorInfo)typeofEditorBrowsableAttribute.__CreateMissingMethod(ConstructorInfo.ConstructorName, CallingConventions.Standard | CallingConventions.HasThis, null, default, new Type[] { typeofEditorBrowsableState }, null); - editorBrowsableNever = CustomAttributeBuilder.__FromBlob(ctor, new byte[] { 01, 00, 01, 00, 00, 00, 00, 00 }); - } - - return editorBrowsableNever; - } - - internal void SetCompilerGenerated(TypeBuilder tb) - { - compilerGeneratedAttribute ??= new CustomAttributeBuilder(context.Resolver.ResolveCoreType(typeof(CompilerGeneratedAttribute).FullName).AsReflection().GetConstructor(Type.EmptyTypes), Array.Empty()); - tb.SetCustomAttribute(compilerGeneratedAttribute); - } - - internal void SetCompilerGenerated(MethodBuilder mb) - { - compilerGeneratedAttribute ??= new CustomAttributeBuilder(context.Resolver.ResolveCoreType(typeof(CompilerGeneratedAttribute).FullName).AsReflection().GetConstructor(Type.EmptyTypes), Array.Empty()); - mb.SetCustomAttribute(compilerGeneratedAttribute); - } - - internal void SetEditorBrowsableNever(TypeBuilder tb) - { - tb.SetCustomAttribute(GetEditorBrowsableNever()); - } - - internal void SetEditorBrowsableNever(MethodBuilder mb) - { - mb.SetCustomAttribute(GetEditorBrowsableNever()); - } - - internal void SetEditorBrowsableNever(PropertyBuilder pb) - { - pb.SetCustomAttribute(GetEditorBrowsableNever()); - } - - internal void SetDeprecatedAttribute(MethodBuilder mb) - { - if (deprecatedAttribute == null) - deprecatedAttribute = new CustomAttributeBuilder(context.Resolver.ResolveCoreType(typeof(ObsoleteAttribute).FullName).GetConstructor([]).AsReflection(), []); - - mb.SetCustomAttribute(deprecatedAttribute); - } - - internal void SetDeprecatedAttribute(TypeBuilder tb) - { - if (deprecatedAttribute == null) - { - deprecatedAttribute = new CustomAttributeBuilder(context.Resolver.ResolveCoreType(typeof(ObsoleteAttribute).FullName).GetConstructor([]).AsReflection(), []); - } - - tb.SetCustomAttribute(deprecatedAttribute); - } - - internal void SetDeprecatedAttribute(FieldBuilder fb) - { - if (deprecatedAttribute == null) - deprecatedAttribute = new CustomAttributeBuilder(context.Resolver.ResolveCoreType(typeof(ObsoleteAttribute).FullName).GetConstructor([]).AsReflection(), new object[0]); - - fb.SetCustomAttribute(deprecatedAttribute); - } - - internal void SetDeprecatedAttribute(PropertyBuilder pb) - { - if (deprecatedAttribute == null) - { - deprecatedAttribute = new CustomAttributeBuilder(context.Resolver.ResolveCoreType(typeof(ObsoleteAttribute).FullName).GetConstructor([]).AsReflection(), new object[0]); - } - pb.SetCustomAttribute(deprecatedAttribute); - } - - internal void SetThrowsAttribute(MethodBuilder mb, string[] exceptions) - { - if (exceptions != null && exceptions.Length != 0) - { - throwsAttribute ??= TypeOfThrowsAttribute.GetConstructor(new Type[] { context.Resolver.ResolveCoreType(typeof(string).FullName).MakeArrayType().AsReflection() }); - exceptions = UnicodeUtil.EscapeInvalidSurrogates(exceptions); - mb.SetCustomAttribute(new CustomAttributeBuilder(throwsAttribute, new object[] { exceptions })); - } - } - - internal void SetGhostInterface(TypeBuilder typeBuilder) - { - ghostInterfaceAttribute ??= new CustomAttributeBuilder(TypeOfGhostInterfaceAttribute.GetConstructor(Type.EmptyTypes), new object[0]); - typeBuilder.SetCustomAttribute(ghostInterfaceAttribute); - } - - internal void SetNonNestedInnerClass(TypeBuilder typeBuilder, string className) - { - nonNestedInnerClassAttribute ??= TypeOfNonNestedInnerClassAttribute.GetConstructor(new Type[] { context.Types.String }); - typeBuilder.SetCustomAttribute(new CustomAttributeBuilder(nonNestedInnerClassAttribute, new object[] { UnicodeUtil.EscapeInvalidSurrogates(className) })); - } - - internal void SetNonNestedOuterClass(TypeBuilder typeBuilder, string className) - { - nonNestedOuterClassAttribute ??= TypeOfNonNestedOuterClassAttribute.GetConstructor(new Type[] { context.Types.String }); - typeBuilder.SetCustomAttribute(new CustomAttributeBuilder(nonNestedOuterClassAttribute, new object[] { UnicodeUtil.EscapeInvalidSurrogates(className) })); - } + object ParseValue(RuntimeClassLoader loader, RuntimeJavaType tw, string val) + { + if (tw == context.JavaBase.TypeOfJavaLangString) + { + return val; + } + else if (tw.IsUnloadable) + { + throw new FatalCompilerErrorException(DiagnosticEvent.MapFileTypeNotFound(tw.Name)); + } + else if (tw.TypeAsTBD.IsEnum) + { + return EnumHelper.Parse(context, tw.TypeAsTBD, val); + } + else if (tw.TypeAsTBD == context.Types.Type) + { + var valtw = loader.TryLoadClassByName(val); + if (valtw != null) + return valtw.TypeAsBaseType; + + return context.StaticCompiler.Universe.GetType(val, true); + } + else if (tw == context.PrimitiveJavaTypeFactory.BOOLEAN) + { + return bool.Parse(val); + } + else if (tw == context.PrimitiveJavaTypeFactory.BYTE) + { + return (byte)sbyte.Parse(val); + } + else if (tw == context.PrimitiveJavaTypeFactory.CHAR) + { + return char.Parse(val); + } + else if (tw == context.PrimitiveJavaTypeFactory.SHORT) + { + return short.Parse(val); + } + else if (tw == context.PrimitiveJavaTypeFactory.INT) + { + return int.Parse(val); + } + else if (tw == context.PrimitiveJavaTypeFactory.FLOAT) + { + return float.Parse(val); + } + else if (tw == context.PrimitiveJavaTypeFactory.LONG) + { + return long.Parse(val); + } + else if (tw == context.PrimitiveJavaTypeFactory.DOUBLE) + { + return double.Parse(val); + } + else + { + throw new NotImplementedException(); + } + } + + internal void SetCustomAttribute(RuntimeClassLoader loader, TypeBuilder tb, IKVM.Tools.Importer.MapXml.Attribute attr) + { + tb.SetCustomAttribute(CreateCustomAttribute(loader, attr)); + } + + internal void SetCustomAttribute(RuntimeClassLoader loader, FieldBuilder fb, IKVM.Tools.Importer.MapXml.Attribute attr) + { + fb.SetCustomAttribute(CreateCustomAttribute(loader, attr)); + } + + internal void SetCustomAttribute(RuntimeClassLoader loader, ParameterBuilder pb, IKVM.Tools.Importer.MapXml.Attribute attr) + { + pb.SetCustomAttribute(CreateCustomAttribute(loader, attr)); + } + + internal void SetCustomAttribute(RuntimeClassLoader loader, MethodBuilder mb, IKVM.Tools.Importer.MapXml.Attribute attr) + { + mb.SetCustomAttribute(CreateCustomAttribute(loader, attr)); + } + + internal void SetCustomAttribute(RuntimeClassLoader loader, PropertyBuilder pb, IKVM.Tools.Importer.MapXml.Attribute attr) + { + pb.SetCustomAttribute(CreateCustomAttribute(loader, attr)); + } + + internal void SetCustomAttribute(RuntimeClassLoader loader, AssemblyBuilder ab, IKVM.Tools.Importer.MapXml.Attribute attr) + { + ab.SetCustomAttribute(CreateCustomAttribute(loader, attr)); + } + + void GetAttributeArgsAndTypes(RuntimeClassLoader loader, IKVM.Tools.Importer.MapXml.Attribute attr, out ITypeSymbol[] argTypes, out object[] args) + { + // TODO add error handling + var twargs = loader.ArgJavaTypeListFromSig(attr.Sig, LoadMode.Link); + argTypes = new ITypeSymbol[twargs.Length]; + args = new object[argTypes.Length]; + for (int i = 0; i < twargs.Length; i++) + { + argTypes[i] = twargs[i].TypeAsSignatureType; + + var tw = twargs[i]; + if (tw == context.JavaBase.TypeOfJavaLangObject) + tw = loader.FieldTypeWrapperFromSig(attr.Params[i].Sig, LoadMode.Link); + + if (tw.IsArray) + { + var arr = Array.CreateInstance(Type.__GetSystemType(tw.ElementTypeWrapper.TypeAsArrayType.TypeCode), attr.Params[i].Elements.Length); + for (int j = 0; j < arr.Length; j++) + arr.SetValue(ParseValue(loader, tw.ElementTypeWrapper, attr.Params[i].Elements[j].Value), j); + + args[i] = arr; + } + else + { + args[i] = ParseValue(loader, tw, attr.Params[i].Value); + } + } + } + + CustomAttributeBuilder CreateCustomAttribute(RuntimeClassLoader loader, IKVM.Tools.Importer.MapXml.Attribute attr) + { + // TODO add error handling + GetAttributeArgsAndTypes(loader, attr, out var argTypes, out var args); + if (attr.Type != null) + { + var t = context.Resolver.ResolveCoreType(attr.Type); + var ci = t.GetConstructor(argTypes); + if (ci == null) + throw new InvalidOperationException($"Constructor missing: {attr.Type}::{attr.Sig}"); + + IPropertySymbol[] namedProperties = []; + object[] propertyValues = []; + + if (attr.Properties != null) + { + namedProperties = new IPropertySymbol[attr.Properties.Length]; + propertyValues = new object[attr.Properties.Length]; + for (int i = 0; i < namedProperties.Length; i++) + { + namedProperties[i] = t.GetProperty(attr.Properties[i].Name); + propertyValues[i] = ParseValue(loader, loader.FieldTypeWrapperFromSig(attr.Properties[i].Sig, LoadMode.Link), attr.Properties[i].Value); + } + } + + IFieldSymbol[] namedFields = []; + object[] fieldValues = []; + + if (attr.Fields != null) + { + namedFields = new IFieldSymbol[attr.Fields.Length]; + fieldValues = new object[attr.Fields.Length]; + for (int i = 0; i < namedFields.Length; i++) + { + namedFields[i] = t.GetField(attr.Fields[i].Name); + fieldValues[i] = ParseValue(loader, loader.FieldTypeWrapperFromSig(attr.Fields[i].Sig, LoadMode.Link), attr.Fields[i].Value); + } + } + + return new CustomAttributeBuilder(ci.AsReflection(), args, namedProperties.AsReflection(), propertyValues, namedFields.AsReflection(), fieldValues); + } + else + { + if (attr.Properties != null) + throw new NotImplementedException("Setting property values on Java attributes is not implemented"); + + var t = loader.LoadClassByName(attr.Class); + + IFieldSymbol[] namedFields = []; + object[] fieldValues = []; + + if (attr.Fields != null) + { + namedFields = new IFieldSymbol[attr.Fields.Length]; + fieldValues = new object[attr.Fields.Length]; + for (int i = 0; i < namedFields.Length; i++) + { + var fw = t.GetFieldWrapper(attr.Fields[i].Name, attr.Fields[i].Sig); + fw.Link(); + namedFields[i] = fw.GetField(); + fieldValues[i] = ParseValue(loader, loader.FieldTypeWrapperFromSig(attr.Fields[i].Sig, LoadMode.Link), attr.Fields[i].Value); + } + } + + var mw = t.GetMethodWrapper("", attr.Sig, false); + if (mw == null) + throw new InvalidOperationException(string.Format("Constructor missing: {0}::{1}", attr.Class, attr.Sig)); + + mw.Link(); + + var ci = (mw.GetMethod() as IConstructorSymbol) ?? ((IConstructorSymbol)mw.GetMethod()); + return new CustomAttributeBuilder(ci.AsReflection(), args, namedFields.AsReflection(), fieldValues); + } + } + + CustomAttributeBuilder GetEditorBrowsableNever() + { + if (editorBrowsableNever == null) + { + var typeofEditorBrowsableAttribute = context.Resolver.ResolveCoreType(typeof(EditorBrowsableAttribute).FullName).AsReflection(); + var typeofEditorBrowsableState = context.Resolver.ResolveCoreType(typeof(EditorBrowsableState).FullName).AsReflection(); + var ctor = (ConstructorInfo)typeofEditorBrowsableAttribute.__CreateMissingMethod(ConstructorInfo.ConstructorName, CallingConventions.Standard | CallingConventions.HasThis, null, default, new Type[] { typeofEditorBrowsableState }, null); + editorBrowsableNever = CustomAttributeBuilder.__FromBlob(ctor, new byte[] { 01, 00, 01, 00, 00, 00, 00, 00 }); + } + + return editorBrowsableNever; + } + + internal void SetCompilerGenerated(TypeBuilder tb) + { + compilerGeneratedAttribute ??= new CustomAttributeBuilder(context.Resolver.ResolveCoreType(typeof(CompilerGeneratedAttribute).FullName).AsReflection().GetConstructor([]), Array.Empty()); + tb.SetCustomAttribute(compilerGeneratedAttribute); + } + + internal void SetCompilerGenerated(MethodBuilder mb) + { + compilerGeneratedAttribute ??= new CustomAttributeBuilder(context.Resolver.ResolveCoreType(typeof(CompilerGeneratedAttribute).FullName).AsReflection().GetConstructor([]), Array.Empty()); + mb.SetCustomAttribute(compilerGeneratedAttribute); + } + + internal void SetEditorBrowsableNever(TypeBuilder tb) + { + tb.SetCustomAttribute(GetEditorBrowsableNever()); + } + + internal void SetEditorBrowsableNever(MethodBuilder mb) + { + mb.SetCustomAttribute(GetEditorBrowsableNever()); + } + + internal void SetEditorBrowsableNever(PropertyBuilder pb) + { + pb.SetCustomAttribute(GetEditorBrowsableNever()); + } + + internal void SetDeprecatedAttribute(MethodBuilder mb) + { + if (deprecatedAttribute == null) + deprecatedAttribute = new CustomAttributeBuilder(context.Resolver.ResolveCoreType(typeof(ObsoleteAttribute).FullName).GetConstructor([]).AsReflection(), []); + + mb.SetCustomAttribute(deprecatedAttribute); + } + + internal void SetDeprecatedAttribute(TypeBuilder tb) + { + if (deprecatedAttribute == null) + { + deprecatedAttribute = new CustomAttributeBuilder(context.Resolver.ResolveCoreType(typeof(ObsoleteAttribute).FullName).GetConstructor([]).AsReflection(), []); + } + + tb.SetCustomAttribute(deprecatedAttribute); + } + + internal void SetDeprecatedAttribute(FieldBuilder fb) + { + if (deprecatedAttribute == null) + deprecatedAttribute = new CustomAttributeBuilder(context.Resolver.ResolveCoreType(typeof(ObsoleteAttribute).FullName).GetConstructor([]).AsReflection(), []); + + fb.SetCustomAttribute(deprecatedAttribute); + } + + internal void SetDeprecatedAttribute(PropertyBuilder pb) + { + if (deprecatedAttribute == null) + { + deprecatedAttribute = new CustomAttributeBuilder(context.Resolver.ResolveCoreType(typeof(ObsoleteAttribute).FullName).GetConstructor([]).AsReflection(), []); + } + pb.SetCustomAttribute(deprecatedAttribute); + } + + internal void SetThrowsAttribute(MethodBuilder mb, string[] exceptions) + { + if (exceptions != null && exceptions.Length != 0) + { + throwsAttribute ??= TypeOfThrowsAttribute.GetConstructor([context.Resolver.ResolveCoreType(typeof(string).FullName).MakeArrayType()]); + exceptions = UnicodeUtil.EscapeInvalidSurrogates(exceptions); + mb.SetCustomAttribute(new CustomAttributeBuilder(throwsAttribute.AsReflection(), [exceptions])); + } + } + + internal void SetGhostInterface(TypeBuilder typeBuilder) + { + ghostInterfaceAttribute ??= new CustomAttributeBuilder(TypeOfGhostInterfaceAttribute.GetConstructor([]).AsReflection(), []); + typeBuilder.SetCustomAttribute(ghostInterfaceAttribute); + } + + internal void SetNonNestedInnerClass(TypeBuilder typeBuilder, string className) + { + nonNestedInnerClassAttribute ??= TypeOfNonNestedInnerClassAttribute.GetConstructor([context.Types.String]); + typeBuilder.SetCustomAttribute(new CustomAttributeBuilder(nonNestedInnerClassAttribute.AsReflection(), [UnicodeUtil.EscapeInvalidSurrogates(className)])); + } + + internal void SetNonNestedOuterClass(TypeBuilder typeBuilder, string className) + { + nonNestedOuterClassAttribute ??= TypeOfNonNestedOuterClassAttribute.GetConstructor([context.Types.String]); + typeBuilder.SetCustomAttribute(new CustomAttributeBuilder(nonNestedOuterClassAttribute.AsReflection(), [UnicodeUtil.EscapeInvalidSurrogates(className)])); + } #endif // IMPORTER @@ -530,8 +519,7 @@ internal void HideFromJava(MethodBuilder mb) internal void HideFromJava(MethodBuilder mb, HideFromJavaFlags flags) { - CustomAttributeBuilder cab = new CustomAttributeBuilder(TypeOfHideFromJavaAttribute.GetConstructor(new Type[] { TypeOfHideFromJavaFlags }), new object[] { flags }); - mb.SetCustomAttribute(cab); + mb.SetCustomAttribute(new CustomAttributeBuilder(TypeOfHideFromJavaAttribute.GetConstructor([TypeOfHideFromJavaFlags]).AsReflection(), [flags])); } internal void HideFromJava(FieldBuilder fb) @@ -541,24 +529,24 @@ internal void HideFromJava(FieldBuilder fb) #if IMPORTER - internal void HideFromJava(PropertyBuilder pb) - { - pb.SetCustomAttribute(HideFromJavaAttributeBuilder); - } + internal void HideFromJava(PropertyBuilder pb) + { + pb.SetCustomAttribute(HideFromJavaAttributeBuilder); + } #endif - internal bool IsHideFromJava(Type type) + internal bool IsHideFromJava(ITypeSymbol type) { return type.IsDefined(TypeOfHideFromJavaAttribute, false) || (type.IsNested && (type.DeclaringType.IsDefined(TypeOfHideFromJavaAttribute, false) || type.Name.StartsWith("__<", StringComparison.Ordinal))); } - internal bool IsHideFromJava(MemberInfo mi) + internal bool IsHideFromJava(IMemberSymbol mi) { return (GetHideFromJavaFlags(mi) & HideFromJavaFlags.Code) != 0; } - internal HideFromJavaFlags GetHideFromJavaFlags(MemberInfo mi) + internal HideFromJavaFlags GetHideFromJavaFlags(IMemberSymbol mi) { // NOTE all privatescope fields and methods are "hideFromJava" // because Java cannot deal with the potential name clashes @@ -572,79 +560,66 @@ internal HideFromJavaFlags GetHideFromJavaFlags(MemberInfo mi) if (mi.Name.StartsWith("__<", StringComparison.Ordinal)) return HideFromJavaFlags.All; -#if !IMPORTER && !EXPORTER - - var attr = mi.GetCustomAttributes(typeofHideFromJavaAttribute, false); + var attr = mi.GetCustomAttributes(TypeOfHideFromJavaAttribute); if (attr.Length == 1) - return ((HideFromJavaAttribute)attr[0]).Flags; + { + var args = attr[0].ConstructorArguments; + if (args.Length == 1) + return (HideFromJavaFlags)args[0].Value; -#else - var attr = CustomAttributeData.__GetCustomAttributes(mi, TypeOfHideFromJavaAttribute, false); - if (attr.Count == 1) - { - var args = attr[0].ConstructorArguments; - if (args.Count == 1) - return (HideFromJavaFlags)args[0].Value; - - return HideFromJavaFlags.All; - } -#endif + return HideFromJavaFlags.All; + } return HideFromJavaFlags.None; } #if IMPORTER - internal void SetImplementsAttribute(TypeBuilder typeBuilder, RuntimeJavaType[] ifaceWrappers) - { - var interfaces = new string[ifaceWrappers.Length]; - for (int i = 0; i < interfaces.Length; i++) - interfaces[i] = UnicodeUtil.EscapeInvalidSurrogates(ifaceWrappers[i].Name); + internal void SetImplementsAttribute(TypeBuilder typeBuilder, RuntimeJavaType[] ifaceWrappers) + { + var interfaces = new string[ifaceWrappers.Length]; + for (int i = 0; i < interfaces.Length; i++) + interfaces[i] = UnicodeUtil.EscapeInvalidSurrogates(ifaceWrappers[i].Name); - if (implementsAttribute == null) - implementsAttribute = TypeOfImplementsAttribute.GetConstructor(new Type[] { context.Resolver.ResolveCoreType(typeof(string).FullName).MakeArrayType().AsReflection() }); + if (implementsAttribute == null) + implementsAttribute = TypeOfImplementsAttribute.GetConstructor([context.Resolver.ResolveCoreType(typeof(string).FullName).MakeArrayType()]); - typeBuilder.SetCustomAttribute(new CustomAttributeBuilder(implementsAttribute, new object[] { interfaces })); - } + typeBuilder.SetCustomAttribute(new CustomAttributeBuilder(implementsAttribute.AsReflection(), new object[] { interfaces })); + } #endif - internal bool IsGhostInterface(Type type) + internal bool IsGhostInterface(ITypeSymbol type) { return type.IsDefined(TypeOfGhostInterfaceAttribute, false); } - internal bool IsRemappedType(Type type) + internal bool IsRemappedType(ITypeSymbol type) { return type.IsDefined(TypeOfRemappedTypeAttribute, false); } - internal bool IsExceptionIsUnsafeForMapping(Type type) + internal bool IsExceptionIsUnsafeForMapping(ITypeSymbol type) { return type.IsDefined(TypeOfExceptionIsUnsafeForMappingAttribute, false); } - internal ModifiersAttribute GetModifiersAttribute(MemberInfo member) + internal ModifiersAttribute GetModifiersAttribute(IMemberSymbol member) { -#if !IMPORTER && !EXPORTER - var attr = member.GetCustomAttributes(typeof(ModifiersAttribute), false); - return attr.Length == 1 ? (ModifiersAttribute)attr[0] : null; -#else - var attr = CustomAttributeData.__GetCustomAttributes(member, TypeOfModifiersAttribute, false); - if (attr.Count == 1) - { - var args = attr[0].ConstructorArguments; - if (args.Count == 2) - return new ModifiersAttribute((Modifiers)args[0].Value, (bool)args[1].Value); + var attr = member.GetCustomAttributes(TypeOfModifiersAttribute, false); + if (attr.Length == 1) + { + var args = attr[0].ConstructorArguments; + if (args.Length == 2) + return new ModifiersAttribute((Modifiers)args[0].Value, (bool)args[1].Value); - return new ModifiersAttribute((Modifiers)args[0].Value); - } + return new ModifiersAttribute((Modifiers)args[0].Value); + } - return null; -#endif + return null; } - internal ExModifiers GetModifiers(MethodBase mb, bool assemblyIsPrivate) + internal ExModifiers GetModifiers(IMethodBaseSymbol mb, bool assemblyIsPrivate) { var attr = GetModifiersAttribute(mb); if (attr != null) @@ -685,7 +660,7 @@ internal ExModifiers GetModifiers(MethodBase mb, bool assemblyIsPrivate) // Some .NET interfaces (like System._AppDomain) have synchronized methods, // Java doesn't allow synchronized on an abstract methods, so we ignore it for // abstract methods. - if ((mb.GetMethodImplementationFlags() & MethodImplAttributes.Synchronized) != 0) + if ((mb.GetMethodImplementationFlags() & System.Reflection.MethodImplAttributes.Synchronized) != 0) { modifiers |= Modifiers.Synchronized; } @@ -696,19 +671,19 @@ internal ExModifiers GetModifiers(MethodBase mb, bool assemblyIsPrivate) modifiers |= Modifiers.Static; } - if ((mb.Attributes & MethodAttributes.PinvokeImpl) != 0) + if ((mb.Attributes & System.Reflection.MethodAttributes.PinvokeImpl) != 0) { modifiers |= Modifiers.Native; } var parameters = mb.GetParameters(); - if (parameters.Length > 0 && parameters[parameters.Length - 1].IsDefined(context.Resolver.ResolveCoreType(typeof(ParamArrayAttribute).FullName).AsReflection(), false)) + if (parameters.Length > 0 && parameters[parameters.Length - 1].IsDefined(context.Resolver.ResolveCoreType(typeof(ParamArrayAttribute).FullName), false)) modifiers |= Modifiers.VarArgs; return new ExModifiers(modifiers, false); } - internal ExModifiers GetModifiers(FieldInfo fi, bool assemblyIsPrivate) + internal ExModifiers GetModifiers(IFieldSymbol fi, bool assemblyIsPrivate) { var attr = GetModifiersAttribute(fi); if (attr != null) @@ -757,439 +732,354 @@ internal ExModifiers GetModifiers(FieldInfo fi, bool assemblyIsPrivate) internal void SetDebuggingModes(AssemblyBuilder assemblyBuilder, DebuggableAttribute.DebuggingModes modes) { - debuggableAttribute ??= TypeOfDebuggableAttribute.GetConstructor(new[] { TypeOfDebuggableAttribute.GetNestedType(nameof(DebuggableAttribute.DebuggingModes)) }); - assemblyBuilder.SetCustomAttribute(new CustomAttributeBuilder(debuggableAttribute, new object[] { modes })); + debuggableAttribute ??= TypeOfDebuggableAttribute.GetConstructor([TypeOfDebuggableAttribute.GetNestedType(nameof(DebuggableAttribute.DebuggingModes))]); + assemblyBuilder.SetCustomAttribute(new CustomAttributeBuilder(debuggableAttribute.AsReflection(), [modes])); } #if IMPORTER - internal void SetModifiers(MethodBuilder mb, Modifiers modifiers, bool isInternal) - { - CustomAttributeBuilder customAttributeBuilder; - if (isInternal) - customAttributeBuilder = new CustomAttributeBuilder(TypeOfModifiersAttribute.GetConstructor(new Type[] { TypeOfModifiers, context.Types.Boolean }), new object[] { modifiers, isInternal }); - else - customAttributeBuilder = new CustomAttributeBuilder(TypeOfModifiersAttribute.GetConstructor(new Type[] { TypeOfModifiers }), new object[] { modifiers }); - - mb.SetCustomAttribute(customAttributeBuilder); - } - - internal void SetModifiers(FieldBuilder fb, Modifiers modifiers, bool isInternal) - { - CustomAttributeBuilder customAttributeBuilder; - if (isInternal) - customAttributeBuilder = new CustomAttributeBuilder(TypeOfModifiersAttribute.GetConstructor(new Type[] { TypeOfModifiers, context.Types.Boolean }), new object[] { modifiers, isInternal }); - else - customAttributeBuilder = new CustomAttributeBuilder(TypeOfModifiersAttribute.GetConstructor(new Type[] { TypeOfModifiers }), new object[] { modifiers }); - - fb.SetCustomAttribute(customAttributeBuilder); - } - - internal void SetModifiers(PropertyBuilder pb, Modifiers modifiers, bool isInternal) - { - CustomAttributeBuilder customAttributeBuilder; - if (isInternal) - customAttributeBuilder = new CustomAttributeBuilder(TypeOfModifiersAttribute.GetConstructor(new Type[] { TypeOfModifiers, context.Types.Boolean }), new object[] { modifiers, isInternal }); - else - customAttributeBuilder = new CustomAttributeBuilder(TypeOfModifiersAttribute.GetConstructor(new Type[] { TypeOfModifiers }), new object[] { modifiers }); - - pb.SetCustomAttribute(customAttributeBuilder); - } - - internal void SetModifiers(TypeBuilder tb, Modifiers modifiers, bool isInternal) - { - CustomAttributeBuilder customAttributeBuilder; - if (isInternal) - customAttributeBuilder = new CustomAttributeBuilder(TypeOfModifiersAttribute.GetConstructor(new Type[] { TypeOfModifiers, context.Types.Boolean }), new object[] { modifiers, isInternal }); - else - customAttributeBuilder = new CustomAttributeBuilder(TypeOfModifiersAttribute.GetConstructor(new Type[] { TypeOfModifiers }), new object[] { modifiers }); - - tb.SetCustomAttribute(customAttributeBuilder); - } - - internal void SetNameSig(MethodBuilder mb, string name, string sig) - { - var customAttributeBuilder = new CustomAttributeBuilder(TypeOfNameSigAttribute.GetConstructor(new Type[] { context.Types.String, context.Types.String }), new object[] { UnicodeUtil.EscapeInvalidSurrogates(name), UnicodeUtil.EscapeInvalidSurrogates(sig) }); - mb.SetCustomAttribute(customAttributeBuilder); - } - - internal void SetInnerClass(TypeBuilder typeBuilder, string innerClass, Modifiers modifiers) - { - var argTypes = new Type[] { context.Types.String, TypeOfModifiers }; - var args = new object[] { UnicodeUtil.EscapeInvalidSurrogates(innerClass), modifiers }; - var ci = TypeOfInnerClassAttribute.GetConstructor(argTypes); - var customAttributeBuilder = new CustomAttributeBuilder(ci, args); - typeBuilder.SetCustomAttribute(customAttributeBuilder); - } - - internal void SetSourceFile(TypeBuilder typeBuilder, string filename) - { - sourceFileAttribute ??= TypeOfSourceFileAttribute.GetConstructor(new Type[] { context.Types.String }); - typeBuilder.SetCustomAttribute(new CustomAttributeBuilder(sourceFileAttribute, new object[] { filename })); - } - - internal void SetSourceFile(ModuleBuilder moduleBuilder, string filename) - { - sourceFileAttribute ??= TypeOfSourceFileAttribute.GetConstructor(new Type[] { context.Types.String }); - moduleBuilder.SetCustomAttribute(new CustomAttributeBuilder(sourceFileAttribute, new object[] { filename })); - } - - internal void SetLineNumberTable(MethodBuilder mb, IKVM.Attributes.LineNumberTableAttribute.LineNumberWriter writer) - { - object arg; - ConstructorInfo con; - if (writer.Count == 1) - { - lineNumberTableAttribute2 ??= TypeOfLineNumberTableAttribute.GetConstructor(new Type[] { context.Types.UInt16 }); - con = lineNumberTableAttribute2; - arg = (ushort)writer.LineNo; - } - else - { - lineNumberTableAttribute1 ??= TypeOfLineNumberTableAttribute.GetConstructor(new Type[] { context.Resolver.ResolveCoreType(typeof(byte).FullName).MakeArrayType().AsReflection() }); - con = lineNumberTableAttribute1; - arg = writer.ToArray(); - } - mb.SetCustomAttribute(new CustomAttributeBuilder(con, new object[] { arg })); - } - - internal void SetEnclosingMethodAttribute(TypeBuilder tb, string className, string methodName, string methodSig) - { - if (enclosingMethodAttribute == null) - { - enclosingMethodAttribute = TypeOfEnclosingMethodAttribute.GetConstructor(new Type[] { context.Types.String, context.Types.String, context.Types.String }); - } - tb.SetCustomAttribute(new CustomAttributeBuilder(enclosingMethodAttribute, - new object[] { UnicodeUtil.EscapeInvalidSurrogates(className), UnicodeUtil.EscapeInvalidSurrogates(methodName), UnicodeUtil.EscapeInvalidSurrogates(methodSig) })); - } - - internal void SetSignatureAttribute(TypeBuilder tb, string signature) - { - signatureAttribute ??= TypeOfSignatureAttribute.GetConstructor(new Type[] { context.Types.String }); - tb.SetCustomAttribute(new CustomAttributeBuilder(signatureAttribute, new object[] { UnicodeUtil.EscapeInvalidSurrogates(signature) })); - } - - internal void SetSignatureAttribute(FieldBuilder fb, string signature) - { - signatureAttribute ??= TypeOfSignatureAttribute.GetConstructor(new Type[] { context.Types.String }); - fb.SetCustomAttribute(new CustomAttributeBuilder(signatureAttribute, new object[] { UnicodeUtil.EscapeInvalidSurrogates(signature) })); - } - - internal void SetSignatureAttribute(MethodBuilder mb, string signature) - { - signatureAttribute ??= TypeOfSignatureAttribute.GetConstructor(new Type[] { context.Types.String }); - mb.SetCustomAttribute(new CustomAttributeBuilder(signatureAttribute, new object[] { UnicodeUtil.EscapeInvalidSurrogates(signature) })); - } - - internal void SetMethodParametersAttribute(MethodBuilder mb, Modifiers[] modifiers) - { - methodParametersAttribute ??= TypeOfMethodParametersAttribute.GetConstructor(new[] { TypeOfModifiers.MakeArrayType() }); - mb.SetCustomAttribute(new CustomAttributeBuilder(methodParametersAttribute, new[] { modifiers })); - } - - internal void SetRuntimeVisibleTypeAnnotationsAttribute(TypeBuilder tb, ref readonly TypeAnnotationTable table) - { - var builder = new BlobBuilder(); - var encoder = new TypeAnnotationTableEncoder(builder); - table.WriteTo(ref encoder); - - runtimeVisibleTypeAnnotationsAttribute ??= TypeOfRuntimeVisibleTypeAnnotationsAttribute.GetConstructor([context.Types.Byte.MakeArrayType()]); - tb.SetCustomAttribute(new CustomAttributeBuilder(runtimeVisibleTypeAnnotationsAttribute, [builder.ToArray()])); - } - - internal void SetRuntimeVisibleTypeAnnotationsAttribute(FieldBuilder fb, ref readonly TypeAnnotationTable table) - { - var builder = new BlobBuilder(); - var encoder = new TypeAnnotationTableEncoder(builder); - table.WriteTo(ref encoder); - - runtimeVisibleTypeAnnotationsAttribute ??= TypeOfRuntimeVisibleTypeAnnotationsAttribute.GetConstructor([context.Types.Byte.MakeArrayType()]); - fb.SetCustomAttribute(new CustomAttributeBuilder(runtimeVisibleTypeAnnotationsAttribute, [builder.ToArray()])); - } - - internal void SetRuntimeVisibleTypeAnnotationsAttribute(MethodBuilder mb, ref readonly TypeAnnotationTable table) - { - var builder = new BlobBuilder(); - var encoder = new TypeAnnotationTableEncoder(builder); - table.WriteTo(ref encoder); - - runtimeVisibleTypeAnnotationsAttribute ??= TypeOfRuntimeVisibleTypeAnnotationsAttribute.GetConstructor([context.Types.Byte.MakeArrayType()]); - mb.SetCustomAttribute(new CustomAttributeBuilder(runtimeVisibleTypeAnnotationsAttribute, [builder.ToArray()])); - } - - internal void SetConstantPoolAttribute(TypeBuilder tb, object[] constantPool) - { - constantPoolAttribute ??= TypeOfConstantPoolAttribute.GetConstructor([context.Types.Object.MakeArrayType()]); - tb.SetCustomAttribute(new CustomAttributeBuilder(constantPoolAttribute, [constantPool])); - } - - internal void SetParamArrayAttribute(ParameterBuilder pb) - { - paramArrayAttribute ??= new CustomAttributeBuilder(context.Resolver.ResolveCoreType(typeof(ParamArrayAttribute).FullName).GetConstructor([]).AsReflection(), []); - pb.SetCustomAttribute(paramArrayAttribute); - } + internal void SetModifiers(MethodBuilder mb, Modifiers modifiers, bool isInternal) + { + CustomAttributeBuilder customAttributeBuilder; + if (isInternal) + customAttributeBuilder = new CustomAttributeBuilder(TypeOfModifiersAttribute.GetConstructor([TypeOfModifiers, context.Types.Boolean]).AsReflection(), [modifiers, isInternal]); + else + customAttributeBuilder = new CustomAttributeBuilder(TypeOfModifiersAttribute.GetConstructor([TypeOfModifiers]).AsReflection(), [modifiers]); + + mb.SetCustomAttribute(customAttributeBuilder); + } + + internal void SetModifiers(FieldBuilder fb, Modifiers modifiers, bool isInternal) + { + CustomAttributeBuilder customAttributeBuilder; + if (isInternal) + customAttributeBuilder = new CustomAttributeBuilder(TypeOfModifiersAttribute.GetConstructor([TypeOfModifiers, context.Types.Boolean]).AsReflection(), [modifiers, isInternal]); + else + customAttributeBuilder = new CustomAttributeBuilder(TypeOfModifiersAttribute.GetConstructor([TypeOfModifiers]).AsReflection(), [modifiers]); + + fb.SetCustomAttribute(customAttributeBuilder); + } + + internal void SetModifiers(PropertyBuilder pb, Modifiers modifiers, bool isInternal) + { + CustomAttributeBuilder customAttributeBuilder; + if (isInternal) + customAttributeBuilder = new CustomAttributeBuilder(TypeOfModifiersAttribute.GetConstructor([TypeOfModifiers, context.Types.Boolean]).AsReflection(), [modifiers, isInternal]); + else + customAttributeBuilder = new CustomAttributeBuilder(TypeOfModifiersAttribute.GetConstructor([TypeOfModifiers]).AsReflection(), [modifiers]); + + pb.SetCustomAttribute(customAttributeBuilder); + } + + internal void SetModifiers(TypeBuilder tb, Modifiers modifiers, bool isInternal) + { + CustomAttributeBuilder customAttributeBuilder; + if (isInternal) + customAttributeBuilder = new CustomAttributeBuilder(TypeOfModifiersAttribute.GetConstructor([TypeOfModifiers, context.Types.Boolean]).AsReflection(), [modifiers, isInternal]); + else + customAttributeBuilder = new CustomAttributeBuilder(TypeOfModifiersAttribute.GetConstructor([TypeOfModifiers]).AsReflection(), [modifiers]); + + tb.SetCustomAttribute(customAttributeBuilder); + } + + internal void SetNameSig(MethodBuilder mb, string name, string sig) + { + var customAttributeBuilder = new CustomAttributeBuilder(TypeOfNameSigAttribute.GetConstructor([context.Types.String, context.Types.String]).AsReflection(), [UnicodeUtil.EscapeInvalidSurrogates(name), UnicodeUtil.EscapeInvalidSurrogates(sig)]); + mb.SetCustomAttribute(customAttributeBuilder); + } + + internal void SetInnerClass(TypeBuilder typeBuilder, string innerClass, Modifiers modifiers) + { + var argTypes = new ITypeSymbol[] { context.Types.String, TypeOfModifiers }; + var args = new object[] { UnicodeUtil.EscapeInvalidSurrogates(innerClass), modifiers }; + var ci = TypeOfInnerClassAttribute.GetConstructor(argTypes); + var customAttributeBuilder = new CustomAttributeBuilder(ci.AsReflection(), args); + typeBuilder.SetCustomAttribute(customAttributeBuilder); + } + + internal void SetSourceFile(TypeBuilder typeBuilder, string filename) + { + sourceFileAttribute ??= TypeOfSourceFileAttribute.GetConstructor([context.Types.String]); + typeBuilder.SetCustomAttribute(new CustomAttributeBuilder(sourceFileAttribute.AsReflection(), [filename])); + } + + internal void SetSourceFile(ModuleBuilder moduleBuilder, string filename) + { + sourceFileAttribute ??= TypeOfSourceFileAttribute.GetConstructor([context.Types.String]); + moduleBuilder.SetCustomAttribute(new CustomAttributeBuilder(sourceFileAttribute.AsReflection(), new object[] { filename })); + } + + internal void SetLineNumberTable(MethodBuilder mb, IKVM.Attributes.LineNumberTableAttribute.LineNumberWriter writer) + { + object arg; + IConstructorSymbol con; + if (writer.Count == 1) + { + lineNumberTableAttribute2 ??= TypeOfLineNumberTableAttribute.GetConstructor([context.Types.UInt16]); + con = lineNumberTableAttribute2; + arg = (ushort)writer.LineNo; + } + else + { + lineNumberTableAttribute1 ??= TypeOfLineNumberTableAttribute.GetConstructor([context.Resolver.ResolveCoreType(typeof(byte).FullName).MakeArrayType()]); + con = lineNumberTableAttribute1; + arg = writer.ToArray(); + } + mb.SetCustomAttribute(new CustomAttributeBuilder(con.AsReflection(), [arg])); + } + + internal void SetEnclosingMethodAttribute(TypeBuilder tb, string className, string methodName, string methodSig) + { + if (enclosingMethodAttribute == null) + { + enclosingMethodAttribute = TypeOfEnclosingMethodAttribute.GetConstructor([context.Types.String, context.Types.String, context.Types.String]); + } + tb.SetCustomAttribute(new CustomAttributeBuilder(enclosingMethodAttribute.AsReflection(), [UnicodeUtil.EscapeInvalidSurrogates(className), UnicodeUtil.EscapeInvalidSurrogates(methodName), UnicodeUtil.EscapeInvalidSurrogates(methodSig)])); + } + + internal void SetSignatureAttribute(TypeBuilder tb, string signature) + { + signatureAttribute ??= TypeOfSignatureAttribute.GetConstructor([context.Types.String]); + tb.SetCustomAttribute(new CustomAttributeBuilder(signatureAttribute.AsReflection(), [UnicodeUtil.EscapeInvalidSurrogates(signature)])); + } + + internal void SetSignatureAttribute(FieldBuilder fb, string signature) + { + signatureAttribute ??= TypeOfSignatureAttribute.GetConstructor([context.Types.String]); + fb.SetCustomAttribute(new CustomAttributeBuilder(signatureAttribute.AsReflection(), [UnicodeUtil.EscapeInvalidSurrogates(signature)])); + } + + internal void SetSignatureAttribute(MethodBuilder mb, string signature) + { + signatureAttribute ??= TypeOfSignatureAttribute.GetConstructor([context.Types.String]); + mb.SetCustomAttribute(new CustomAttributeBuilder(signatureAttribute.AsReflection(), [UnicodeUtil.EscapeInvalidSurrogates(signature)])); + } + + internal void SetMethodParametersAttribute(MethodBuilder mb, Modifiers[] modifiers) + { + methodParametersAttribute ??= TypeOfMethodParametersAttribute.GetConstructor([TypeOfModifiers.MakeArrayType()]); + mb.SetCustomAttribute(new CustomAttributeBuilder(methodParametersAttribute.AsReflection(), [modifiers])); + } + + internal void SetRuntimeVisibleTypeAnnotationsAttribute(TypeBuilder tb, ref readonly TypeAnnotationTable table) + { + var builder = new BlobBuilder(); + var encoder = new TypeAnnotationTableEncoder(builder); + table.WriteTo(ref encoder); + + runtimeVisibleTypeAnnotationsAttribute ??= TypeOfRuntimeVisibleTypeAnnotationsAttribute.GetConstructor([context.Types.Byte.MakeArrayType()]); + tb.SetCustomAttribute(new CustomAttributeBuilder(runtimeVisibleTypeAnnotationsAttribute.AsReflection(), [builder.ToArray()])); + } + + internal void SetRuntimeVisibleTypeAnnotationsAttribute(FieldBuilder fb, ref readonly TypeAnnotationTable table) + { + var builder = new BlobBuilder(); + var encoder = new TypeAnnotationTableEncoder(builder); + table.WriteTo(ref encoder); + + runtimeVisibleTypeAnnotationsAttribute ??= TypeOfRuntimeVisibleTypeAnnotationsAttribute.GetConstructor([context.Types.Byte.MakeArrayType()]); + fb.SetCustomAttribute(new CustomAttributeBuilder(runtimeVisibleTypeAnnotationsAttribute.AsReflection(), [builder.ToArray()])); + } + + internal void SetRuntimeVisibleTypeAnnotationsAttribute(MethodBuilder mb, ref readonly TypeAnnotationTable table) + { + var builder = new BlobBuilder(); + var encoder = new TypeAnnotationTableEncoder(builder); + table.WriteTo(ref encoder); + + runtimeVisibleTypeAnnotationsAttribute ??= TypeOfRuntimeVisibleTypeAnnotationsAttribute.GetConstructor([context.Types.Byte.MakeArrayType()]); + mb.SetCustomAttribute(new CustomAttributeBuilder(runtimeVisibleTypeAnnotationsAttribute.AsReflection(), [builder.ToArray()])); + } + + internal void SetConstantPoolAttribute(TypeBuilder tb, object[] constantPool) + { + constantPoolAttribute ??= TypeOfConstantPoolAttribute.GetConstructor([context.Types.Object.MakeArrayType()]); + tb.SetCustomAttribute(new CustomAttributeBuilder(constantPoolAttribute.AsReflection(), [constantPool])); + } + + internal void SetParamArrayAttribute(ParameterBuilder pb) + { + paramArrayAttribute ??= new CustomAttributeBuilder(context.Resolver.ResolveCoreType(typeof(ParamArrayAttribute).FullName).GetConstructor([]).AsReflection(), []); + pb.SetCustomAttribute(paramArrayAttribute); + } #endif // IMPORTER - internal NameSigAttribute GetNameSig(MemberInfo member) + internal NameSigAttribute GetNameSig(IMemberSymbol member) { -#if !IMPORTER && !EXPORTER - var attr = member.GetCustomAttributes(typeof(NameSigAttribute), false); - return attr.Length == 1 ? (NameSigAttribute)attr[0] : null; -#else - foreach (var cad in CustomAttributeData.__GetCustomAttributes(member, TypeOfNameSigAttribute, false)) - { - var args = cad.ConstructorArguments; - return new NameSigAttribute((string)args[0].Value, (string)args[1].Value); - } + foreach (var cad in member.GetCustomAttributes(TypeOfNameSigAttribute)) + { + var args = cad.ConstructorArguments; + return new NameSigAttribute((string)args[0].Value, (string)args[1].Value); + } - return null; -#endif + return null; } - internal T[] DecodeArray(CustomAttributeTypedArgument arg) + internal T[] DecodeArray(CoreLib.Symbols.CustomAttributeTypedArgument arg) { + +/* Unmerged change from project 'IKVM.Tools.Exporter (net8.0)' +Before: var elems = (IList)arg.Value; var arr = new T[elems.Count]; +After: + var elems = (IList)arg.Value; + var arr = new T[elems.Count]; +*/ + var elems = (IList)arg.Value; + var arr = new T[elems.Count]; for (int i = 0; i < arr.Length; i++) arr[i] = (T)elems[i].Value; return arr; } - internal ImplementsAttribute GetImplements(Type type) + internal ImplementsAttribute GetImplements(ITypeSymbol type) { -#if !IMPORTER && !EXPORTER - var attribs = type.GetCustomAttributes(typeof(ImplementsAttribute), false); - return attribs.Length == 1 ? (ImplementsAttribute)attribs[0] : null; -#else - foreach (var cad in CustomAttributeData.__GetCustomAttributes(type, TypeOfImplementsAttribute, false)) - { - var args = cad.ConstructorArguments; - return new ImplementsAttribute(DecodeArray(args[0])); - } + foreach (var cad in type.GetCustomAttributes(TypeOfImplementsAttribute)) + { + var args = cad.ConstructorArguments; + return new ImplementsAttribute(DecodeArray(args[0])); + } - return null; -#endif + return null; } - internal ThrowsAttribute GetThrows(MethodBase mb) + internal ThrowsAttribute GetThrows(IMethodBaseSymbol mb) { -#if !IMPORTER && !EXPORTER - var attribs = mb.GetCustomAttributes(typeof(ThrowsAttribute), false); - return attribs.Length == 1 ? (ThrowsAttribute)attribs[0] : null; -#else - foreach (var cad in CustomAttributeData.__GetCustomAttributes(mb, TypeOfThrowsAttribute, false)) - { - var args = cad.ConstructorArguments; - if (args[0].ArgumentType == context.Types.String.MakeArrayType()) - { - return new ThrowsAttribute(DecodeArray(args[0])); - } - else if (args[0].ArgumentType == context.Types.Type.MakeArrayType()) - { - return new ThrowsAttribute(DecodeArray(args[0])); - } - else - { - return new ThrowsAttribute((Type)args[0].Value); - } - } - - return null; -#endif + foreach (var cad in mb.GetCustomAttributes(TypeOfThrowsAttribute)) + { + var args = cad.ConstructorArguments; + if (args[0].ArgumentType == context.Types.String.MakeArrayType()) + { + return new ThrowsAttribute(DecodeArray(args[0])); + } + else if (args[0].ArgumentType == context.Types.Type.MakeArrayType()) + { + return new ThrowsAttribute(DecodeArray(args[0])); + } + else + { + return new ThrowsAttribute((Type)args[0].Value); + } + } + + return null; } - internal string[] GetNonNestedInnerClasses(Type t) + internal string[] GetNonNestedInnerClasses(ITypeSymbol t) { -#if !IMPORTER && !EXPORTER - var attribs = t.GetCustomAttributes(typeof(NonNestedInnerClassAttribute), false); - var classes = new string[attribs.Length]; - for (int i = 0; i < attribs.Length; i++) - classes[i] = ((NonNestedInnerClassAttribute)attribs[i]).InnerClassName; + var list = new List(); + foreach (var cad in t.GetCustomAttributes(TypeOfNonNestedInnerClassAttribute)) + list.Add(UnicodeUtil.UnescapeInvalidSurrogates((string)cad.ConstructorArguments[0].Value)); - return classes; -#else - var list = new List(); - foreach (var cad in CustomAttributeData.__GetCustomAttributes(t, TypeOfNonNestedInnerClassAttribute, false)) - { - var args = cad.ConstructorArguments; - list.Add(UnicodeUtil.UnescapeInvalidSurrogates((string)args[0].Value)); - } - - return list.ToArray(); -#endif + return list.ToArray(); } - internal string GetNonNestedOuterClasses(Type t) + internal string GetNonNestedOuterClasses(ITypeSymbol t) { -#if !IMPORTER && !EXPORTER - var attribs = t.GetCustomAttributes(typeof(NonNestedOuterClassAttribute), false); - return attribs.Length == 1 ? ((NonNestedOuterClassAttribute)attribs[0]).OuterClassName : null; -#else - foreach (var cad in CustomAttributeData.__GetCustomAttributes(t, TypeOfNonNestedOuterClassAttribute, false)) - { - var args = cad.ConstructorArguments; - return UnicodeUtil.UnescapeInvalidSurrogates((string)args[0].Value); - } - return null; -#endif + foreach (var cad in t.GetCustomAttributes(TypeOfNonNestedOuterClassAttribute)) + return UnicodeUtil.UnescapeInvalidSurrogates((string)cad.ConstructorArguments[0].Value); + + return null; } - internal IKVM.Attributes.SignatureAttribute GetSignature(MemberInfo member) + internal IKVM.Attributes.SignatureAttribute GetSignature(IMemberSymbol member) { -#if !IMPORTER && !EXPORTER - var attribs = member.GetCustomAttributes(typeof(IKVM.Attributes.SignatureAttribute), false); - return attribs.Length == 1 ? (IKVM.Attributes.SignatureAttribute)attribs[0] : null; -#else - foreach (var cad in CustomAttributeData.__GetCustomAttributes(member, TypeOfSignatureAttribute, false)) - { - var args = cad.ConstructorArguments; - return new IKVM.Attributes.SignatureAttribute((string)args[0].Value); - } + foreach (var cad in member.GetCustomAttributes(TypeOfSignatureAttribute)) + return new IKVM.Attributes.SignatureAttribute((string)cad.ConstructorArguments[0].Value); - return null; -#endif + return null; } - internal IKVM.Attributes.MethodParametersAttribute GetMethodParameters(MethodBase method) + internal IKVM.Attributes.MethodParametersAttribute GetMethodParameters(IMethodBaseSymbol method) { -#if !IMPORTER && !EXPORTER - var attribs = method.GetCustomAttributes(typeof(IKVM.Attributes.MethodParametersAttribute), false); - return attribs.Length == 1 ? (IKVM.Attributes.MethodParametersAttribute)attribs[0] : null; -#else - foreach (var cad in CustomAttributeData.__GetCustomAttributes(method, TypeOfMethodParametersAttribute, false)) - { - var args = cad.ConstructorArguments; - return new IKVM.Attributes.MethodParametersAttribute(DecodeArray(args[0])); - } - return null; -#endif + foreach (var cad in method.GetCustomAttributes(TypeOfMethodParametersAttribute)) + return new IKVM.Attributes.MethodParametersAttribute(DecodeArray(cad.ConstructorArguments[0])); + + return null; } - internal object[] GetConstantPool(Type type) + internal object[] GetConstantPool(ITypeSymbol type) { -#if !IMPORTER && !EXPORTER - var attribs = type.GetCustomAttributes(typeof(ConstantPoolAttribute), false); - return attribs.Length == 1 ? ((ConstantPoolAttribute)attribs[0]).constantPool : null; -#else - foreach (var cad in CustomAttributeData.__GetCustomAttributes(type, TypeOfConstantPoolAttribute, false)) - return ConstantPoolAttribute.Decompress(DecodeArray(cad.ConstructorArguments[0])); + foreach (var cad in type.GetCustomAttributes(TypeOfConstantPoolAttribute)) + return ConstantPoolAttribute.Decompress(DecodeArray(cad.ConstructorArguments[0])); - return null; -#endif + return null; } - internal byte[] GetRuntimeVisibleTypeAnnotations(MemberInfo member) + internal byte[] GetRuntimeVisibleTypeAnnotations(IMemberSymbol member) { -#if !IMPORTER && !EXPORTER - object[] attribs = member.GetCustomAttributes(typeof(IKVM.Attributes.RuntimeVisibleTypeAnnotationsAttribute), false); - return attribs.Length == 1 ? ((IKVM.Attributes.RuntimeVisibleTypeAnnotationsAttribute)attribs[0]).data : null; -#else - foreach (CustomAttributeData cad in CustomAttributeData.__GetCustomAttributes(member, TypeOfRuntimeVisibleTypeAnnotationsAttribute, false)) - { - return DecodeArray(cad.ConstructorArguments[0]); - } + foreach (var cad in member.GetCustomAttributes(TypeOfRuntimeVisibleTypeAnnotationsAttribute)) + return DecodeArray(cad.ConstructorArguments[0]); - return null; -#endif + return null; } - internal InnerClassAttribute GetInnerClass(Type type) + internal InnerClassAttribute GetInnerClass(ITypeSymbol type) { -#if !IMPORTER && !EXPORTER - object[] attribs = type.GetCustomAttributes(typeof(InnerClassAttribute), false); - return attribs.Length == 1 ? (InnerClassAttribute)attribs[0] : null; -#else - foreach (CustomAttributeData cad in CustomAttributeData.__GetCustomAttributes(type, TypeOfInnerClassAttribute, false)) - { - IList args = cad.ConstructorArguments; - return new InnerClassAttribute((string)args[0].Value, (Modifiers)args[1].Value); - } - return null; -#endif + foreach (var cad in type.GetCustomAttributes(TypeOfInnerClassAttribute)) + { + var args = cad.ConstructorArguments; + return new InnerClassAttribute((string)args[0].Value, (Modifiers)args[1].Value); + } + + return null; } - internal RemappedInterfaceMethodAttribute[] GetRemappedInterfaceMethods(Type type) + internal RemappedInterfaceMethodAttribute[] GetRemappedInterfaceMethods(ITypeSymbol type) { -#if !IMPORTER && !EXPORTER - var attr = type.GetCustomAttributes(typeof(RemappedInterfaceMethodAttribute), false); - var attr1 = new RemappedInterfaceMethodAttribute[attr.Length]; - Array.Copy(attr, attr1, attr.Length); - return attr1; -#else - var attrs = new List(); - foreach (var cad in CustomAttributeData.__GetCustomAttributes(type, TypeOfRemappedInterfaceMethodAttribute, false)) - { - var args = cad.ConstructorArguments; - attrs.Add(new RemappedInterfaceMethodAttribute((string)args[0].Value, (string)args[1].Value, DecodeArray(args[2]))); - } - - return attrs.ToArray(); -#endif + var attrs = new List(); + foreach (var cad in type.GetCustomAttributes(TypeOfRemappedInterfaceMethodAttribute)) + { + var args = cad.ConstructorArguments; + attrs.Add(new RemappedInterfaceMethodAttribute((string)args[0].Value, (string)args[1].Value, DecodeArray(args[2]))); + } + + return attrs.ToArray(); } - internal RemappedTypeAttribute GetRemappedType(Type type) + internal RemappedTypeAttribute GetRemappedType(ITypeSymbol type) { -#if !IMPORTER && !EXPORTER - var attribs = type.GetCustomAttributes(typeof(RemappedTypeAttribute), false); - return attribs.Length == 1 ? (RemappedTypeAttribute)attribs[0] : null; -#else - foreach (var cad in CustomAttributeData.__GetCustomAttributes(type, TypeOfRemappedTypeAttribute, false)) - { - var args = cad.ConstructorArguments; - return new RemappedTypeAttribute((Type)args[0].Value); - } + foreach (var cad in type.GetCustomAttributes(TypeOfRemappedTypeAttribute)) + return new RemappedTypeAttribute((Type)cad.ConstructorArguments[0].Value); - return null; -#endif + return null; } - internal RemappedClassAttribute[] GetRemappedClasses(Assembly coreAssembly) + internal RemappedClassAttribute[] GetRemappedClasses(IAssemblySymbol coreAssembly) { -#if !IMPORTER && !EXPORTER - var attr = coreAssembly.GetCustomAttributes(typeof(RemappedClassAttribute), false); - var attr1 = new RemappedClassAttribute[attr.Length]; - Array.Copy(attr, attr1, attr.Length); - return attr1; -#else - var attrs = new List(); - foreach (var cad in CustomAttributeData.__GetCustomAttributes(coreAssembly, TypeOfRemappedClassAttribute, false)) - { - var args = cad.ConstructorArguments; - attrs.Add(new RemappedClassAttribute((string)args[0].Value, (Type)args[1].Value)); - } - - return attrs.ToArray(); -#endif + var attrs = new List(); + + foreach (var cad in coreAssembly.GetCustomAttributes(TypeOfRemappedClassAttribute)) + { + var args = cad.ConstructorArguments; + attrs.Add(new RemappedClassAttribute((string)args[0].Value, (Type)args[1].Value)); + } + + return attrs.ToArray(); } - internal string GetAnnotationAttributeType(Type type) + internal string GetAnnotationAttributeType(ITypeSymbol type) { -#if !IMPORTER && !EXPORTER - var attr = type.GetCustomAttributes(typeof(AnnotationAttributeAttribute), false); - if (attr.Length == 1) - return ((AnnotationAttributeAttribute)attr[0]).AttributeType; + foreach (var cad in type.GetCustomAttributes(TypeOfAnnotationAttributeAttribute)) + return UnicodeUtil.UnescapeInvalidSurrogates((string)cad.ConstructorArguments[0].Value); return null; -#else - foreach (var cad in CustomAttributeData.__GetCustomAttributes(type, TypeOfAnnotationAttributeAttribute, false)) - return UnicodeUtil.UnescapeInvalidSurrogates((string)cad.ConstructorArguments[0].Value); - - return null; -#endif } - internal AssemblyName[] GetInternalsVisibleToAttributes(Assembly assembly) + internal System.Reflection.AssemblyName[] GetInternalsVisibleToAttributes(IAssemblySymbol assembly) { - var list = new List(); - foreach (var cad in CustomAttributeData.GetCustomAttributes(assembly)) + var list = new List(); + + foreach (var cad in assembly.GetCustomAttributes()) { - if (cad.Constructor.DeclaringType == context.Resolver.ResolveCoreType(typeof(InternalsVisibleToAttribute).FullName).AsReflection()) + if (cad.Constructor.DeclaringType == context.Resolver.ResolveCoreType(typeof(InternalsVisibleToAttribute).FullName)) { try { - list.Add(new AssemblyName((string)cad.ConstructorArguments[0].Value)); + list.Add(new System.Reflection.AssemblyName((string)cad.ConstructorArguments[0].Value)); } catch { @@ -1201,97 +1091,83 @@ internal AssemblyName[] GetInternalsVisibleToAttributes(Assembly assembly) return list.ToArray(); } - internal bool IsJavaModule(Module mod) + internal bool IsJavaModule(IModuleSymbol mod) { return mod.IsDefined(TypeOfJavaModuleAttribute, false); } - internal object[] GetJavaModuleAttributes(Module mod) + internal object[] GetJavaModuleAttributes(IModuleSymbol mod) { -#if !IMPORTER && !EXPORTER - return mod.GetCustomAttributes(TypeOfJavaModuleAttribute, false); -#else - List attrs = new List(); - foreach (CustomAttributeData cad in CustomAttributeData.__GetCustomAttributes(mod, TypeOfJavaModuleAttribute, false)) - { - IList args = cad.ConstructorArguments; - if (args.Count == 0) - { - attrs.Add(new JavaModuleAttribute()); - } - else - { - attrs.Add(new JavaModuleAttribute(DecodeArray(args[0]))); - } - } - return attrs.ToArray(); -#endif + var attrs = new List(); + + foreach (var cad in mod.GetCustomAttributes(TypeOfJavaModuleAttribute)) + { + var args = cad.ConstructorArguments; + if (args.Length == 0) + attrs.Add(new JavaModuleAttribute()); + else + attrs.Add(new JavaModuleAttribute(DecodeArray(args[0]))); + } + + return attrs.ToArray(); } - internal bool IsNoPackagePrefix(Type type) + internal bool IsNoPackagePrefix(ITypeSymbol type) { return type.IsDefined(TypeOfNoPackagePrefixAttribute, false) || type.Assembly.IsDefined(TypeOfNoPackagePrefixAttribute, false); } - internal bool HasEnclosingMethodAttribute(Type type) + internal bool HasEnclosingMethodAttribute(ITypeSymbol type) { return type.IsDefined(TypeOfEnclosingMethodAttribute, false); } - internal IKVM.Attributes.EnclosingMethodAttribute GetEnclosingMethodAttribute(Type type) + internal IKVM.Attributes.EnclosingMethodAttribute GetEnclosingMethodAttribute(ITypeSymbol type) { -#if !IMPORTER && !EXPORTER - var attr = type.GetCustomAttributes(typeof(IKVM.Attributes.EnclosingMethodAttribute), false); - if (attr.Length == 1) - return ((IKVM.Attributes.EnclosingMethodAttribute)attr[0]).SetClassName(context, type); + foreach (var cad in type.GetCustomAttributes(TypeOfEnclosingMethodAttribute)) + return new IKVM.Attributes.EnclosingMethodAttribute((string)cad.ConstructorArguments[0].Value, (string)cad.ConstructorArguments[1].Value, (string)cad.ConstructorArguments[2].Value).SetClassName(context, type.AsReflection()); return null; -#else - foreach (var cad in CustomAttributeData.__GetCustomAttributes(type, TypeOfEnclosingMethodAttribute, false)) - return new IKVM.Attributes.EnclosingMethodAttribute((string)cad.ConstructorArguments[0].Value, (string)cad.ConstructorArguments[1].Value, (string)cad.ConstructorArguments[2].Value).SetClassName(context, type); - - return null; -#endif } #if IMPORTER - internal void SetRemappedClass(AssemblyBuilder assemblyBuilder, string name, Type shadowType) - { - var remappedClassAttribute = TypeOfRemappedClassAttribute.GetConstructor(new Type[] { context.Types.String, context.Types.Type }); - assemblyBuilder.SetCustomAttribute(new CustomAttributeBuilder(remappedClassAttribute, new object[] { name, shadowType })); - } - - internal void SetRemappedType(TypeBuilder typeBuilder, Type shadowType) - { - var remappedTypeAttribute = TypeOfRemappedTypeAttribute.GetConstructor(new Type[] { context.Types.Type }); - typeBuilder.SetCustomAttribute(new CustomAttributeBuilder(remappedTypeAttribute, new object[] { shadowType })); - } - - internal void SetRemappedInterfaceMethod(TypeBuilder typeBuilder, string name, string mappedTo, string[] throws) - { - var cab = new CustomAttributeBuilder(TypeOfRemappedInterfaceMethodAttribute.GetConstructor(new Type[] { context.Types.String, context.Types.String, context.Types.String.MakeArrayType() }), new object[] { name, mappedTo, throws }); - typeBuilder.SetCustomAttribute(cab); - } - - internal void SetExceptionIsUnsafeForMapping(TypeBuilder typeBuilder) - { - var cab = new CustomAttributeBuilder(TypeOfExceptionIsUnsafeForMappingAttribute.GetConstructor(Type.EmptyTypes), Array.Empty()); - typeBuilder.SetCustomAttribute(cab); - } + internal void SetRemappedClass(AssemblyBuilder assemblyBuilder, string name, ITypeSymbol shadowType) + { + var remappedClassAttribute = TypeOfRemappedClassAttribute.GetConstructor([context.Types.String, context.Types.Type]); + assemblyBuilder.SetCustomAttribute(new CustomAttributeBuilder(remappedClassAttribute.AsReflection(), [name, shadowType])); + } + + internal void SetRemappedType(TypeBuilder typeBuilder, ITypeSymbol shadowType) + { + var remappedTypeAttribute = TypeOfRemappedTypeAttribute.GetConstructor([context.Types.Type]); + typeBuilder.SetCustomAttribute(new CustomAttributeBuilder(remappedTypeAttribute.AsReflection(), [shadowType])); + } + + internal void SetRemappedInterfaceMethod(TypeBuilder typeBuilder, string name, string mappedTo, string[] throws) + { + var cab = new CustomAttributeBuilder(TypeOfRemappedInterfaceMethodAttribute.GetConstructor([context.Types.String, context.Types.String, context.Types.String.MakeArrayType()]).AsReflection(), [name, mappedTo, throws]); + typeBuilder.SetCustomAttribute(cab); + } + + internal void SetExceptionIsUnsafeForMapping(TypeBuilder typeBuilder) + { + var cab = new CustomAttributeBuilder(TypeOfExceptionIsUnsafeForMappingAttribute.GetConstructor([]).AsReflection(), Array.Empty()); + typeBuilder.SetCustomAttribute(cab); + } #endif internal void SetRuntimeCompatibilityAttribute(AssemblyBuilder assemblyBuilder) { - var runtimeCompatibilityAttribute = context.Resolver.ResolveCoreType(typeof(RuntimeCompatibilityAttribute).FullName).AsReflection(); - assemblyBuilder.SetCustomAttribute(new CustomAttributeBuilder(runtimeCompatibilityAttribute.GetConstructor(Type.EmptyTypes), Array.Empty(), new PropertyInfo[] { runtimeCompatibilityAttribute.GetProperty("WrapNonExceptionThrows") }, new object[] { true }, Array.Empty(), Array.Empty())); + var runtimeCompatibilityAttribute = context.Resolver.ResolveCoreType(typeof(RuntimeCompatibilityAttribute).FullName); + assemblyBuilder.SetCustomAttribute(new CustomAttributeBuilder(runtimeCompatibilityAttribute.GetConstructor([]).AsReflection(), [], [runtimeCompatibilityAttribute.GetProperty("WrapNonExceptionThrows").AsReflection()], [true], [], [])); } internal void SetInternalsVisibleToAttribute(AssemblyBuilder assemblyBuilder, string assemblyName) { - var internalsVisibleToAttribute = context.Resolver.ResolveCoreType(typeof(InternalsVisibleToAttribute).FullName).AsReflection(); - var cab = new CustomAttributeBuilder(internalsVisibleToAttribute.GetConstructor(new Type[] { context.Types.String }), new object[] { assemblyName }); + var internalsVisibleToAttribute = context.Resolver.ResolveCoreType(typeof(InternalsVisibleToAttribute).FullName); + var cab = new CustomAttributeBuilder(internalsVisibleToAttribute.GetConstructor([context.Types.String]).AsReflection(), [assemblyName]); assemblyBuilder.SetCustomAttribute(cab); } diff --git a/src/IKVM.Runtime/Attributes/LineNumberTableAttribute.cs b/src/IKVM.Runtime/Attributes/LineNumberTableAttribute.cs index 2ce05c73c..eeafb50c1 100644 --- a/src/IKVM.Runtime/Attributes/LineNumberTableAttribute.cs +++ b/src/IKVM.Runtime/Attributes/LineNumberTableAttribute.cs @@ -27,114 +27,115 @@ namespace IKVM.Attributes { [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor)] - public sealed class LineNumberTableAttribute : Attribute - { - - private byte[] table; - - public LineNumberTableAttribute(ushort lineno) - { - LineNumberWriter w = new LineNumberWriter(1); - w.AddMapping(0, lineno); - table = w.ToArray(); - } - - public LineNumberTableAttribute(byte[] table) - { - this.table = table; - } - - public sealed class LineNumberWriter - { - private System.IO.MemoryStream stream; - private int prevILOffset; - private int prevLineNum; - private int count; - - public LineNumberWriter(int estimatedCount) - { - stream = new System.IO.MemoryStream(estimatedCount * 2); - } - - public void AddMapping(int ilOffset, int linenumber) - { - if(count == 0) - { - if(ilOffset == 0 && linenumber != 0) - { - prevLineNum = linenumber; - count++; - WritePackedInteger(linenumber - (64 + 50)); - return; - } - else - { - prevLineNum = linenumber & ~3; - WritePackedInteger(((-prevLineNum / 4) - (64 + 50))); - } - } - bool pc_overflow; - bool lineno_overflow; - byte lead; - int deltaPC = ilOffset - prevILOffset; - if(deltaPC >= 0 && deltaPC < 31) - { - lead = (byte)deltaPC; - pc_overflow = false; - } - else - { - lead = (byte)31; - pc_overflow = true; - } - int deltaLineNo = linenumber - prevLineNum; - const int bias = 2; - if(deltaLineNo >= -bias && deltaLineNo < 7 - bias) - { - lead |= (byte)((deltaLineNo + bias) << 5); - lineno_overflow = false; - } - else - { - lead |= (byte)(7 << 5); - lineno_overflow = true; - } - stream.WriteByte(lead); - if(pc_overflow) - { - WritePackedInteger(deltaPC - (64 + 31)); - } - if(lineno_overflow) - { - WritePackedInteger(deltaLineNo); - } - prevILOffset = ilOffset; - prevLineNum = linenumber; - count++; - } - - public int Count - { - get - { - return count; - } - } - - public int LineNo - { - get - { - return prevLineNum; - } - } - - public byte[] ToArray() - { - return stream.ToArray(); - } - - /* + public sealed class LineNumberTableAttribute : Attribute + { + + private byte[] table; + + public LineNumberTableAttribute(ushort lineno) + { + LineNumberWriter w = new LineNumberWriter(1); + w.AddMapping(0, lineno); + table = w.ToArray(); + } + + public LineNumberTableAttribute(byte[] table) + { + this.table = table; + } + + public sealed class LineNumberWriter + { + + System.IO.MemoryStream stream; + int prevILOffset; + int prevLineNum; + int count; + + public LineNumberWriter(int estimatedCount) + { + stream = new System.IO.MemoryStream(estimatedCount * 2); + } + + public void AddMapping(int ilOffset, int linenumber) + { + if (count == 0) + { + if (ilOffset == 0 && linenumber != 0) + { + prevLineNum = linenumber; + count++; + WritePackedInteger(linenumber - (64 + 50)); + return; + } + else + { + prevLineNum = linenumber & ~3; + WritePackedInteger(((-prevLineNum / 4) - (64 + 50))); + } + } + bool pc_overflow; + bool lineno_overflow; + byte lead; + int deltaPC = ilOffset - prevILOffset; + if (deltaPC >= 0 && deltaPC < 31) + { + lead = (byte)deltaPC; + pc_overflow = false; + } + else + { + lead = (byte)31; + pc_overflow = true; + } + int deltaLineNo = linenumber - prevLineNum; + const int bias = 2; + if (deltaLineNo >= -bias && deltaLineNo < 7 - bias) + { + lead |= (byte)((deltaLineNo + bias) << 5); + lineno_overflow = false; + } + else + { + lead |= (byte)(7 << 5); + lineno_overflow = true; + } + stream.WriteByte(lead); + if (pc_overflow) + { + WritePackedInteger(deltaPC - (64 + 31)); + } + if (lineno_overflow) + { + WritePackedInteger(deltaLineNo); + } + prevILOffset = ilOffset; + prevLineNum = linenumber; + count++; + } + + public int Count + { + get + { + return count; + } + } + + public int LineNo + { + get + { + return prevLineNum; + } + } + + public byte[] ToArray() + { + return stream.ToArray(); + } + + /* * packed integer format: * ---------------------- * @@ -145,109 +146,109 @@ public byte[] ToArray() * E0 - FE Reserved * FF Five byte integer */ - private void WritePackedInteger(int val) - { - if(val >= -64 && val < 64) - { - val += 64; - stream.WriteByte((byte)val); - } - else if(val >= -8192 && val < 8192) - { - val += 8192; - stream.WriteByte((byte)(0x80 + (val >> 8))); - stream.WriteByte((byte)val); - } - else if(val >= -1048576 && val < 1048576) - { - val += 1048576; - stream.WriteByte((byte)(0xC0 + (val >> 16))); - stream.WriteByte((byte)(val >> 8)); - stream.WriteByte((byte)val); - } - else - { - stream.WriteByte(0xFF); - stream.WriteByte((byte)(val >> 24)); - stream.WriteByte((byte)(val >> 16)); - stream.WriteByte((byte)(val >> 8)); - stream.WriteByte((byte)(val >> 0)); - } - } - } - - private int ReadPackedInteger(ref int position) - { - byte b = table[position++]; - if(b < 128) - { - return b - 64; - } - else if((b & 0xC0) == 0x80) - { - return ((b & 0x7F) << 8) + table[position++] - 8192; - } - else if((b & 0xE0) == 0xC0) - { - int val = ((b & 0x3F) << 16); - val += (table[position++] << 8); - val += table[position++]; - return val - 1048576; - } - else if(b == 0xFF) - { - int val = table[position++] << 24; - val += table[position++] << 16; - val += table[position++] << 8; - val += table[position++] << 0; - return val; - } - else - { - throw new InvalidProgramException(); - } - } - - public int GetLineNumber(int ilOffset) - { - int i = 0; - int prevILOffset = 0; - int prevLineNum = ReadPackedInteger(ref i) + (64 + 50); - int line; - if(prevLineNum > 0) - { - line = prevLineNum; - } - else - { - prevLineNum = 4 * -prevLineNum; - line = -1; - } - while(i < table.Length) - { - byte lead = table[i++]; - int deltaPC = lead & 31; - int deltaLineNo = (lead >> 5) - 2; - if(deltaPC == 31) - { - deltaPC = ReadPackedInteger(ref i) + (64 + 31); - } - if(deltaLineNo == 5) - { - deltaLineNo = ReadPackedInteger(ref i); - } - int currILOffset = prevILOffset + deltaPC; - if(currILOffset > ilOffset) - { - return line; - } - line = prevLineNum + deltaLineNo; - prevILOffset = currILOffset; - prevLineNum = line; - } - return line; - } - - } + private void WritePackedInteger(int val) + { + if (val >= -64 && val < 64) + { + val += 64; + stream.WriteByte((byte)val); + } + else if (val >= -8192 && val < 8192) + { + val += 8192; + stream.WriteByte((byte)(0x80 + (val >> 8))); + stream.WriteByte((byte)val); + } + else if (val >= -1048576 && val < 1048576) + { + val += 1048576; + stream.WriteByte((byte)(0xC0 + (val >> 16))); + stream.WriteByte((byte)(val >> 8)); + stream.WriteByte((byte)val); + } + else + { + stream.WriteByte(0xFF); + stream.WriteByte((byte)(val >> 24)); + stream.WriteByte((byte)(val >> 16)); + stream.WriteByte((byte)(val >> 8)); + stream.WriteByte((byte)(val >> 0)); + } + } + } + + private int ReadPackedInteger(ref int position) + { + byte b = table[position++]; + if (b < 128) + { + return b - 64; + } + else if ((b & 0xC0) == 0x80) + { + return ((b & 0x7F) << 8) + table[position++] - 8192; + } + else if ((b & 0xE0) == 0xC0) + { + int val = ((b & 0x3F) << 16); + val += (table[position++] << 8); + val += table[position++]; + return val - 1048576; + } + else if (b == 0xFF) + { + int val = table[position++] << 24; + val += table[position++] << 16; + val += table[position++] << 8; + val += table[position++] << 0; + return val; + } + else + { + throw new InvalidProgramException(); + } + } + + public int GetLineNumber(int ilOffset) + { + int i = 0; + int prevILOffset = 0; + int prevLineNum = ReadPackedInteger(ref i) + (64 + 50); + int line; + if (prevLineNum > 0) + { + line = prevLineNum; + } + else + { + prevLineNum = 4 * -prevLineNum; + line = -1; + } + while (i < table.Length) + { + byte lead = table[i++]; + int deltaPC = lead & 31; + int deltaLineNo = (lead >> 5) - 2; + if (deltaPC == 31) + { + deltaPC = ReadPackedInteger(ref i) + (64 + 31); + } + if (deltaLineNo == 5) + { + deltaLineNo = ReadPackedInteger(ref i); + } + int currILOffset = prevILOffset + deltaPC; + if (currILOffset > ilOffset) + { + return line; + } + line = prevLineNum + deltaLineNo; + prevILOffset = currILOffset; + prevLineNum = line; + } + return line; + } + + } } diff --git a/src/IKVM.Runtime/ByteCodeHelperMethods.cs b/src/IKVM.Runtime/ByteCodeHelperMethods.cs index 666a21a67..e0691d5f2 100644 --- a/src/IKVM.Runtime/ByteCodeHelperMethods.cs +++ b/src/IKVM.Runtime/ByteCodeHelperMethods.cs @@ -21,20 +21,13 @@ Jeroen Frijters jeroen@frijters.net */ -using System; +using System.Reflection; using IKVM.CoreLib.Diagnostics; -using IKVM.CoreLib.Symbols.IkvmReflection; -using IKVM.CoreLib.Symbols.Reflection; +using IKVM.CoreLib.Symbols; #if IMPORTER -using IKVM.Reflection; -using IKVM.Reflection.Emit; using IKVM.Tools.Importer; - -using Type = IKVM.Reflection.Type; -#else -using System.Reflection; #endif namespace IKVM.Runtime @@ -45,64 +38,64 @@ namespace IKVM.Runtime class ByteCodeHelperMethods { - internal readonly MethodInfo multianewarray; - internal readonly MethodInfo multianewarray_ghost; - internal readonly MethodInfo anewarray_ghost; - internal readonly MethodInfo f2i; - internal readonly MethodInfo d2i; - internal readonly MethodInfo f2l; - internal readonly MethodInfo d2l; - internal readonly MethodInfo arraycopy_fast; - internal readonly MethodInfo arraycopy_primitive_8; - internal readonly MethodInfo arraycopy_primitive_4; - internal readonly MethodInfo arraycopy_primitive_2; - internal readonly MethodInfo arraycopy_primitive_1; - internal readonly MethodInfo arraycopy; - internal readonly MethodInfo DynamicCast; - internal readonly MethodInfo DynamicAaload; - internal readonly MethodInfo DynamicAastore; - internal readonly MethodInfo DynamicClassLiteral; - internal readonly MethodInfo DynamicMultianewarray; - internal readonly MethodInfo DynamicNewarray; - internal readonly MethodInfo DynamicNewCheckOnly; - internal readonly MethodInfo DynamicCreateDelegate; - internal readonly MethodInfo DynamicLoadMethodType; - internal readonly MethodInfo DynamicLoadMethodHandle; - internal readonly MethodInfo DynamicBinderMemberLookup; - internal readonly MethodInfo DynamicMapException; - internal readonly MethodInfo DynamicCallerID; - internal readonly MethodInfo DynamicLinkIndyCallSite; - internal readonly MethodInfo DynamicEraseInvokeExact; - internal readonly MethodInfo VerboseCastFailure; - internal readonly MethodInfo SkipFinalizer; - internal readonly MethodInfo SkipFinalizerOf; - internal readonly MethodInfo DynamicInstanceOf; - internal readonly MethodInfo VolatileReadBoolean; - internal readonly MethodInfo VolatileReadByte; - internal readonly MethodInfo VolatileReadChar; - internal readonly MethodInfo VolatileReadShort; - internal readonly MethodInfo VolatileReadInt; - internal readonly MethodInfo VolatileReadLong; - internal readonly MethodInfo VolatileReadFloat; - internal readonly MethodInfo VolatileReadDouble; - internal readonly MethodInfo VolatileWriteBoolean; - internal readonly MethodInfo VolatileWriteByte; - internal readonly MethodInfo VolatileWriteChar; - internal readonly MethodInfo VolatileWriteShort; - internal readonly MethodInfo VolatileWriteInt; - internal readonly MethodInfo VolatileWriteLong; - internal readonly MethodInfo VolatileWriteFloat; - internal readonly MethodInfo VolatileWriteDouble; - internal readonly MethodInfo CompareAndSwapObject; - internal readonly MethodInfo CompareAndSwapInt; - internal readonly MethodInfo CompareAndSwapLong; - internal readonly MethodInfo CompareAndSwapDouble; - internal readonly MethodInfo MapException; - internal readonly MethodInfo GetDelegateForInvokeExact; - internal readonly MethodInfo GetDelegateForInvoke; - internal readonly MethodInfo GetDelegateForInvokeBasic; - internal readonly MethodInfo LoadMethodType; - internal readonly MethodInfo LinkIndyCallSite; + internal readonly IMethodSymbol multianewarray; + internal readonly IMethodSymbol multianewarray_ghost; + internal readonly IMethodSymbol anewarray_ghost; + internal readonly IMethodSymbol f2i; + internal readonly IMethodSymbol d2i; + internal readonly IMethodSymbol f2l; + internal readonly IMethodSymbol d2l; + internal readonly IMethodSymbol arraycopy_fast; + internal readonly IMethodSymbol arraycopy_primitive_8; + internal readonly IMethodSymbol arraycopy_primitive_4; + internal readonly IMethodSymbol arraycopy_primitive_2; + internal readonly IMethodSymbol arraycopy_primitive_1; + internal readonly IMethodSymbol arraycopy; + internal readonly IMethodSymbol DynamicCast; + internal readonly IMethodSymbol DynamicAaload; + internal readonly IMethodSymbol DynamicAastore; + internal readonly IMethodSymbol DynamicClassLiteral; + internal readonly IMethodSymbol DynamicMultianewarray; + internal readonly IMethodSymbol DynamicNewarray; + internal readonly IMethodSymbol DynamicNewCheckOnly; + internal readonly IMethodSymbol DynamicCreateDelegate; + internal readonly IMethodSymbol DynamicLoadMethodType; + internal readonly IMethodSymbol DynamicLoadMethodHandle; + internal readonly IMethodSymbol DynamicBinderMemberLookup; + internal readonly IMethodSymbol DynamicMapException; + internal readonly IMethodSymbol DynamicCallerID; + internal readonly IMethodSymbol DynamicLinkIndyCallSite; + internal readonly IMethodSymbol DynamicEraseInvokeExact; + internal readonly IMethodSymbol VerboseCastFailure; + internal readonly IMethodSymbol SkipFinalizer; + internal readonly IMethodSymbol SkipFinalizerOf; + internal readonly IMethodSymbol DynamicInstanceOf; + internal readonly IMethodSymbol VolatileReadBoolean; + internal readonly IMethodSymbol VolatileReadByte; + internal readonly IMethodSymbol VolatileReadChar; + internal readonly IMethodSymbol VolatileReadShort; + internal readonly IMethodSymbol VolatileReadInt; + internal readonly IMethodSymbol VolatileReadLong; + internal readonly IMethodSymbol VolatileReadFloat; + internal readonly IMethodSymbol VolatileReadDouble; + internal readonly IMethodSymbol VolatileWriteBoolean; + internal readonly IMethodSymbol VolatileWriteByte; + internal readonly IMethodSymbol VolatileWriteChar; + internal readonly IMethodSymbol VolatileWriteShort; + internal readonly IMethodSymbol VolatileWriteInt; + internal readonly IMethodSymbol VolatileWriteLong; + internal readonly IMethodSymbol VolatileWriteFloat; + internal readonly IMethodSymbol VolatileWriteDouble; + internal readonly IMethodSymbol CompareAndSwapObject; + internal readonly IMethodSymbol CompareAndSwapInt; + internal readonly IMethodSymbol CompareAndSwapLong; + internal readonly IMethodSymbol CompareAndSwapDouble; + internal readonly IMethodSymbol MapException; + internal readonly IMethodSymbol GetDelegateForInvokeExact; + internal readonly IMethodSymbol GetDelegateForInvoke; + internal readonly IMethodSymbol GetDelegateForInvokeBasic; + internal readonly IMethodSymbol LoadMethodType; + internal readonly IMethodSymbol LinkIndyCallSite; /// /// Initializes a new instance. @@ -110,11 +103,7 @@ class ByteCodeHelperMethods /// public ByteCodeHelperMethods(RuntimeContext context) { -#if IMPORTER || EXPORTER - var typeofByteCodeHelper = ((IkvmReflectionTypeSymbol)context.Resolver.ResolveRuntimeType("IKVM.Runtime.ByteCodeHelper")).ReflectionObject; -#else - var typeofByteCodeHelper = ((ReflectionTypeSymbol)context.Resolver.ResolveRuntimeType("IKVM.Runtime.ByteCodeHelper")).ReflectionObject; -#endif + var typeofByteCodeHelper = context.Resolver.ResolveRuntimeType("IKVM.Runtime.ByteCodeHelper"); multianewarray = GetHelper(typeofByteCodeHelper, "multianewarray"); multianewarray_ghost = GetHelper(typeofByteCodeHelper, "multianewarray_ghost"); anewarray_ghost = GetHelper(typeofByteCodeHelper, "anewarray_ghost"); @@ -144,29 +133,29 @@ public ByteCodeHelperMethods(RuntimeContext context) DynamicLinkIndyCallSite = GetHelper(typeofByteCodeHelper, "DynamicLinkIndyCallSite"); DynamicEraseInvokeExact = GetHelper(typeofByteCodeHelper, "DynamicEraseInvokeExact"); VerboseCastFailure = GetHelper(typeofByteCodeHelper, "VerboseCastFailure"); - SkipFinalizer = GetHelper(typeofByteCodeHelper, "SkipFinalizer", new Type[] { }); - SkipFinalizerOf = GetHelper(typeofByteCodeHelper, "SkipFinalizer", new Type[] { context.Types.Object }); + SkipFinalizer = GetHelper(typeofByteCodeHelper, "SkipFinalizer", []); + SkipFinalizerOf = GetHelper(typeofByteCodeHelper, "SkipFinalizer", [context.Types.Object]); DynamicInstanceOf = GetHelper(typeofByteCodeHelper, "DynamicInstanceOf"); - VolatileReadBoolean = GetHelper(typeofByteCodeHelper, "VolatileRead", new Type[] { context.Types.Boolean.MakeByRefType() }); - VolatileReadByte = GetHelper(typeofByteCodeHelper, "VolatileRead", new Type[] { context.Types.Byte.MakeByRefType() }); - VolatileReadChar = GetHelper(typeofByteCodeHelper, "VolatileRead", new Type[] { context.Types.Char.MakeByRefType() }); - VolatileReadShort = GetHelper(typeofByteCodeHelper, "VolatileRead", new Type[] { context.Types.Int16.MakeByRefType() }); - VolatileReadInt = GetHelper(typeofByteCodeHelper, "VolatileRead", new Type[] { context.Types.Int32.MakeByRefType() }); - VolatileReadLong = GetHelper(typeofByteCodeHelper, "VolatileRead", new Type[] { context.Types.Int64.MakeByRefType() }); - VolatileReadFloat = GetHelper(typeofByteCodeHelper, "VolatileRead", new Type[] { context.Types.Single.MakeByRefType() }); - VolatileReadDouble = GetHelper(typeofByteCodeHelper, "VolatileRead", new Type[] { context.Types.Double.MakeByRefType() }); - VolatileWriteBoolean = GetHelper(typeofByteCodeHelper, "VolatileWrite", new Type[] { context.Types.Boolean.MakeByRefType(), context.Types.Boolean }); - VolatileWriteByte = GetHelper(typeofByteCodeHelper, "VolatileWrite", new Type[] { context.Types.Byte.MakeByRefType(), context.Types.Byte }); - VolatileWriteChar = GetHelper(typeofByteCodeHelper, "VolatileWrite", new Type[] { context.Types.Char.MakeByRefType(), context.Types.Char }); - VolatileWriteShort = GetHelper(typeofByteCodeHelper, "VolatileWrite", new Type[] { context.Types.Int16.MakeByRefType(), context.Types.Int16 }); - VolatileWriteInt = GetHelper(typeofByteCodeHelper, "VolatileWrite", new Type[] { context.Types.Int32.MakeByRefType(), context.Types.Int32 }); - VolatileWriteLong = GetHelper(typeofByteCodeHelper, "VolatileWrite", new Type[] { context.Types.Int64.MakeByRefType(), context.Types.Int64 }); - VolatileWriteFloat = GetHelper(typeofByteCodeHelper, "VolatileWrite", new Type[] { context.Types.Single.MakeByRefType(), context.Types.Single }); - VolatileWriteDouble = GetHelper(typeofByteCodeHelper, "VolatileWrite", new Type[] { context.Types.Double.MakeByRefType(), context.Types.Double }); - CompareAndSwapObject = GetHelper(typeofByteCodeHelper, "CompareAndSwap", new[] { context.Types.Object.MakeByRefType(), context.Types.Object, context.Types.Object }); - CompareAndSwapInt = GetHelper(typeofByteCodeHelper, "CompareAndSwap", new[] { context.Types.Int32.MakeByRefType(), context.Types.Int32, context.Types.Int32 }); - CompareAndSwapLong = GetHelper(typeofByteCodeHelper, "CompareAndSwap", new[] { context.Types.Int64.MakeByRefType(), context.Types.Int64, context.Types.Int64 }); - CompareAndSwapDouble = GetHelper(typeofByteCodeHelper, "CompareAndSwap", new[] { context.Types.Double.MakeByRefType(), context.Types.Double, context.Types.Double }); + VolatileReadBoolean = GetHelper(typeofByteCodeHelper, "VolatileRead", [context.Types.Boolean.MakeByRefType()]); + VolatileReadByte = GetHelper(typeofByteCodeHelper, "VolatileRead", [context.Types.Byte.MakeByRefType()]); + VolatileReadChar = GetHelper(typeofByteCodeHelper, "VolatileRead", [context.Types.Char.MakeByRefType()]); + VolatileReadShort = GetHelper(typeofByteCodeHelper, "VolatileRead", [context.Types.Int16.MakeByRefType()]); + VolatileReadInt = GetHelper(typeofByteCodeHelper, "VolatileRead", [context.Types.Int32.MakeByRefType()]); + VolatileReadLong = GetHelper(typeofByteCodeHelper, "VolatileRead", [context.Types.Int64.MakeByRefType()]); + VolatileReadFloat = GetHelper(typeofByteCodeHelper, "VolatileRead", [context.Types.Single.MakeByRefType()]); + VolatileReadDouble = GetHelper(typeofByteCodeHelper, "VolatileRead", [context.Types.Double.MakeByRefType()]); + VolatileWriteBoolean = GetHelper(typeofByteCodeHelper, "VolatileWrite", [context.Types.Boolean.MakeByRefType(), context.Types.Boolean]); + VolatileWriteByte = GetHelper(typeofByteCodeHelper, "VolatileWrite", [context.Types.Byte.MakeByRefType(), context.Types.Byte]); + VolatileWriteChar = GetHelper(typeofByteCodeHelper, "VolatileWrite", [context.Types.Char.MakeByRefType(), context.Types.Char]); + VolatileWriteShort = GetHelper(typeofByteCodeHelper, "VolatileWrite", [context.Types.Int16.MakeByRefType(), context.Types.Int16]); + VolatileWriteInt = GetHelper(typeofByteCodeHelper, "VolatileWrite", [context.Types.Int32.MakeByRefType(), context.Types.Int32]); + VolatileWriteLong = GetHelper(typeofByteCodeHelper, "VolatileWrite", [context.Types.Int64.MakeByRefType(), context.Types.Int64]); + VolatileWriteFloat = GetHelper(typeofByteCodeHelper, "VolatileWrite", [context.Types.Single.MakeByRefType(), context.Types.Single]); + VolatileWriteDouble = GetHelper(typeofByteCodeHelper, "VolatileWrite", [context.Types.Double.MakeByRefType(), context.Types.Double]); + CompareAndSwapObject = GetHelper(typeofByteCodeHelper, "CompareAndSwap", [context.Types.Object.MakeByRefType(), context.Types.Object, context.Types.Object]); + CompareAndSwapInt = GetHelper(typeofByteCodeHelper, "CompareAndSwap", [context.Types.Int32.MakeByRefType(), context.Types.Int32, context.Types.Int32]); + CompareAndSwapLong = GetHelper(typeofByteCodeHelper, "CompareAndSwap", [context.Types.Int64.MakeByRefType(), context.Types.Int64, context.Types.Int64]); + CompareAndSwapDouble = GetHelper(typeofByteCodeHelper, "CompareAndSwap", [context.Types.Double.MakeByRefType(), context.Types.Double, context.Types.Double]); MapException = GetHelper(typeofByteCodeHelper, "MapException"); GetDelegateForInvokeExact = GetHelper(typeofByteCodeHelper, "GetDelegateForInvokeExact"); GetDelegateForInvoke = GetHelper(typeofByteCodeHelper, "GetDelegateForInvoke"); @@ -175,12 +164,12 @@ public ByteCodeHelperMethods(RuntimeContext context) LinkIndyCallSite = GetHelper(typeofByteCodeHelper, "LinkIndyCallSite"); } - static MethodInfo GetHelper(Type type, string method) + static IMethodSymbol GetHelper(ITypeSymbol type, string method) { return GetHelper(type, method, null); } - static MethodInfo GetHelper(Type type, string method, Type[] parameters) + static IMethodSymbol GetHelper(ITypeSymbol type, string method, ITypeSymbol[] parameters) { var mi = parameters == null ? type.GetMethod(method) : type.GetMethod(method, parameters); if (mi == null) diff --git a/src/IKVM.Runtime/CodeEmitter.cs b/src/IKVM.Runtime/CodeEmitter.cs index 91a05f0c5..0d17bb213 100644 --- a/src/IKVM.Runtime/CodeEmitter.cs +++ b/src/IKVM.Runtime/CodeEmitter.cs @@ -27,11 +27,11 @@ Jeroen Frijters using System.Diagnostics.SymbolStore; using System.Diagnostics; +using IKVM.CoreLib.Symbols; + #if IMPORTER using IKVM.Reflection; using IKVM.Reflection.Emit; - -using Type = IKVM.Reflection.Type; #else using System.Reflection; using System.Reflection.Emit; @@ -45,11 +45,11 @@ class CodeEmitterFactory readonly RuntimeContext context; - MethodInfo objectToString; - MethodInfo verboseCastFailure; - MethodInfo monitorEnter; - MethodInfo monitorExit; - MethodInfo memoryBarrier; + IMethodSymbol objectToString; + IMethodSymbol verboseCastFailure; + IMethodSymbol monitorEnter; + IMethodSymbol monitorExit; + IMethodSymbol memoryBarrier; /// /// Initializes a new instance. @@ -60,15 +60,15 @@ public CodeEmitterFactory(RuntimeContext context) this.context = context ?? throw new ArgumentNullException(nameof(context)); } - public MethodInfo ObjectToStringMethod => objectToString ??= context.Types.Object.GetMethod("ToString", BindingFlags.Public | BindingFlags.Instance, null, [], null); + public IMethodSymbol ObjectToStringMethod => objectToString ??= context.Types.Object.GetMethod("ToString", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance, []); - public MethodInfo VerboseCastFailureMethod => verboseCastFailure ??= JVM.SafeGetEnvironmentVariable("IKVM_VERBOSE_CAST") == null ? null : context.ByteCodeHelperMethods.VerboseCastFailure; + public IMethodSymbol VerboseCastFailureMethod => verboseCastFailure ??= JVM.SafeGetEnvironmentVariable("IKVM_VERBOSE_CAST") == null ? null : context.ByteCodeHelperMethods.VerboseCastFailure; - public MethodInfo MonitorEnterMethod => monitorEnter ??= context.Resolver.ResolveCoreType(typeof(System.Threading.Monitor).FullName).AsReflection().GetMethod("Enter", BindingFlags.Public | BindingFlags.Static, null, [context.Types.Object], null); + public IMethodSymbol MonitorEnterMethod => monitorEnter ??= context.Resolver.ResolveCoreType(typeof(System.Threading.Monitor).FullName).GetMethod("Enter", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static, [context.Types.Object]); - public MethodInfo MonitorExitMethod => monitorExit ??= context.Resolver.ResolveCoreType(typeof(System.Threading.Monitor).FullName).AsReflection().GetMethod("Exit", BindingFlags.Public | BindingFlags.Static, null, [context.Types.Object], null); + public IMethodSymbol MonitorExitMethod => monitorExit ??= context.Resolver.ResolveCoreType(typeof(System.Threading.Monitor).FullName).GetMethod("Exit", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static, [context.Types.Object]); - public MethodInfo MemoryBarrierMethod => memoryBarrier ??= context.Resolver.ResolveCoreType(typeof(System.Threading.Thread).FullName).GetMethod("MemoryBarrier", []).AsReflection(); + public IMethodSymbol MemoryBarrierMethod => memoryBarrier ??= context.Resolver.ResolveCoreType(typeof(System.Threading.Thread).FullName).GetMethod("MemoryBarrier", []); public bool ExperimentalOptimizations = JVM.SafeGetEnvironmentVariable("IKVM_EXPERIMENTAL_OPTIMIZATIONS") != null; @@ -79,7 +79,7 @@ public CodeEmitterFactory(RuntimeContext context) /// public CodeEmitter Create(MethodBuilder mb) { - return new CodeEmitter(context, mb.GetILGenerator(), mb.DeclaringType); + return new CodeEmitter(context, mb.GetILGenerator(), context.Resolver.ResolveType(mb.DeclaringType)); } #if IMPORTER == false @@ -110,7 +110,7 @@ sealed class CodeEmitter CodeEmitterLocal[] tempLocals = new CodeEmitterLocal[32]; ISymbolDocumentWriter symbols; List code = new List(10); - readonly Type declaringType; + readonly ITypeSymbol declaringType; enum CodeType : short { @@ -216,11 +216,11 @@ internal OpCodeWrapper(OpCode opcode, object data) internal long ValueInt64 => (long)data; - internal Type Type => (Type)data; + internal ITypeSymbol Type => (ITypeSymbol)data; - internal FieldInfo FieldInfo => (FieldInfo)data; + internal IFieldSymbol FieldInfo => (IFieldSymbol)data; - internal MethodBase MethodBase => (MethodBase)data; + internal IMethodBaseSymbol MethodBase => (IMethodBaseSymbol)data; internal void RealEmit(int ilOffset, CodeEmitter codeEmitter, ref int lineNumber) { @@ -254,14 +254,14 @@ sealed class CalliWrapper { internal readonly CallingConvention unmanagedCallConv; - internal readonly Type returnType; - internal readonly Type[] parameterTypes; + internal readonly ITypeSymbol returnType; + internal readonly ITypeSymbol[] parameterTypes; - internal CalliWrapper(CallingConvention unmanagedCallConv, Type returnType, Type[] parameterTypes) + internal CalliWrapper(CallingConvention unmanagedCallConv, ITypeSymbol returnType, ITypeSymbol[] parameterTypes) { this.unmanagedCallConv = unmanagedCallConv; this.returnType = returnType; - this.parameterTypes = parameterTypes == null ? null : (Type[])parameterTypes.Clone(); + this.parameterTypes = parameterTypes == null ? null : (ITypeSymbol[])parameterTypes.Clone(); } } @@ -270,16 +270,16 @@ sealed class ManagedCalliWrapper { internal readonly CallingConventions callConv; - internal readonly Type returnType; - internal readonly Type[] parameterTypes; - internal readonly Type[] optionalParameterTypes; + internal readonly ITypeSymbol returnType; + internal readonly ITypeSymbol[] parameterTypes; + internal readonly ITypeSymbol[] optionalParameterTypes; - internal ManagedCalliWrapper(CallingConventions callConv, Type returnType, Type[] parameterTypes, Type[] optionalParameterTypes) + internal ManagedCalliWrapper(CallingConventions callConv, ITypeSymbol returnType, ITypeSymbol[] parameterTypes, ITypeSymbol[] optionalParameterTypes) { this.callConv = callConv; this.returnType = returnType; - this.parameterTypes = parameterTypes == null ? null : (Type[])parameterTypes.Clone(); - this.optionalParameterTypes = optionalParameterTypes == null ? null : (Type[])optionalParameterTypes.Clone(); + this.parameterTypes = parameterTypes == null ? null : (ITypeSymbol[])parameterTypes.Clone(); + this.optionalParameterTypes = optionalParameterTypes == null ? null : (ITypeSymbol[])optionalParameterTypes.Clone(); } } @@ -290,7 +290,7 @@ internal ManagedCalliWrapper(CallingConventions callConv, Type returnType, Type[ /// /// /// - public CodeEmitter(RuntimeContext context, ILGenerator ilgen, Type declaringType) + public CodeEmitter(RuntimeContext context, ILGenerator ilgen, ITypeSymbol declaringType) { this.context = context; this.ilgen_real = ilgen; @@ -345,7 +345,7 @@ private void RealEmitPseudoOpCode(int ilOffset, CodeType type, object data) ilgen_real.BeginExceptionBlock(); break; case CodeType.BeginCatchBlock: - ilgen_real.BeginCatchBlock((Type)data); + ilgen_real.BeginCatchBlock(((ITypeSymbol)data).AsReflection()); break; case CodeType.BeginFaultBlock: ilgen_real.BeginFaultBlock(); @@ -358,13 +358,13 @@ private void RealEmitPseudoOpCode(int ilOffset, CodeType type, object data) ilgen_real.Emit(OpCodes.Br_S, (sbyte)-2); // bogus target of implicit leave break; case CodeType.MemoryBarrier: - ilgen_real.Emit(OpCodes.Call, context.CodeEmitterFactory.MemoryBarrierMethod); + ilgen_real.Emit(OpCodes.Call, context.CodeEmitterFactory.MemoryBarrierMethod.AsReflection()); break; case CodeType.MonitorEnter: - ilgen_real.Emit(OpCodes.Call, context.CodeEmitterFactory.MonitorEnterMethod); + ilgen_real.Emit(OpCodes.Call, context.CodeEmitterFactory.MonitorEnterMethod.AsReflection()); break; case CodeType.MonitorExit: - ilgen_real.Emit(OpCodes.Call, context.CodeEmitterFactory.MonitorExitMethod); + ilgen_real.Emit(OpCodes.Call, context.CodeEmitterFactory.MonitorExitMethod.AsReflection()); break; case CodeType.TailCallPrevention: ilgen_real.Emit(OpCodes.Ldnull); @@ -398,17 +398,17 @@ void RealEmitOpCode(OpCode opcode, object arg) { ilgen_real.Emit(opcode, l); } - else if (arg is MethodInfo mi) + else if (arg is IMethodSymbol mi) { - ilgen_real.Emit(opcode, mi); + ilgen_real.Emit(opcode, mi.AsReflection()); } - else if (arg is ConstructorInfo ci) + else if (arg is IConstructorSymbol ci) { - ilgen_real.Emit(opcode, ci); + ilgen_real.Emit(opcode, ci.AsReflection()); } - else if (arg is FieldInfo fi) + else if (arg is IFieldSymbol fi) { - ilgen_real.Emit(opcode, fi); + ilgen_real.Emit(opcode, fi.AsReflection()); } else if (arg is sbyte sby) { @@ -434,9 +434,9 @@ void RealEmitOpCode(OpCode opcode, object arg) { ilgen_real.Emit(opcode, s); } - else if (arg is Type type) + else if (arg is ITypeSymbol type) { - ilgen_real.Emit(opcode, type); + ilgen_real.Emit(opcode, type.AsReflection()); } else if (arg is CodeEmitterLocal local) { @@ -456,11 +456,11 @@ void RealEmitOpCode(OpCode opcode, object arg) } else if (arg is ManagedCalliWrapper margs) { - ilgen_real.EmitCalli(opcode, margs.callConv, margs.returnType, margs.parameterTypes, margs.optionalParameterTypes); + ilgen_real.EmitCalli(opcode, margs.callConv, margs.returnType.AsReflection(), margs.parameterTypes.AsReflection(), margs.optionalParameterTypes.AsReflection()); } else if (arg is CalliWrapper args) { - ilgen_real.EmitCalli(opcode, args.unmanagedCallConv, args.returnType, args.parameterTypes); + ilgen_real.EmitCalli(opcode, args.unmanagedCallConv, args.returnType.AsReflection(), args.parameterTypes.AsReflection()); } else { @@ -585,7 +585,7 @@ bool IsSideEffectFreePush(int index) // when the type is initialized (which is what we mean in the rest of the IKVM code as well) // but it is good to point it out here because strictly speaking we're violating the // BeforeFieldInit contract here by considering dummy loads not to be field accesses. - if ((field.DeclaringType.Attributes & TypeAttributes.BeforeFieldInit) != 0) + if ((field.DeclaringType.Attributes & System.Reflection.TypeAttributes.BeforeFieldInit) != 0) { return true; } @@ -833,7 +833,7 @@ void OptimizePatterns() } } - bool MatchCompare(int index, OpCode cmp1, OpCode cmp2, Type type) + bool MatchCompare(int index, OpCode cmp1, OpCode cmp2, ITypeSymbol type) { return code[index].opcode == OpCodes.Stloc && code[index].Local.LocalType == type && code[index + 1].opcode == OpCodes.Stloc && code[index + 1].Local.LocalType == type @@ -2115,33 +2115,31 @@ internal void DefineSymbolDocument(ModuleBuilder module, string url, Guid langua #endif } - internal CodeEmitterLocal UnsafeAllocTempLocal(Type type) + internal CodeEmitterLocal UnsafeAllocTempLocal(ITypeSymbol type) { int free = -1; for (int i = 0; i < tempLocals.Length; i++) { - CodeEmitterLocal lb = tempLocals[i]; + var lb = tempLocals[i]; if (lb == null) { if (free == -1) - { free = i; - } } else if (lb.LocalType == type) { return lb; } } - CodeEmitterLocal lb1 = DeclareLocal(type); + + var lb1 = DeclareLocal(type); if (free != -1) - { tempLocals[free] = lb1; - } + return lb1; } - internal CodeEmitterLocal AllocTempLocal(Type type) + internal CodeEmitterLocal AllocTempLocal(ITypeSymbol type) { for (int i = 0; i < tempLocals.Length; i++) { @@ -2170,7 +2168,7 @@ internal void ReleaseTempLocal(CodeEmitterLocal lb) } } - internal void BeginCatchBlock(Type exceptionType) + internal void BeginCatchBlock(ITypeSymbol exceptionType) { EmitPseudoOpCode(CodeType.BeginCatchBlock, exceptionType); } @@ -2199,7 +2197,7 @@ internal void BeginScope() EmitPseudoOpCode(CodeType.BeginScope, null); } - internal CodeEmitterLocal DeclareLocal(Type localType) + internal CodeEmitterLocal DeclareLocal(ITypeSymbol localType) { var local = new CodeEmitterLocal(localType); EmitPseudoOpCode(CodeType.DeclareLocal, local); @@ -2221,7 +2219,7 @@ internal void EmitUnaligned(byte alignment) EmitOpCode(OpCodes.Unaligned, alignment); } - internal void Emit(OpCode opcode, MethodBase mb) + internal void Emit(OpCode opcode, IMethodBaseSymbol mb) { EmitOpCode(opcode, mb); } @@ -2231,7 +2229,7 @@ internal void EmitLdc_R8(double arg) EmitOpCode(OpCodes.Ldc_R8, arg); } - internal void Emit(OpCode opcode, FieldInfo field) + internal void Emit(OpCode opcode, IFieldSymbol field) { EmitOpCode(opcode, field); } @@ -2374,17 +2372,17 @@ internal void Emit(OpCode opcode, string arg) EmitOpCode(opcode, arg); } - internal void Emit(OpCode opcode, Type cls) + internal void Emit(OpCode opcode, ITypeSymbol cls) { EmitOpCode(opcode, cls); } - internal void EmitCalli(OpCode opcode, CallingConvention unmanagedCallConv, Type returnType, Type[] parameterTypes) + internal void EmitCalli(OpCode opcode, CallingConvention unmanagedCallConv, ITypeSymbol returnType, ITypeSymbol[] parameterTypes) { EmitOpCode(opcode, new CalliWrapper(unmanagedCallConv, returnType, parameterTypes)); } - internal void EmitCalli(OpCode opcode, CallingConventions unmanagedCallConv, Type returnType, Type[] parameterTypes, Type[] optionalParameterTypes) + internal void EmitCalli(OpCode opcode, CallingConventions unmanagedCallConv, ITypeSymbol returnType, ITypeSymbol[] parameterTypes, ITypeSymbol[] optionalParameterTypes) { EmitOpCode(opcode, new ManagedCalliWrapper(unmanagedCallConv, returnType, parameterTypes, optionalParameterTypes)); } @@ -2405,9 +2403,9 @@ internal void MarkLabel(CodeEmitterLabel loc) EmitPseudoOpCode(CodeType.Label, loc); } - internal void ThrowException(Type excType) + internal void ThrowException(ITypeSymbol excType) { - Emit(OpCodes.Newobj, excType.GetConstructor(Type.EmptyTypes)); + Emit(OpCodes.Newobj, excType.GetConstructor([])); Emit(OpCodes.Throw); } @@ -2462,7 +2460,7 @@ internal void EmitNullCheck() Emit(OpCodes.Pop); } - internal void EmitCastclass(Type type) + internal void EmitCastclass(ITypeSymbol type) { if (context.CodeEmitterFactory.VerboseCastFailureMethod != null) { @@ -2488,7 +2486,7 @@ internal void EmitCastclass(Type type) // This is basically the same as Castclass, except that it // throws an IncompatibleClassChangeError on failure. - internal void EmitAssertType(Type type) + internal void EmitAssertType(ITypeSymbol type) { var isnull = DefineLabel(); Emit(OpCodes.Dup); @@ -2504,7 +2502,7 @@ internal void EmitAssertType(Type type) MarkLabel(ok); } - internal void EmitUnboxSpecial(Type type) + internal void EmitUnboxSpecial(ITypeSymbol type) { // NOTE if the reference is null, we treat it as a default instance of the value type. var label1 = DefineLabel(); @@ -2569,7 +2567,7 @@ internal void Emit_ldiv() MarkLabel(label2); } - internal void Emit_instanceof(Type type) + internal void Emit_instanceof(ITypeSymbol type) { Emit(OpCodes.Isinst, type); Emit(OpCodes.Ldnull); @@ -2605,7 +2603,7 @@ internal void Emit_if_le_lt_ge_gt(Comparison comp, CodeEmitterLabel label) } } - private void EmitCmp(Type type, OpCode cmp1, OpCode cmp2) + private void EmitCmp(ITypeSymbol type, OpCode cmp1, OpCode cmp2) { var value1 = AllocTempLocal(type); var value2 = AllocTempLocal(type); diff --git a/src/IKVM.Runtime/CodeEmitterLocal.cs b/src/IKVM.Runtime/CodeEmitterLocal.cs index d9f8e2b26..6f9161b3a 100644 --- a/src/IKVM.Runtime/CodeEmitterLocal.cs +++ b/src/IKVM.Runtime/CodeEmitterLocal.cs @@ -21,14 +21,13 @@ Jeroen Frijters jeroen@frijters.net */ -using System; +using IKVM.CoreLib.Symbols; #if IMPORTER -using IKVM.Reflection; using IKVM.Reflection.Emit; -using Type = IKVM.Reflection.Type; #else using System.Reflection.Emit; + #endif namespace IKVM.Runtime @@ -37,16 +36,16 @@ namespace IKVM.Runtime sealed class CodeEmitterLocal { - private Type type; + private ITypeSymbol type; private string name; private LocalBuilder local; - internal CodeEmitterLocal(Type type) + internal CodeEmitterLocal(ITypeSymbol type) { this.type = type; } - internal Type LocalType + internal ITypeSymbol LocalType { get { return type; } } @@ -64,13 +63,13 @@ internal int __LocalIndex internal void Emit(ILGenerator ilgen, OpCode opcode) { // it's a temporary local that is only allocated on-demand - local ??= ilgen.DeclareLocal(type); + local ??= ilgen.DeclareLocal(type.AsReflection()); ilgen.Emit(opcode, local); } internal void Declare(ILGenerator ilgen) { - local = ilgen.DeclareLocal(type); + local = ilgen.DeclareLocal(type.AsReflection()); #if NETFRAMEWORK || IMPORTER if (name != null) diff --git a/src/IKVM.Runtime/DefineMethodHelper.cs b/src/IKVM.Runtime/DefineMethodHelper.cs index f04b221f4..5468da337 100644 --- a/src/IKVM.Runtime/DefineMethodHelper.cs +++ b/src/IKVM.Runtime/DefineMethodHelper.cs @@ -74,7 +74,7 @@ internal MethodBuilder DefineMethod(RuntimeJavaTypeFactory context, TypeBuilder if (firstParameter != null) { parameterTypes[0] = firstParameter; - modopt[0] = Type.EmptyTypes; + modopt[0] = []; } for (int i = 0; i < parameters.Length; i++) { diff --git a/src/IKVM.Runtime/DynamicClassLoader.cs b/src/IKVM.Runtime/DynamicClassLoader.cs index fd0caf88a..b8f86ec23 100644 --- a/src/IKVM.Runtime/DynamicClassLoader.cs +++ b/src/IKVM.Runtime/DynamicClassLoader.cs @@ -529,7 +529,7 @@ public static ModuleBuilder CreateModuleBuilder(RuntimeContext context, Assembly #if NETFRAMEWORK if (!AppDomain.CurrentDomain.IsFullyTrusted) - attribs.Add(new CustomAttributeBuilder(typeof(System.Security.SecurityTransparentAttribute).GetConstructor(Type.EmptyTypes), new object[0])); + attribs.Add(new CustomAttributeBuilder(typeof(System.Security.SecurityTransparentAttribute).GetConstructor([]), [])); #endif var assemblyBuilder = DefineDynamicAssembly(name, access, attribs); @@ -548,7 +548,7 @@ public static ModuleBuilder CreateModuleBuilder(RuntimeContext context, Assembly var moduleBuilder = assemblyBuilder.DefineDynamicModule(name.Name); #endif - moduleBuilder.SetCustomAttribute(new CustomAttributeBuilder(typeof(IKVM.Attributes.JavaModuleAttribute).GetConstructor(Type.EmptyTypes), new object[0])); + moduleBuilder.SetCustomAttribute(new CustomAttributeBuilder(typeof(IKVM.Attributes.JavaModuleAttribute).GetConstructor([]), [])); return moduleBuilder; } diff --git a/src/IKVM.Runtime/EnumHelper.cs b/src/IKVM.Runtime/EnumHelper.cs index 1e6917c62..90173db61 100644 --- a/src/IKVM.Runtime/EnumHelper.cs +++ b/src/IKVM.Runtime/EnumHelper.cs @@ -24,11 +24,7 @@ Jeroen Frijters using System; using System.Diagnostics; -#if IMPORTER || EXPORTER -using IKVM.Reflection; - -using Type = IKVM.Reflection.Type; -#endif +using IKVM.CoreLib.Symbols; namespace IKVM.Runtime { @@ -36,24 +32,13 @@ namespace IKVM.Runtime static class EnumHelper { - internal static Type GetUnderlyingType(Type enumType) - { - -#if IMPORTER || EXPORTER - return enumType.GetEnumUnderlyingType(); -#else - return Enum.GetUnderlyingType(enumType); -#endif - } - -#if IMPORTER - - internal static object Parse(RuntimeContext context, Type type, string value) + internal static object Parse(RuntimeContext context, ITypeSymbol type, string value) { object retval = null; + foreach (string str in value.Split(',')) { - FieldInfo field = type.GetField(str.Trim(), BindingFlags.Public | BindingFlags.Static); + var field = type.GetField(str.Trim(), System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static); if (field == null) { throw new InvalidOperationException("Enum value '" + str + "' not found in " + type.FullName); @@ -70,7 +55,6 @@ internal static object Parse(RuntimeContext context, Type type, string value) return retval; } -#endif // note that we only support the integer types that C# supports // (the CLI also supports bool, char, IntPtr & UIntPtr) @@ -86,7 +70,7 @@ internal static object OrBoxedIntegrals(RuntimeContext context, object v1, objec else { long v = ((IConvertible)v1).ToInt64(null) | ((IConvertible)v2).ToInt64(null); - switch (Type.GetTypeCode(context.Resolver.ResolveCoreType(v1.GetType().FullName).AsReflection())) + switch (context.Resolver.ResolveCoreType(v1.GetType().FullName).TypeCode) { case TypeCode.SByte: return (sbyte)v; @@ -109,7 +93,7 @@ internal static object OrBoxedIntegrals(RuntimeContext context, object v1, objec } // this method can be used to convert an enum value or its underlying value to a Java primitive - internal static object GetPrimitiveValue(RuntimeContext context, Type underlyingType, object obj) + internal static object GetPrimitiveValue(RuntimeContext context, ITypeSymbol underlyingType, object obj) { // Note that this method doesn't trust that obj is of the correct type, // because it turns out there exist assemblies (e.g. gtk-sharp.dll) that diff --git a/src/IKVM.Runtime/IRuntimeSymbolResolver.cs b/src/IKVM.Runtime/IRuntimeSymbolResolver.cs new file mode 100644 index 000000000..09b5a0140 --- /dev/null +++ b/src/IKVM.Runtime/IRuntimeSymbolResolver.cs @@ -0,0 +1,28 @@ +using System; + +using IKVM.CoreLib.Symbols; + +#if IMPORTER || EXPORTER +using Type = IKVM.Reflection.Type; +#endif + +namespace IKVM.Runtime +{ + + /// + /// Provides an interface to resolve a managed type symbols extended for the Runtime classes. + /// + interface IRuntimeSymbolResolver : ISymbolResolver + { + + /// + /// Gets the associated with the specified type. + /// + /// + /// + ITypeSymbol ResolveType(Type type); + + } + + +} diff --git a/src/IKVM.Runtime/JNI/JNIEnv.cs b/src/IKVM.Runtime/JNI/JNIEnv.cs index be813a7e4..51a0c46f1 100644 --- a/src/IKVM.Runtime/JNI/JNIEnv.cs +++ b/src/IKVM.Runtime/JNI/JNIEnv.cs @@ -353,7 +353,7 @@ internal static jint ThrowNew(JNIEnv* pEnv, nint clazz, byte* msg) { wrapper.Finish(); var cons = (java.lang.reflect.Constructor)mw.ToMethodOrConstructor(false); - JVM.SetPendingException((Exception)cons.newInstance(msg == null ? new object[0] : new object[] { DecodeMUTF8Argument(msg, nameof(msg)) }, env.callerID)); + JVM.SetPendingException((Exception)cons.newInstance(msg == null ? [] : new object[] { DecodeMUTF8Argument(msg, nameof(msg)) }, env.callerID)); return JNI_OK; } catch (RetargetableJavaException x) diff --git a/src/IKVM.Runtime/JVM.Resolver.cs b/src/IKVM.Runtime/JVM.Resolver.cs index b366e9e5a..18fc01b75 100644 --- a/src/IKVM.Runtime/JVM.Resolver.cs +++ b/src/IKVM.Runtime/JVM.Resolver.cs @@ -9,6 +9,10 @@ using IKVM.CoreLib.Symbols; using IKVM.CoreLib.Symbols.Reflection; +#if IMPORTER || EXPORTER +using Type = IKVM.Reflection.Type; +#endif + namespace IKVM.Runtime { @@ -20,7 +24,7 @@ static partial class JVM /// /// Provides support for resolving managed types from the current JVM environment. /// - internal class Resolver : ISymbolResolver + internal class Resolver : IRuntimeSymbolResolver { /// @@ -87,6 +91,12 @@ public ITypeSymbol ResolveRuntimeType(string typeName) return typeof(Resolver).Assembly.GetType(typeName) is { } t ? _context.GetOrCreateTypeSymbol(t) : null; } + /// + public ITypeSymbol ResolveType(Type type) + { + return type is { } t ? _context.GetOrCreateTypeSymbol(t) : null; + } + } } diff --git a/src/IKVM.Runtime/Java/Externs/java/lang/Class.cs b/src/IKVM.Runtime/Java/Externs/java/lang/Class.cs index e0ae4ff52..ea4d8fa57 100644 --- a/src/IKVM.Runtime/Java/Externs/java/lang/Class.cs +++ b/src/IKVM.Runtime/Java/Externs/java/lang/Class.cs @@ -72,7 +72,7 @@ static class Class var type = Type.GetType(name); if (type != null) - tw = JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(type); + tw = JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(JVM.Context.Resolver.ResolveType(type)); if (tw == null) { @@ -359,6 +359,7 @@ public static object[] getEnclosingMethod0(global::java.lang.Class thisClass) { var wrapper = RuntimeJavaType.FromClass(thisClass); wrapper.Finish(); + var decl = wrapper.DeclaringTypeWrapper; if (decl == null) return null; @@ -368,7 +369,7 @@ public static object[] getEnclosingMethod0(global::java.lang.Class thisClass) throw new IllegalAccessError(string.Format("tried to access class {0} from class {1}", decl.Name, wrapper.Name)); decl.Finish(); - RuntimeJavaType[] declInner = decl.InnerClasses; + var declInner = decl.InnerClasses; for (int i = 0; i < declInner.Length; i++) { if (declInner[i].Name == wrapper.Name && declInner[i].EnsureLoadable(decl.ClassLoader) == wrapper) @@ -398,8 +399,7 @@ public static object[] getEnclosingMethod0(global::java.lang.Class thisClass) { // The protection domain for statically compiled code is created lazily (not at global::java.lang.Class creation time), // to work around boot strap issues. - var acl = wrapper.ClassLoader as RuntimeAssemblyClassLoader; - if (acl != null) + if (wrapper.ClassLoader is RuntimeAssemblyClassLoader acl) pd = acl.GetProtectionDomain(); else if (wrapper is RuntimeAnonymousJavaType) { @@ -445,7 +445,7 @@ public static object[] getEnclosingMethod0(global::java.lang.Class thisClass) public static string getGenericSignature0(global::java.lang.Class thisClass) { - RuntimeJavaType tw = RuntimeJavaType.FromClass(thisClass); + var tw = RuntimeJavaType.FromClass(thisClass); tw.Finish(); return tw.GetGenericSignature(); } @@ -453,14 +453,14 @@ public static string getGenericSignature0(global::java.lang.Class thisClass) internal static object AnnotationsToMap(RuntimeClassLoader loader, object[] objAnn) { #if FIRST_PASS - return null; + throw new NotImplementedException(); #else - global::java.util.LinkedHashMap map = new global::java.util.LinkedHashMap(); + var map = new global::java.util.LinkedHashMap(); if (objAnn != null) { foreach (object obj in objAnn) { - global::java.lang.annotation.Annotation a = obj as global::java.lang.annotation.Annotation; + var a = obj as global::java.lang.annotation.Annotation; if (a != null) { map.put(a.annotationType(), FreezeOrWrapAttribute(a)); @@ -469,12 +469,11 @@ internal static object AnnotationsToMap(RuntimeClassLoader loader, object[] objA { a = (global::java.lang.annotation.Annotation)JVM.NewAnnotation(loader.GetJavaClassLoader(), ((IKVM.Attributes.DynamicAnnotationAttribute)obj).Definition); if (a != null) - { map.put(a.annotationType(), a); - } } } } + return map; #endif } @@ -500,9 +499,10 @@ internal static object AnnotationsToMap(RuntimeClassLoader loader, object[] objA public static object getDeclaredAnnotationsImpl(global::java.lang.Class thisClass) { #if FIRST_PASS - return null; + throw new NotImplementedException(); #else - RuntimeJavaType wrapper = RuntimeJavaType.FromClass(thisClass); + var wrapper = RuntimeJavaType.FromClass(thisClass); + try { wrapper.Finish(); @@ -511,6 +511,7 @@ public static object getDeclaredAnnotationsImpl(global::java.lang.Class thisClas { throw x.ToJava(); } + return AnnotationsToMap(wrapper.ClassLoader, wrapper.GetDeclaredAnnotations()); #endif } @@ -518,16 +519,17 @@ public static object getDeclaredAnnotationsImpl(global::java.lang.Class thisClas public static object getDeclaredFields0(global::java.lang.Class thisClass, bool publicOnly) { #if FIRST_PASS - return null; + throw new NotImplementedException(); #else Profiler.Enter("Class.getDeclaredFields0"); + try { - RuntimeJavaType wrapper = RuntimeJavaType.FromClass(thisClass); - // we need to finish the type otherwise all fields will not be in the field map yet + var wrapper = RuntimeJavaType.FromClass(thisClass); wrapper.Finish(); - RuntimeJavaField[] fields = wrapper.GetFields(); - List list = new List(); + + var fields = wrapper.GetFields(); + var list = new List(); for (int i = 0; i < fields.Length; i++) { if (fields[i].IsHideFromReflection) @@ -543,6 +545,7 @@ public static object getDeclaredFields0(global::java.lang.Class thisClass, bool list.Add((global::java.lang.reflect.Field)fields[i].ToField(false, i)); } } + return list.ToArray(); } catch (RetargetableJavaException x) @@ -606,7 +609,7 @@ public static object getDeclaredMethods0(global::java.lang.Class thisClass, bool public static object getDeclaredConstructors0(global::java.lang.Class thisClass, bool publicOnly) { #if FIRST_PASS - return null; + throw new NotImplementedException(); #else Profiler.Enter("Class.getDeclaredConstructors0"); try @@ -652,7 +655,7 @@ public static object getDeclaredConstructors0(global::java.lang.Class thisClass, public static global::java.lang.Class[] getDeclaredClasses0(global::java.lang.Class thisClass) { #if FIRST_PASS - return null; + throw new NotImplementedException(); #else try { diff --git a/src/IKVM.Runtime/Java/Externs/sun/reflect/ReflectionFactory.cs b/src/IKVM.Runtime/Java/Externs/sun/reflect/ReflectionFactory.cs index 5c6488df9..3997dd1f8 100644 --- a/src/IKVM.Runtime/Java/Externs/sun/reflect/ReflectionFactory.cs +++ b/src/IKVM.Runtime/Java/Externs/sun/reflect/ReflectionFactory.cs @@ -310,14 +310,14 @@ sealed class BoxUtil static readonly MethodInfo valueOfFloat = typeof(global::java.lang.Float).GetMethod("valueOf", new Type[] { typeof(float) }); static readonly MethodInfo valueOfLong = typeof(global::java.lang.Long).GetMethod("valueOf", new Type[] { typeof(long) }); static readonly MethodInfo valueOfDouble = typeof(global::java.lang.Double).GetMethod("valueOf", new Type[] { typeof(double) }); - static readonly MethodInfo byteValue = typeof(global::java.lang.Byte).GetMethod("byteValue", Type.EmptyTypes); - static readonly MethodInfo booleanValue = typeof(global::java.lang.Boolean).GetMethod("booleanValue", Type.EmptyTypes); - static readonly MethodInfo charValue = typeof(global::java.lang.Character).GetMethod("charValue", Type.EmptyTypes); - static readonly MethodInfo shortValue = typeof(global::java.lang.Short).GetMethod("shortValue", Type.EmptyTypes); - static readonly MethodInfo intValue = typeof(global::java.lang.Integer).GetMethod("intValue", Type.EmptyTypes); - static readonly MethodInfo floatValue = typeof(global::java.lang.Float).GetMethod("floatValue", Type.EmptyTypes); - static readonly MethodInfo longValue = typeof(global::java.lang.Long).GetMethod("longValue", Type.EmptyTypes); - static readonly MethodInfo doubleValue = typeof(global::java.lang.Double).GetMethod("doubleValue", Type.EmptyTypes); + static readonly MethodInfo byteValue = typeof(global::java.lang.Byte).GetMethod("byteValue", []); + static readonly MethodInfo booleanValue = typeof(global::java.lang.Boolean).GetMethod("booleanValue", []); + static readonly MethodInfo charValue = typeof(global::java.lang.Character).GetMethod("charValue", []); + static readonly MethodInfo shortValue = typeof(global::java.lang.Short).GetMethod("shortValue", []); + static readonly MethodInfo intValue = typeof(global::java.lang.Integer).GetMethod("intValue", []); + static readonly MethodInfo floatValue = typeof(global::java.lang.Float).GetMethod("floatValue", []); + static readonly MethodInfo longValue = typeof(global::java.lang.Long).GetMethod("longValue", []); + static readonly MethodInfo doubleValue = typeof(global::java.lang.Double).GetMethod("doubleValue", []); internal static void EmitUnboxArg(CodeEmitter ilgen, RuntimeJavaType type) { @@ -522,9 +522,9 @@ sealed class FastMethodAccessorImpl : global::sun.reflect.MethodAccessor /// static FastMethodAccessorImpl() { - nullPointerExceptionCtor = typeof(global::java.lang.NullPointerException).GetConstructor(Type.EmptyTypes); + nullPointerExceptionCtor = typeof(global::java.lang.NullPointerException).GetConstructor([]); nullPointerExceptionWithMessageCtor = typeof(global::java.lang.NullPointerException).GetConstructor(new[] { typeof(string) }); - illegalArgumentExceptionCtor = typeof(global::java.lang.IllegalArgumentException).GetConstructor(Type.EmptyTypes); + illegalArgumentExceptionCtor = typeof(global::java.lang.IllegalArgumentException).GetConstructor([]); illegalArgumentExceptionWithMessageCtor = typeof(global::java.lang.IllegalArgumentException).GetConstructor(new[] { typeof(string) }); illegalArgumentExceptionWithMessageAndCauseCtor = typeof(global::java.lang.IllegalArgumentException).GetConstructor(new[] { typeof(string), typeof(Exception) }); illegalArgumentExceptionWithCauseCtor = typeof(global::java.lang.IllegalArgumentException).GetConstructor(new[] { typeof(Exception) }); diff --git a/src/IKVM.Runtime/LambdaMetafactory.cs b/src/IKVM.Runtime/LambdaMetafactory.cs index fd160d6cf..ea553973b 100644 --- a/src/IKVM.Runtime/LambdaMetafactory.cs +++ b/src/IKVM.Runtime/LambdaMetafactory.cs @@ -419,7 +419,7 @@ private static MethodBuilder CreateConstructorAndDispatch(RuntimeByteCodeJavaTyp MethodBuilder ctor = ReflectUtil.DefineConstructor(tb, MethodAttributes.Assembly, capturedTypes); CodeEmitter ilgen = context.Context.CodeEmitterFactory.Create(ctor); ilgen.Emit(OpCodes.Ldarg_0); - ilgen.Emit(OpCodes.Call, context.Context.Types.Object.GetConstructor(Type.EmptyTypes)); + ilgen.Emit(OpCodes.Call, context.Context.Types.Object.GetConstructor([])); for (int i = 0; i < capturedTypes.Length; i++) { ilgen.EmitLdarg(0); @@ -471,7 +471,7 @@ private static MethodBuilder CreateConstructorAndDispatch(RuntimeByteCodeJavaTyp // writeReplace method if (serializable) { - MethodBuilder writeReplace = tb.DefineMethod("writeReplace", MethodAttributes.Private, context.Context.Types.Object, Type.EmptyTypes); + MethodBuilder writeReplace = tb.DefineMethod("writeReplace", MethodAttributes.Private, context.Context.Types.Object, []); ilgen = context.Context.CodeEmitterFactory.Create(writeReplace); context.TypeWrapper.EmitClassLiteral(ilgen); ilgen.Emit(OpCodes.Ldstr, cpi.GetRetType().Name.Replace('.', '/')); diff --git a/src/IKVM.Runtime/MethodHandleUtil.root.cs b/src/IKVM.Runtime/MethodHandleUtil.root.cs index 40fa2d848..414420e07 100644 --- a/src/IKVM.Runtime/MethodHandleUtil.root.cs +++ b/src/IKVM.Runtime/MethodHandleUtil.root.cs @@ -23,14 +23,7 @@ Jeroen Frijters */ using System; -#if IMPORTER -using IKVM.Tools.Importer; - -using Type = IKVM.Reflection.Type; -#else -using System.Reflection; -using System.Reflection.Emit; -#endif +using IKVM.CoreLib.Symbols; namespace IKVM.Runtime { @@ -42,9 +35,9 @@ partial class MethodHandleUtil readonly RuntimeContext context; - readonly Type typeofMHA; - readonly Type[] typeofMHV; - readonly Type[] typeofMH; + readonly ITypeSymbol typeofMHA; + readonly ITypeSymbol[] typeofMHV; + readonly ITypeSymbol[] typeofMH; /// /// Initializes a new instance. @@ -53,58 +46,56 @@ public MethodHandleUtil(RuntimeContext context) { this.context = context ?? throw new ArgumentNullException(nameof(context)); - typeofMHA = context.Resolver.ResolveRuntimeType("IKVM.Runtime.MHA`8").AsReflection(); - typeofMHV = new Type[] { - context.Resolver.ResolveRuntimeType("IKVM.Runtime.MHV").AsReflection(), - context.Resolver.ResolveRuntimeType("IKVM.Runtime.MHV`1").AsReflection(), - context.Resolver.ResolveRuntimeType("IKVM.Runtime.MHV`2").AsReflection(), - context.Resolver.ResolveRuntimeType("IKVM.Runtime.MHV`3").AsReflection(), - context.Resolver.ResolveRuntimeType("IKVM.Runtime.MHV`4").AsReflection(), - context.Resolver.ResolveRuntimeType("IKVM.Runtime.MHV`5").AsReflection(), - context.Resolver.ResolveRuntimeType("IKVM.Runtime.MHV`6").AsReflection(), - context.Resolver.ResolveRuntimeType("IKVM.Runtime.MHV`7").AsReflection(), - context.Resolver.ResolveRuntimeType("IKVM.Runtime.MHV`8").AsReflection(), + typeofMHA = context.Resolver.ResolveRuntimeType("IKVM.Runtime.MHA`8"); + typeofMHV = new[] { + context.Resolver.ResolveRuntimeType("IKVM.Runtime.MHV"), + context.Resolver.ResolveRuntimeType("IKVM.Runtime.MHV`1"), + context.Resolver.ResolveRuntimeType("IKVM.Runtime.MHV`2"), + context.Resolver.ResolveRuntimeType("IKVM.Runtime.MHV`3"), + context.Resolver.ResolveRuntimeType("IKVM.Runtime.MHV`4"), + context.Resolver.ResolveRuntimeType("IKVM.Runtime.MHV`5"), + context.Resolver.ResolveRuntimeType("IKVM.Runtime.MHV`6"), + context.Resolver.ResolveRuntimeType("IKVM.Runtime.MHV`7"), + context.Resolver.ResolveRuntimeType("IKVM.Runtime.MHV`8"), }; - typeofMH = new Type[] { + typeofMH = new[] { null, - context.Resolver.ResolveRuntimeType("IKVM.Runtime.MH`1").AsReflection(), - context.Resolver.ResolveRuntimeType("IKVM.Runtime.MH`2").AsReflection(), - context.Resolver.ResolveRuntimeType("IKVM.Runtime.MH`3").AsReflection(), - context.Resolver.ResolveRuntimeType("IKVM.Runtime.MH`4").AsReflection(), - context.Resolver.ResolveRuntimeType("IKVM.Runtime.MH`5").AsReflection(), - context.Resolver.ResolveRuntimeType("IKVM.Runtime.MH`6").AsReflection(), - context.Resolver.ResolveRuntimeType("IKVM.Runtime.MH`7").AsReflection(), - context.Resolver.ResolveRuntimeType("IKVM.Runtime.MH`8").AsReflection(), - context.Resolver.ResolveRuntimeType("IKVM.Runtime.MH`9").AsReflection(), + context.Resolver.ResolveRuntimeType("IKVM.Runtime.MH`1"), + context.Resolver.ResolveRuntimeType("IKVM.Runtime.MH`2"), + context.Resolver.ResolveRuntimeType("IKVM.Runtime.MH`3"), + context.Resolver.ResolveRuntimeType("IKVM.Runtime.MH`4"), + context.Resolver.ResolveRuntimeType("IKVM.Runtime.MH`5"), + context.Resolver.ResolveRuntimeType("IKVM.Runtime.MH`6"), + context.Resolver.ResolveRuntimeType("IKVM.Runtime.MH`7"), + context.Resolver.ResolveRuntimeType("IKVM.Runtime.MH`8"), + context.Resolver.ResolveRuntimeType("IKVM.Runtime.MH`9"), }; } - internal bool IsPackedArgsContainer(Type type) + internal bool IsPackedArgsContainer(ITypeSymbol type) { return type.IsGenericType && type.GetGenericTypeDefinition() == typeofMHA; } - internal Type CreateMethodHandleDelegateType(RuntimeJavaType[] args, RuntimeJavaType ret) + internal ITypeSymbol CreateMethodHandleDelegateType(RuntimeJavaType[] args, RuntimeJavaType ret) { - Type[] typeArgs = new Type[args.Length]; + var typeArgs = new ITypeSymbol[args.Length]; for (int i = 0; i < args.Length; i++) - { typeArgs[i] = args[i].TypeAsSignatureType; - } + return CreateDelegateType(typeArgs, ret.TypeAsSignatureType); } - internal Type CreateMemberWrapperDelegateType(RuntimeJavaType[] args, RuntimeJavaType ret) + internal ITypeSymbol CreateMemberWrapperDelegateType(RuntimeJavaType[] args, RuntimeJavaType ret) { - Type[] typeArgs = new Type[args.Length]; + var typeArgs = new ITypeSymbol[args.Length]; for (int i = 0; i < args.Length; i++) - { typeArgs[i] = AsBasicType(args[i]); - } + return CreateDelegateType(typeArgs, AsBasicType(ret)); } - Type CreateDelegateType(Type[] types, Type retType) + ITypeSymbol CreateDelegateType(ITypeSymbol[] types, ITypeSymbol retType) { if (types.Length == 0 && retType == context.Types.Void) { @@ -144,14 +135,14 @@ Type CreateDelegateType(Type[] types, Type retType) } } - Type[] SubArray(Type[] inArray, int start, int length) + ITypeSymbol[] SubArray(ITypeSymbol[] inArray, int start, int length) { - var outArray = new Type[length]; + var outArray = new ITypeSymbol[length]; Array.Copy(inArray, start, outArray, 0, length); return outArray; } - internal Type AsBasicType(RuntimeJavaType tw) + internal ITypeSymbol AsBasicType(RuntimeJavaType tw) { if (tw == context.PrimitiveJavaTypeFactory.BOOLEAN || tw == context.PrimitiveJavaTypeFactory.BYTE || tw == context.PrimitiveJavaTypeFactory.CHAR || tw == context.PrimitiveJavaTypeFactory.SHORT || tw == context.PrimitiveJavaTypeFactory.INT) return context.Types.Int32; @@ -161,7 +152,7 @@ internal Type AsBasicType(RuntimeJavaType tw) return context.Types.Object; } - internal bool HasOnlyBasicTypes(RuntimeJavaType[] args, RuntimeJavaType ret) + internal bool HasOnlyBasicTypes(RuntimeJavaType[] args, RuntimeJavaType ret) { foreach (var tw in args) if (!IsBasicType(tw)) diff --git a/src/IKVM.Runtime/ReflectUtil.cs b/src/IKVM.Runtime/ReflectUtil.cs index e219ae4c2..31889ad73 100644 --- a/src/IKVM.Runtime/ReflectUtil.cs +++ b/src/IKVM.Runtime/ReflectUtil.cs @@ -23,6 +23,9 @@ Jeroen Frijters */ using System; +using IKVM.CoreLib.Symbols; + + #if IMPORTER || EXPORTER using IKVM.Reflection; using IKVM.Reflection.Emit; @@ -39,78 +42,66 @@ namespace IKVM.Runtime static class ReflectUtil { - internal static bool IsSameAssembly(Type type1, Type type2) + internal static bool IsSameAssembly(ITypeSymbol type1, ITypeSymbol type2) { return type1.Assembly.Equals(type2.Assembly); } - internal static bool IsFromAssembly(Type type, Assembly assembly) + internal static bool IsFromAssembly(ITypeSymbol type, IAssemblySymbol assembly) { return type.Assembly.Equals(assembly); } - internal static Assembly GetAssembly(Type type) + internal static IAssemblySymbol GetAssembly(ITypeSymbol type) { return type.Assembly; } - internal static bool IsDynamicAssembly(Assembly asm) + internal static bool IsDynamicAssembly(IAssemblySymbol asm) { #if IMPORTER || EXPORTER return false; #else - return asm.IsDynamic; + return asm.AsReflection().IsDynamic; #endif } - internal static bool IsReflectionOnly(Type type) + internal static bool IsReflectionOnly(ITypeSymbol type) { while (type.HasElementType) type = type.GetElementType(); var asm = type.Assembly; - if (asm != null && asm.ReflectionOnly) + if (asm != null && asm.AsReflection().ReflectionOnly) return true; if (!type.IsGenericType || type.IsGenericTypeDefinition) return false; // we have a generic type instantiation, it might have ReflectionOnly type arguments - foreach (Type arg in type.GetGenericArguments()) + foreach (var arg in type.GetGenericArguments()) if (IsReflectionOnly(arg)) return true; return false; } - internal static bool ContainsTypeBuilder(Type type) + internal static bool ContainsTypeBuilder(ITypeSymbol type) { while (type.HasElementType) type = type.GetElementType(); if (!type.IsGenericType || type.IsGenericTypeDefinition) - return type is TypeBuilder; + return type.AsReflection() is TypeBuilder; - foreach (Type arg in type.GetGenericArguments()) + foreach (var arg in type.GetGenericArguments()) if (ContainsTypeBuilder(arg)) return true; - return type.GetGenericTypeDefinition() is TypeBuilder; - } - - internal static bool IsVector(Type type) - { -#if IMPORTER || EXPORTER - return type.__IsVector; -#else - // there's no API to distinguish an array of rank 1 from a vector, - // so we check if the type name ends in [], which indicates it's a vector - // (non-vectors will have [*] or [,]). - return type.IsArray && type.Name.EndsWith("[]"); -#endif + return type.GetGenericTypeDefinition().AsReflection() is TypeBuilder; } - internal static bool IsDynamicMethod(MethodInfo method) + internal static bool IsDynamicMethod(IMethodSymbol method) { // there's no way to distinguish a baked DynamicMethod from a RuntimeMethodInfo and // on top of that Mono behaves completely different from .NET @@ -128,10 +119,10 @@ internal static bool IsDynamicMethod(MethodInfo method) internal static MethodBuilder DefineTypeInitializer(TypeBuilder typeBuilder, RuntimeClassLoader loader) { var attr = MethodAttributes.Static | MethodAttributes.RTSpecialName | MethodAttributes.SpecialName | MethodAttributes.Private; - return typeBuilder.DefineMethod(ConstructorInfo.TypeConstructorName, attr, null, Type.EmptyTypes); + return typeBuilder.DefineMethod(ConstructorInfo.TypeConstructorName, attr, null, []); } - internal static bool MatchNameAndPublicKeyToken(AssemblyName name1, AssemblyName name2) + internal static bool MatchNameAndPublicKeyToken(System.Reflection.AssemblyName name1, System.Reflection.AssemblyName name2) { return name1.Name.Equals(name2.Name, StringComparison.OrdinalIgnoreCase) && CompareKeys(name1.GetPublicKeyToken(), name2.GetPublicKeyToken()); } @@ -150,7 +141,7 @@ static bool CompareKeys(byte[] b1, byte[] b2) return true; } - internal static bool IsConstructor(MethodBase method) + internal static bool IsConstructor(IMethodBaseSymbol method) { return method.IsSpecialName && method.Name == ConstructorInfo.ConstructorName; } @@ -165,12 +156,12 @@ internal static MethodBuilder DefineConstructor(TypeBuilder tb, MethodAttributes /// /// /// - internal static bool CanOwnDynamicMethod(Type type) + internal static bool CanOwnDynamicMethod(ITypeSymbol type) { return type != null && !type.IsInterface && !type.HasElementType && !type.IsGenericTypeDefinition && !type.IsGenericParameter; } - internal static bool MatchParameterInfos(ParameterInfo p1, ParameterInfo p2) + internal static bool MatchParameterInfos(IParameterSymbol p1, IParameterSymbol p2) { if (p1.ParameterType != p2.ParameterType) { @@ -187,41 +178,39 @@ internal static bool MatchParameterInfos(ParameterInfo p1, ParameterInfo p2) return true; } - private static bool MatchTypes(Type[] t1, Type[] t2) + private static bool MatchTypes(ITypeSymbol[] t1, ITypeSymbol[] t2) { if (t1.Length == t2.Length) { for (int i = 0; i < t1.Length; i++) - { if (t1[i] != t2[i]) - { return false; - } - } + return true; } + return false; } #if IMPORTER - internal static Type GetMissingType(Type type) + internal static ITypeSymbol GetMissingType(ITypeSymbol type) { while (type.HasElementType) type = type.GetElementType(); - if (type.__IsMissing) + if (type.IsMissing) { return type; } - else if (type.__ContainsMissingType) + else if (type.ContainsMissing) { if (type.IsGenericType) { foreach (var arg in type.GetGenericArguments()) { var t1 = GetMissingType(arg); - if (t1.__IsMissing) + if (t1.IsMissing) return t1; } } diff --git a/src/IKVM.Runtime/RuntimeAccessStubJavaMethod.cs b/src/IKVM.Runtime/RuntimeAccessStubJavaMethod.cs index f3cfa8171..e5d2c4518 100644 --- a/src/IKVM.Runtime/RuntimeAccessStubJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimeAccessStubJavaMethod.cs @@ -22,14 +22,11 @@ Jeroen Frijters */ using IKVM.Attributes; +using IKVM.CoreLib.Symbols; #if IMPORTER || EXPORTER -using IKVM.Reflection; using IKVM.Reflection.Emit; - -using Type = IKVM.Reflection.Type; #else -using System.Reflection; using System.Reflection.Emit; #endif @@ -39,8 +36,8 @@ namespace IKVM.Runtime sealed class RuntimeAccessStubJavaMethod : RuntimeSmartJavaMethod { - readonly MethodInfo stubVirtual; - readonly MethodInfo stubNonVirtual; + readonly IMethodSymbol stubVirtual; + readonly IMethodSymbol stubNonVirtual; /// /// Initializes a new instance. @@ -55,7 +52,7 @@ sealed class RuntimeAccessStubJavaMethod : RuntimeSmartJavaMethod /// /// /// - internal RuntimeAccessStubJavaMethod(RuntimeJavaType declaringType, string name, string sig, MethodInfo core, MethodInfo stubVirtual, MethodInfo stubNonVirtual, RuntimeJavaType returnType, RuntimeJavaType[] parameterTypes, Modifiers modifiers, MemberFlags flags) : + internal RuntimeAccessStubJavaMethod(RuntimeJavaType declaringType, string name, string sig, IMethodSymbol core, IMethodSymbol stubVirtual, IMethodSymbol stubNonVirtual, RuntimeJavaType returnType, RuntimeJavaType[] parameterTypes, Modifiers modifiers, MemberFlags flags) : base(declaringType, name, sig, core, returnType, parameterTypes, modifiers, flags) { this.stubVirtual = stubVirtual; diff --git a/src/IKVM.Runtime/RuntimeAnonymousJavaType.cs b/src/IKVM.Runtime/RuntimeAnonymousJavaType.cs index 9f0571753..86001a66c 100644 --- a/src/IKVM.Runtime/RuntimeAnonymousJavaType.cs +++ b/src/IKVM.Runtime/RuntimeAnonymousJavaType.cs @@ -26,6 +26,7 @@ Jeroen Frijters using System.Reflection; using IKVM.Attributes; +using IKVM.CoreLib.Symbols; namespace IKVM.Runtime { @@ -38,32 +39,32 @@ namespace IKVM.Runtime sealed class RuntimeAnonymousJavaType : RuntimeJavaType { - readonly Type type; + readonly ITypeSymbol type; /// /// Initializes a new instance. /// /// /// - internal RuntimeAnonymousJavaType(RuntimeContext context, Type type) : + internal RuntimeAnonymousJavaType(RuntimeContext context, ITypeSymbol type) : base(context, TypeFlags.Anonymous, Modifiers.Final | Modifiers.Synthetic, GetName(context, type)) { this.type = type; } - internal static bool IsAnonymous(RuntimeContext context, Type type) + internal static bool IsAnonymous(RuntimeContext context, ITypeSymbol type) { return type.IsSpecialName && type.Name.StartsWith(NestedTypeName.IntrinsifiedAnonymousClass, StringComparison.Ordinal) && context.AttributeHelper.IsJavaModule(type.Module); } - private static string GetName(RuntimeContext context, Type type) + private static string GetName(RuntimeContext context, ITypeSymbol type) { return context.ClassLoaderFactory.GetJavaTypeFromType(type.DeclaringType).Name + type.Name.Replace(NestedTypeName.IntrinsifiedAnonymousClass, "$$Lambda$"); } internal override RuntimeClassLoader ClassLoader => Context.ClassLoaderFactory.GetJavaTypeFromType(type.DeclaringType).ClassLoader; - internal override Type TypeAsTBD + internal override ITypeSymbol TypeAsTBD { get { return type; } } @@ -122,7 +123,7 @@ protected override void LazyPublishMembers() SetFields(fields.ToArray()); } - void GetSig(MethodInfo mi, out RuntimeJavaType returnType, out RuntimeJavaType[] parameterTypes, out string signature) + void GetSig(IMethodSymbol mi, out RuntimeJavaType returnType, out RuntimeJavaType[] parameterTypes, out string signature) { returnType = RuntimeManagedByteCodeJavaType.GetParameterTypeWrapper(Context, mi.ReturnParameter); var parameters = mi.GetParameters(); diff --git a/src/IKVM.Runtime/RuntimeArrayJavaType.cs b/src/IKVM.Runtime/RuntimeArrayJavaType.cs index ed204a85f..1bcc4c1b8 100644 --- a/src/IKVM.Runtime/RuntimeArrayJavaType.cs +++ b/src/IKVM.Runtime/RuntimeArrayJavaType.cs @@ -25,6 +25,8 @@ Jeroen Frijters using System.Diagnostics; using IKVM.Attributes; +using IKVM.CoreLib.Symbols; + #if IMPORTER || EXPORTER using IKVM.Reflection; @@ -68,7 +70,7 @@ internal override RuntimeJavaType BaseTypeWrapper internal static MethodInfo GetCloneMethod(RuntimeContext context) { - return context.Types.Array.GetMethod("Clone", BindingFlags.Public | BindingFlags.Instance, null, Type.EmptyTypes, null); + return context.Types.Array.GetMethod("Clone", BindingFlags.Public | BindingFlags.Instance, null, [], null); } protected override void LazyPublishMembers() @@ -179,18 +181,18 @@ internal override RuntimeJavaType GetUltimateElementTypeWrapper() return ultimateElementTypeWrapper; } - internal static Type MakeArrayType(Type type, int dims) + internal static ITypeSymbol MakeArrayType(ITypeSymbol type, int dims) { // NOTE this is not just an optimization, but it is also required to // make sure that ReflectionOnly types stay ReflectionOnly types // (in particular instantiations of generic types from mscorlib that // have ReflectionOnly type parameters). for (int i = 0; i < dims; i++) - { type = type.MakeArrayType(); - } + return type; } + } } diff --git a/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs b/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs index ef11c41dc..8ce64aa78 100644 --- a/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs +++ b/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs @@ -32,6 +32,8 @@ Jeroen Frijters using IKVM.CoreLib.Diagnostics; using IKVM.Attributes; using IKVM.Runtime.Syntax; +using IKVM.CoreLib.Symbols; + #if IMPORTER || EXPORTER @@ -68,7 +70,7 @@ internal class RuntimeAssemblyClassLoader : RuntimeClassLoader Dictionary> exports; string[] exportedAssemblyNames; AssemblyLoader[] exportedAssemblies; - Dictionary exportedLoaders; + Dictionary exportedLoaders; /// /// Manages a loaded assembly. @@ -77,13 +79,13 @@ sealed class AssemblyLoader { readonly RuntimeAssemblyClassLoader loader; - readonly Assembly assembly; + readonly IAssemblySymbol assembly; bool[] isJavaModule; - Module[] modules; + IModuleSymbol[] modules; Dictionary nameMap; bool hasDotNetModule; - AssemblyName[] internalsVisibleTo; + System.Reflection.AssemblyName[] internalsVisibleTo; string[] jarList; #if !IMPORTER && !EXPORTER && !FIRST_PASS sun.misc.URLClassPath urlClassPath; @@ -94,7 +96,7 @@ sealed class AssemblyLoader /// /// /// - internal AssemblyLoader(RuntimeAssemblyClassLoader loader, Assembly assembly) + internal AssemblyLoader(RuntimeAssemblyClassLoader loader, IAssemblySymbol assembly) { this.loader = loader ?? throw new ArgumentNullException(nameof(loader)); this.assembly = assembly ?? throw new ArgumentNullException(nameof(assembly)); @@ -114,8 +116,7 @@ internal AssemblyLoader(RuntimeAssemblyClassLoader loader, Assembly assembly) var map = jma.GetClassMap(); if (map != null) { - if (nameMap == null) - nameMap = new Dictionary(); + nameMap ??= []; for (int j = 0; j < map.Length; j += 2) { @@ -152,7 +153,7 @@ internal AssemblyLoader(RuntimeAssemblyClassLoader loader, Assembly assembly) } } - internal Assembly Assembly + internal IAssemblySymbol Assembly { get { return assembly; } } @@ -174,7 +175,7 @@ internal bool HasJavaModule /// /// /// - Type GetType(string name) + ITypeSymbol GetType(string name) { try { @@ -197,12 +198,12 @@ Type GetType(string name) } /// - /// Attempts to load a type with the specified name from the given . + /// Attempts to load a type with the specified name from the given . /// /// /// /// - Type GetType(Module module, string name) + ITypeSymbol GetType(IModuleSymbol module, string name) { try { @@ -224,13 +225,12 @@ Type GetType(Module module, string name) return null; } - Type GetJavaType(Module module, string name) + ITypeSymbol GetJavaType(IModuleSymbol module, string name) { try { string n = null; - if (nameMap != null) - nameMap.TryGetValue(name, out n); + nameMap?.TryGetValue(name, out n); var t = GetType(module, n ?? name); if (t == null) @@ -300,6 +300,7 @@ internal RuntimeJavaType DoLoad(string name) // let that generated the manufactured nested classes // (note that for generic outer types, we need to duplicate this in ClassLoaderWrapper.LoadGenericClass) RuntimeJavaType outer = null; + if (name.EndsWith(RuntimeManagedJavaType.DelegateInterfaceSuffix)) { outer = DoLoad(name.Substring(0, name.Length - RuntimeManagedJavaType.DelegateInterfaceSuffix.Length)); @@ -336,7 +337,7 @@ internal RuntimeJavaType DoLoad(string name) /// /// /// - internal JavaTypeName? GetTypeNameAndType(Type type, out bool isJavaType) + internal JavaTypeName? GetTypeNameAndType(ITypeSymbol type, out bool isJavaType) { // find the module index of the type's module var module = type.Module; @@ -373,7 +374,7 @@ internal RuntimeJavaType DoLoad(string name) } } - internal RuntimeJavaType CreateJavaTypeForAssemblyType(Type type) + internal RuntimeJavaType CreateJavaTypeForAssemblyType(ITypeSymbol type) { var name = GetTypeNameAndType(type, out bool isJavaType); if (name == null) @@ -393,7 +394,7 @@ internal RuntimeJavaType CreateJavaTypeForAssemblyType(Type type) } } - internal bool InternalsVisibleTo(AssemblyName otherName) + internal bool InternalsVisibleTo(System.Reflection.AssemblyName otherName) { if (internalsVisibleTo == null) Interlocked.CompareExchange(ref internalsVisibleTo, loader.Context.AttributeHelper.GetInternalsVisibleToAttributes(assembly), null); @@ -438,7 +439,7 @@ internal java.util.Enumeration FindResources(string name) /// /// /// - internal RuntimeAssemblyClassLoader(RuntimeContext context, Assembly assembly) : + internal RuntimeAssemblyClassLoader(RuntimeContext context, IAssemblySymbol assembly) : this(context, assembly, null) { @@ -450,7 +451,7 @@ internal RuntimeAssemblyClassLoader(RuntimeContext context, Assembly assembly) : /// /// /// - internal RuntimeAssemblyClassLoader(RuntimeContext context, Assembly assembly, string[] fixedReferences) : + internal RuntimeAssemblyClassLoader(RuntimeContext context, IAssemblySymbol assembly, string[] fixedReferences) : base(context, CodeGenOptions.None, null) { this.assemblyLoader = new AssemblyLoader(this, assembly); @@ -498,18 +499,18 @@ void DoInitializeExports() { if (delegates == null) { - if (ReflectUtil.IsDynamicAssembly(assemblyLoader.Assembly) == false && assemblyLoader.Assembly.GetManifestResourceInfo("ikvm.exports") != null) + if (ReflectUtil.IsDynamicAssembly(assemblyLoader.Assembly) == false && assemblyLoader.Assembly.AsReflection().GetManifestResourceInfo("ikvm.exports") != null) { var wildcardExports = new List(); - using (var stream = assemblyLoader.Assembly.GetManifestResourceStream("ikvm.exports")) + using (var stream = assemblyLoader.Assembly.AsReflection().GetManifestResourceStream("ikvm.exports")) { var rdr = new BinaryReader(stream); var assemblyCount = rdr.ReadInt32(); exports = new Dictionary>(); exportedAssemblies = new AssemblyLoader[assemblyCount]; exportedAssemblyNames = new string[assemblyCount]; - exportedLoaders = new Dictionary(); + exportedLoaders = new Dictionary(); for (int i = 0; i < assemblyCount; i++) { @@ -554,9 +555,9 @@ void LazyInitExports() DoInitializeExports(); } - internal Assembly MainAssembly => assemblyLoader.Assembly; + internal IAssemblySymbol MainAssembly => assemblyLoader.Assembly; - internal Assembly GetAssembly(RuntimeJavaType wrapper) + internal IAssemblySymbol GetAssembly(RuntimeJavaType wrapper) { Debug.Assert(wrapper.ClassLoader == this); @@ -566,7 +567,7 @@ internal Assembly GetAssembly(RuntimeJavaType wrapper) return wrapper.TypeAsBaseType.Assembly; } - Assembly LoadAssemblyOrClearName(ref string name, bool exported) + IAssemblySymbol LoadAssemblyOrClearName(ref string name, bool exported) { // previous load attempt failed if (name == null) @@ -574,7 +575,7 @@ Assembly LoadAssemblyOrClearName(ref string name, bool exported) try { - return Context.Resolver.ResolveAssembly(name).AsReflection(); + return Context.Resolver.ResolveAssembly(name); } catch { @@ -610,7 +611,7 @@ internal RuntimeJavaType DoLoad(string name) return null; } - internal JavaTypeName? GetTypeNameAndType(Type type, out bool isJavaType) + internal JavaTypeName? GetTypeNameAndType(ITypeSymbol type, out bool isJavaType) { return GetLoader(type.Assembly).GetTypeNameAndType(type, out isJavaType); } @@ -628,9 +629,9 @@ AssemblyLoader TryGetLoaderByIndex(int index) return loader; } - internal List GetAllAvailableAssemblies() + internal List GetAllAvailableAssemblies() { - var list = new List(); + var list = new List(); list.Add(assemblyLoader.Assembly); LazyInitExports(); @@ -648,7 +649,7 @@ internal List GetAllAvailableAssemblies() return list; } - AssemblyLoader GetLoader(Assembly assembly) + AssemblyLoader GetLoader(IAssemblySymbol assembly) { if (assemblyLoader.Assembly == assembly) return assemblyLoader; @@ -656,7 +657,7 @@ AssemblyLoader GetLoader(Assembly assembly) return GetLoaderForExportedAssembly(assembly); } - AssemblyLoader GetLoaderForExportedAssembly(Assembly assembly) + AssemblyLoader GetLoaderForExportedAssembly(IAssemblySymbol assembly) { LazyInitExports(); @@ -691,7 +692,7 @@ AssemblyLoader GetLoaderForExportedAssembly(Assembly assembly) /// /// /// - internal virtual RuntimeJavaType GetJavaTypeFromAssemblyType(Type type) + internal virtual RuntimeJavaType GetJavaTypeFromAssemblyType(ITypeSymbol type) { if (type.Name.EndsWith("[]")) throw new InternalException(); @@ -853,12 +854,12 @@ RuntimeJavaType FindReferenced(string name) #if !IMPORTER && !EXPORTER - static java.net.URL MakeResourceURL(Assembly asm, string name) + static java.net.URL MakeResourceURL(IAssemblySymbol asm, string name) { #if FIRST_PASS throw new NotImplementedException(); #else - return new java.io.File(Path.Combine(VfsTable.GetAssemblyResourcesPath(JVM.Vfs.Context, asm, JVM.Properties.HomePath), name)).toURI().toURL(); + return new java.io.File(Path.Combine(VfsTable.GetAssemblyResourcesPath(JVM.Vfs.Context, asm.AsReflection(), JVM.Properties.HomePath), name)).toURI().toURL(); #endif } @@ -868,7 +869,7 @@ static java.net.URL MakeResourceURL(Assembly asm, string name) throw new NotImplementedException(); #else // cannot find resources in dynamic assembly - if (assemblyLoader.Assembly.IsDynamic) + if (assemblyLoader.Assembly.AsReflection().IsDynamic) yield break; var found = false; @@ -884,14 +885,14 @@ static java.net.URL MakeResourceURL(Assembly asm, string name) if (assemblyLoader.HasJavaModule == false) { // attempt to find an assembly resource with the exact name - if (unmangledName != "" && assemblyLoader.Assembly.GetManifestResourceInfo(unmangledName) != null) + if (unmangledName != "" && assemblyLoader.Assembly.AsReflection().GetManifestResourceInfo(unmangledName) != null) { found = true; yield return MakeResourceURL(assemblyLoader.Assembly, unmangledName); } // the JavaResourceAttribute can be used to manufacture a named Java resource - foreach (var res in assemblyLoader.Assembly.GetCustomAttributes()) + foreach (var res in assemblyLoader.Assembly.AsReflection().GetCustomAttributes()) { if (res.JavaName == unmangledName) { @@ -903,7 +904,7 @@ static java.net.URL MakeResourceURL(Assembly asm, string name) // find an assembly resource with the managed resource name var name = JVM.MangleResourceName(unmangledName); - if (assemblyLoader.Assembly.GetManifestResourceInfo(name) != null) + if (assemblyLoader.Assembly.AsReflection().GetManifestResourceInfo(name) != null) { found = true; yield return MakeResourceURL(assemblyLoader.Assembly, name); @@ -932,7 +933,7 @@ static java.net.URL MakeResourceURL(Assembly asm, string name) yield return (java.net.URL)urls.nextElement(); } - if (loader.Assembly.GetManifestResourceInfo(name) != null) + if (loader.Assembly.AsReflection().GetManifestResourceInfo(name) != null) { found = true; yield return MakeResourceURL(loader.Assembly, name); @@ -945,7 +946,7 @@ static java.net.URL MakeResourceURL(Assembly asm, string name) { var tw = FindLoadedClass(unmangledName.Substring(0, unmangledName.Length - 6).Replace('/', '.')); if (tw != null && tw.ClassLoader == this && !tw.IsArray && !tw.IsDynamic) - yield return new java.io.File(Path.Combine(VfsTable.GetAssemblyClassesPath(JVM.Vfs.Context, assemblyLoader.Assembly, JVM.Properties.HomePath), unmangledName)).toURI().toURL(); + yield return new java.io.File(Path.Combine(VfsTable.GetAssemblyClassesPath(JVM.Vfs.Context, assemblyLoader.Assembly.AsReflection(), JVM.Properties.HomePath), unmangledName)).toURI().toURL(); } #endif } @@ -1081,7 +1082,7 @@ internal override java.lang.ClassLoader GetJavaClassLoader() internal virtual java.security.ProtectionDomain GetProtectionDomain() { if (protectionDomain == null) - Interlocked.CompareExchange(ref protectionDomain, new java.security.ProtectionDomain(assemblyLoader.Assembly), null); + Interlocked.CompareExchange(ref protectionDomain, new java.security.ProtectionDomain(assemblyLoader.Assembly.AsReflection()), null); return protectionDomain; } @@ -1104,26 +1105,24 @@ internal override bool InternalsVisibleToImpl(RuntimeJavaType wrapper, RuntimeJa #else // we're OK if the type being accessed (wrapper) is a dynamic type // or if the dynamic assembly has internal access - return GetAssembly(wrapper).Equals(GetTypeWrapperFactory().ModuleBuilder.Assembly) - || GetTypeWrapperFactory().HasInternalAccess; + return GetAssembly(wrapper).Equals(GetTypeWrapperFactory().ModuleBuilder.Assembly) || GetTypeWrapperFactory().HasInternalAccess; #endif } - AssemblyName otherName; + #if IMPORTER - ImportClassLoader ccl = other as ImportClassLoader; + var ccl = other as ImportClassLoader; if (ccl == null) - { return false; - } - otherName = ccl.GetAssemblyName(); + + var otherName = ccl.GetAssemblyName(); #else - RuntimeAssemblyClassLoader acl = other as RuntimeAssemblyClassLoader; + var acl = other as RuntimeAssemblyClassLoader; if (acl == null) - { return false; - } - otherName = acl.GetAssembly(friend).GetName(); + + var otherName = acl.GetAssembly(friend).GetName(); #endif + return GetLoader(GetAssembly(wrapper)).InternalsVisibleTo(otherName); } @@ -1185,9 +1184,9 @@ Type GetCustomClassLoaderType() } } - var attribs = assembly.GetCustomAttributes(typeof(CustomAssemblyClassLoaderAttribute), false); - if (attribs.Length == 1) - return ((CustomAssemblyClassLoaderAttribute)attribs[0]).Type; + var attribs = assembly.GetCustomAttribute(Context.Resolver.ResolveRuntimeType(typeof(CustomAssemblyClassLoaderAttribute).FullName), false); + if (attribs is not null) + return new CustomAssemblyClassLoaderAttribute((System.Type)attribs.Value.ConstructorArguments[0].Value); return null; } diff --git a/src/IKVM.Runtime/RuntimeAssemblyClassLoaderFactory.cs b/src/IKVM.Runtime/RuntimeAssemblyClassLoaderFactory.cs index 6b847c286..5b50ef661 100644 --- a/src/IKVM.Runtime/RuntimeAssemblyClassLoaderFactory.cs +++ b/src/IKVM.Runtime/RuntimeAssemblyClassLoaderFactory.cs @@ -24,11 +24,10 @@ Jeroen Frijters using System; using System.Collections.Generic; using System.Runtime.CompilerServices; +using IKVM.CoreLib.Symbols; #if IMPORTER || EXPORTER using IKVM.Reflection; - -using Type = IKVM.Reflection.Type; #else using System.Reflection; #endif @@ -51,7 +50,7 @@ class RuntimeAssemblyClassLoaderFactory /// Maps existing instances to instances. Allows /// assemblies to be unloaded. /// - readonly ConditionalWeakTable assemblyClassLoaders = new(); + readonly ConditionalWeakTable assemblyClassLoaders = new(); #if !IMPORTER && !EXPORTER && !FIRST_PASS internal Dictionary customClassLoaderRedirects; @@ -73,7 +72,7 @@ public RuntimeAssemblyClassLoaderFactory(RuntimeContext context) /// /// /// - public RuntimeAssemblyClassLoader FromAssembly(Assembly assembly) + public RuntimeAssemblyClassLoader FromAssembly(IAssemblySymbol assembly) { if (assemblyClassLoaders.TryGetValue(assembly, out RuntimeAssemblyClassLoader loader)) return loader; @@ -96,7 +95,7 @@ public RuntimeAssemblyClassLoader FromAssembly(Assembly assembly) /// /// /// - RuntimeAssemblyClassLoader Create(Assembly assembly) + RuntimeAssemblyClassLoader Create(IAssemblySymbol assembly) { // If the assembly is a part of a multi-assembly shared class loader, // it will export the __ type from the main assembly in the group. @@ -108,9 +107,9 @@ RuntimeAssemblyClassLoader Create(Assembly assembly) return FromAssembly(mainAssembly); } - var baseAssembly = context.Resolver.ResolveBaseAssembly().AsReflection(); + var baseAssembly = context.Resolver.ResolveBaseAssembly(); #if IMPORTER - if (baseAssembly != null && assembly.IsDefined(context.Resolver.ResolveRuntimeType("IKVM.Attributes.RemappedClassAttribute").AsReflection(), false)) + if (baseAssembly != null && assembly.IsDefined(context.Resolver.ResolveRuntimeType("IKVM.Attributes.RemappedClassAttribute"), false)) context.ClassLoaderFactory.LoadRemappedTypes(); #endif diff --git a/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishContext.cs b/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishContext.cs index 7c7c5ebce..9443a3efa 100644 --- a/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishContext.cs +++ b/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishContext.cs @@ -133,7 +133,7 @@ internal void EmitDynamicClassLiteral(CodeEmitter ilgen, RuntimeJavaType tw, boo if (!dynamicClassLiteral.TryGetValue(cacheKey, out var method)) { var fb = typeBuilder.DefineField("__<>class", context.JavaBase.TypeOfJavaLangClass.TypeAsSignatureType, FieldAttributes.PrivateScope | FieldAttributes.Static); - var mb = DefineHelperMethod("__<>class", context.JavaBase.TypeOfJavaLangClass.TypeAsSignatureType, Type.EmptyTypes); + var mb = DefineHelperMethod("__<>class", context.JavaBase.TypeOfJavaLangClass.TypeAsSignatureType, []); var ilgen2 = context.CodeEmitterFactory.Create(mb); ilgen2.Emit(OpCodes.Ldsfld, fb); var label = ilgen2.DefineLabel(); @@ -185,7 +185,7 @@ private void CreateGetCallerID() { RuntimeJavaType tw = context.JavaBase.TypeOfIkvmInternalCallerID; FieldBuilder callerIDField = typeBuilder.DefineField("__", tw.TypeAsSignatureType, FieldAttributes.Private | FieldAttributes.Static | FieldAttributes.SpecialName); - MethodBuilder mb = DefineHelperMethod("__", tw.TypeAsSignatureType, Type.EmptyTypes); + MethodBuilder mb = DefineHelperMethod("__", tw.TypeAsSignatureType, []); callerIDMethod = mb; CodeEmitter ilgen = context.CodeEmitterFactory.Create(mb); ilgen.Emit(OpCodes.Ldsfld, callerIDField); @@ -604,7 +604,7 @@ internal Type FinishImpl() // - we don't want the synthesized constructor to show up in Java if (!hasConstructor) { - var ilgen = context.CodeEmitterFactory.Create(ReflectUtil.DefineConstructor(typeBuilder, MethodAttributes.PrivateScope, Type.EmptyTypes)); + var ilgen = context.CodeEmitterFactory.Create(ReflectUtil.DefineConstructor(typeBuilder, MethodAttributes.PrivateScope, [])); ilgen.Emit(OpCodes.Ldnull); ilgen.Emit(OpCodes.Throw); ilgen.DoEmit(); @@ -1295,7 +1295,7 @@ void GenerateAccessStub(RuntimeJavaField fw, bool type1) { var propType = fw.FieldTypeWrapper.TypeAsPublicSignatureType; var modopt = wrapper.GetModOpt(fw.FieldTypeWrapper, true); - var pb = typeBuilder.DefineProperty(fw.Name, PropertyAttributes.None, propType, null, modopt, Type.EmptyTypes, null, null); + var pb = typeBuilder.DefineProperty(fw.Name, PropertyAttributes.None, propType, null, modopt, [], null, null); if (type1) context.AttributeHelper.HideFromReflection(pb); else @@ -1308,7 +1308,7 @@ void GenerateAccessStub(RuntimeJavaField fw, bool type1) // we append the IKVM.Attributes.AccessStub type to the modopt array for use in the property accessor method signature // to make sure they never conflict with any user defined methhods var modopt2 = ArrayUtil.Concat(modopt, context.Resolver.ResolveRuntimeType(typeof(IKVM.Attributes.AccessStub).FullName).AsReflection()); - var getter = typeBuilder.DefineMethod("get_" + fw.Name, attribs, CallingConventions.Standard, propType, null, modopt2, Type.EmptyTypes, null, null); + var getter = typeBuilder.DefineMethod("get_" + fw.Name, attribs, CallingConventions.Standard, propType, null, modopt2, [], null, null); context.AttributeHelper.HideFromJava(getter); pb.SetGetMethod(getter); var ilgen = context.CodeEmitterFactory.Create(getter); @@ -1607,7 +1607,7 @@ internal static class JniProxyBuilder static JniProxyBuilder() { mod = DynamicClassLoader.CreateJniProxyModuleBuilder(); - var cab = new CustomAttributeBuilder(JVM.Context.Resolver.ResolveRuntimeType(typeof(JavaModuleAttribute).FullName).GetConstructor([]).AsReflection(), new object[0]); + var cab = new CustomAttributeBuilder(JVM.Context.Resolver.ResolveRuntimeType(typeof(JavaModuleAttribute).FullName).GetConstructor([]).AsReflection(), []); mod.SetCustomAttribute(cab); } @@ -1950,7 +1950,7 @@ void ImplementInterfaces(RuntimeJavaType[] interfaces, List int { typeBuilder.AddInterfaceImplementation(context.Resolver.ResolveCoreType(typeof(System.Collections.IEnumerable).FullName).AsReflection()); // FXBUG we're using the same method name as the C# compiler here because both the .NET and Mono implementations of Xml serialization depend on this method name - var mb = typeBuilder.DefineMethod("System.Collections.IEnumerable.GetEnumerator", MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final | MethodAttributes.SpecialName, context.Resolver.ResolveCoreType(typeof(System.Collections.IEnumerator).FullName).AsReflection(), Type.EmptyTypes); + var mb = typeBuilder.DefineMethod("System.Collections.IEnumerable.GetEnumerator", MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final | MethodAttributes.SpecialName, context.Resolver.ResolveCoreType(typeof(System.Collections.IEnumerator).FullName).AsReflection(), []); context.AttributeHelper.HideFromJava(mb); typeBuilder.DefineMethodOverride(mb, context.Resolver.ResolveCoreType(typeof(System.Collections.IEnumerable).FullName).GetMethod("GetEnumerator").AsReflection()); var ilgen = context.CodeEmitterFactory.Create(mb); @@ -2196,9 +2196,9 @@ internal MethodBuilder DefineThreadLocalType() int id = nestedTypeBuilders == null ? 0 : nestedTypeBuilders.Count; var tb = typeBuilder.DefineNestedType(NestedTypeName.ThreadLocal + id, TypeAttributes.NestedPrivate | TypeAttributes.Sealed, threadLocal.TypeAsBaseType); var fb = tb.DefineField("field", context.Types.Object, FieldAttributes.Private | FieldAttributes.Static); - fb.SetCustomAttribute(new CustomAttributeBuilder(context.Resolver.ResolveCoreType(typeof(ThreadStaticAttribute).FullName).GetConstructor([]).AsReflection(), new object[0])); + fb.SetCustomAttribute(new CustomAttributeBuilder(context.Resolver.ResolveCoreType(typeof(ThreadStaticAttribute).FullName).GetConstructor([]).AsReflection(), [])); - var mbGet = tb.DefineMethod("get", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final, context.Types.Object, Type.EmptyTypes); + var mbGet = tb.DefineMethod("get", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final, context.Types.Object, []); var ilgen = mbGet.GetILGenerator(); ilgen.Emit(OpCodes.Ldsfld, fb); ilgen.Emit(OpCodes.Ret); @@ -2209,7 +2209,7 @@ internal MethodBuilder DefineThreadLocalType() ilgen.Emit(OpCodes.Stsfld, fb); ilgen.Emit(OpCodes.Ret); - var cb = ReflectUtil.DefineConstructor(tb, MethodAttributes.Assembly, Type.EmptyTypes); + var cb = ReflectUtil.DefineConstructor(tb, MethodAttributes.Assembly, []); var ctorilgen = context.CodeEmitterFactory.Create(cb); ctorilgen.Emit(OpCodes.Ldarg_0); var basector = threadLocal.GetMethodWrapper("", "()V", false); @@ -2231,7 +2231,7 @@ internal MethodBuilder GetAtomicReferenceFieldUpdater(RuntimeJavaField field) RuntimeJavaType arfuTypeWrapper = context.ClassLoaderFactory.LoadClassCritical("ikvm.internal.IntrinsicAtomicReferenceFieldUpdater"); TypeBuilder tb = typeBuilder.DefineNestedType(NestedTypeName.AtomicReferenceFieldUpdater + arfuMap.Count, TypeAttributes.NestedPrivate | TypeAttributes.Sealed, arfuTypeWrapper.TypeAsBaseType); AtomicReferenceFieldUpdaterEmitter.EmitImpl(context, tb, field.GetField()); - cb = ReflectUtil.DefineConstructor(tb, MethodAttributes.Assembly, Type.EmptyTypes); + cb = ReflectUtil.DefineConstructor(tb, MethodAttributes.Assembly, []); arfuMap.Add(field, cb); CodeEmitter ctorilgen = context.CodeEmitterFactory.Create(cb); ctorilgen.Emit(OpCodes.Ldarg_0); diff --git a/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.DelegateInvokeStubMethodWrapper.cs b/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.DelegateInvokeStubMethodWrapper.cs index 9ad510cc3..7e4a7f3ec 100644 --- a/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.DelegateInvokeStubMethodWrapper.cs +++ b/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.DelegateInvokeStubMethodWrapper.cs @@ -24,6 +24,7 @@ Jeroen Frijters using System; using IKVM.Attributes; +using IKVM.CoreLib.Symbols; #if IMPORTER using IKVM.Reflection; @@ -49,41 +50,47 @@ private sealed partial class JavaTypeImpl private sealed class DelegateInvokeStubMethodWrapper : RuntimeJavaMethod { - readonly Type delegateType; + readonly ITypeSymbol delegateType; - internal DelegateInvokeStubMethodWrapper(RuntimeJavaType declaringType, Type delegateType, string sig) - : base(declaringType, RuntimeManagedJavaType.GetDelegateInvokeStubName(delegateType), sig, null, null, null, Modifiers.Public | Modifiers.Final, MemberFlags.HideFromReflection) + /// + /// Initializes a new instance. + /// + /// + /// + /// + internal DelegateInvokeStubMethodWrapper(RuntimeJavaType declaringType, ITypeSymbol delegateType, string sig) : + base(declaringType, RuntimeManagedJavaType.GetDelegateInvokeStubName(delegateType), sig, null, null, null, Modifiers.Public | Modifiers.Final, MemberFlags.HideFromReflection) { this.delegateType = delegateType; } internal MethodInfo DoLink(TypeBuilder tb) { - RuntimeJavaMethod mw = this.DeclaringType.GetMethodWrapper("Invoke", this.Signature, true); + var mw = DeclaringType.GetMethodWrapper("Invoke", Signature, true); - MethodInfo invoke = delegateType.GetMethod("Invoke"); - ParameterInfo[] parameters = invoke.GetParameters(); - Type[] parameterTypes = new Type[parameters.Length]; + var invoke = delegateType.GetMethod("Invoke"); + var parameters = invoke.GetParameters(); + var parameterTypes = new ITypeSymbol[parameters.Length]; for (int i = 0; i < parameterTypes.Length; i++) - { parameterTypes[i] = parameters[i].ParameterType; - } - MethodBuilder mb = tb.DefineMethod(this.Name, MethodAttributes.Public, invoke.ReturnType, parameterTypes); + + var mb = tb.DefineMethod(Name, MethodAttributes.Public, invoke.ReturnType.AsReflection(), parameterTypes.AsReflection()); DeclaringType.Context.AttributeHelper.HideFromReflection(mb); - CodeEmitter ilgen = DeclaringType.Context.CodeEmitterFactory.Create(mb); + var ilgen = DeclaringType.Context.CodeEmitterFactory.Create(mb); if (mw == null || mw.IsStatic || !mw.IsPublic) { ilgen.EmitThrow(mw == null || mw.IsStatic ? "java.lang.AbstractMethodError" : "java.lang.IllegalAccessError", DeclaringType.Name + ".Invoke" + Signature); ilgen.DoEmit(); return mb; } - CodeEmitterLocal[] byrefs = new CodeEmitterLocal[parameters.Length]; + + var byrefs = new CodeEmitterLocal[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { if (parameters[i].ParameterType.IsByRef) { - Type elemType = parameters[i].ParameterType.GetElementType(); - CodeEmitterLocal local = ilgen.DeclareLocal(RuntimeArrayJavaType.MakeArrayType(elemType, 1)); + var elemType = parameters[i].ParameterType.GetElementType(); + var local = ilgen.DeclareLocal(RuntimeArrayJavaType.MakeArrayType(elemType, 1)); byrefs[i] = local; ilgen.Emit(OpCodes.Ldc_I4_1); ilgen.Emit(OpCodes.Newarr, elemType); @@ -101,30 +108,29 @@ internal MethodInfo DoLink(TypeBuilder tb) for (int i = 0; i < parameters.Length; i++) { if (byrefs[i] != null) - { ilgen.Emit(OpCodes.Ldloc, byrefs[i]); - } else - { ilgen.EmitLdarg(i + 1); - } } + mw.Link(); mw.EmitCallvirt(ilgen); + CodeEmitterLocal returnValue = null; if (mw.ReturnType != DeclaringType.Context.PrimitiveJavaTypeFactory.VOID) { returnValue = ilgen.DeclareLocal(mw.ReturnType.TypeAsSignatureType); ilgen.Emit(OpCodes.Stloc, returnValue); } - CodeEmitterLabel exit = ilgen.DefineLabel(); + + var exit = ilgen.DefineLabel(); ilgen.EmitLeave(exit); ilgen.BeginFinallyBlock(); for (int i = 0; i < parameters.Length; i++) { if (byrefs[i] != null) { - Type elemType = byrefs[i].LocalType.GetElementType(); + var elemType = byrefs[i].LocalType.GetElementType(); ilgen.EmitLdarg(i + 1); ilgen.Emit(OpCodes.Ldloc, byrefs[i]); ilgen.Emit(OpCodes.Ldc_I4_0); @@ -132,13 +138,13 @@ internal MethodInfo DoLink(TypeBuilder tb) ilgen.Emit(OpCodes.Stobj, elemType); } } + ilgen.Emit(OpCodes.Endfinally); ilgen.EndExceptionBlock(); ilgen.MarkLabel(exit); if (returnValue != null) - { ilgen.Emit(OpCodes.Ldloc, returnValue); - } + ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); return mb; diff --git a/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.cs b/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.cs index 7dfb11654..2964cf197 100644 --- a/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.cs +++ b/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.cs @@ -64,11 +64,11 @@ private sealed partial class JavaTypeImpl : DynamicImpl MethodBuilder finalizeMethod; int recursionCount; #if IMPORTER - RuntimeByteCodeJavaType enclosingClassWrapper; - AnnotationBuilder annotationBuilder; - TypeBuilder enumBuilder; - TypeBuilder privateInterfaceMethods; - ConcurrentDictionary nestedTypeNames; // only keys are used, values are always null + RuntimeByteCodeJavaType enclosingClassWrapper; + AnnotationBuilder annotationBuilder; + TypeBuilder enumBuilder; + TypeBuilder privateInterfaceMethods; + ConcurrentDictionary nestedTypeNames; // only keys are used, values are always null #endif internal JavaTypeImpl(RuntimeJavaType host, ClassFile f, RuntimeByteCodeJavaType wrapper) @@ -92,15 +92,15 @@ internal void CreateStep1() if (m.IsClassInitializer) { #if IMPORTER - if (IsSideEffectFreeStaticInitializerOrNoop(m, out var noop)) - { - if (noop) - flags |= MemberFlags.NoOp; - } - else - { - hasclinit = true; - } + if (IsSideEffectFreeStaticInitializerOrNoop(m, out var noop)) + { + if (noop) + flags |= MemberFlags.NoOp; + } + else + { + hasclinit = true; + } #else hasclinit = true; #endif @@ -110,12 +110,12 @@ internal void CreateStep1() flags |= MemberFlags.InternalAccess; #if IMPORTER - if (m.IsCallerSensitive && SupportsCallerID(m)) - flags |= MemberFlags.CallerID; + if (m.IsCallerSensitive && SupportsCallerID(m)) + flags |= MemberFlags.CallerID; - // set as module initializer - if (m.IsModuleInitializer) - flags |= MemberFlags.ModuleInitializer; + // set as module initializer + if (m.IsModuleInitializer) + flags |= MemberFlags.ModuleInitializer; #endif if (wrapper.IsGhost && m.IsVirtual) @@ -190,78 +190,78 @@ internal void CreateStep1() } } #if IMPORTER - wrapper.AddMapXmlFields(ref fields); + wrapper.AddMapXmlFields(ref fields); #endif wrapper.SetFields(fields); } #if IMPORTER - bool SupportsCallerID(ClassFile.Method method) - { - if ((classFile.Name == "sun.reflect.Reflection" && method.Name == "getCallerClass") || (classFile.Name == "java.lang.SecurityManager" && method.Name == "checkMemberAccess")) - { - // ignore CallerSensitive on methods that don't need CallerID parameter - return false; - } - else if (method.IsStatic) - { - return true; - } - else if ((classFile.IsFinal || classFile.Name == "java.lang.Runtime" || classFile.Name == "java.io.ObjectStreamClass") && wrapper.BaseTypeWrapper.GetMethodWrapper(method.Name, method.Signature, true) == null && !HasInterfaceMethod(wrapper, method.Name, method.Signature)) - { - // We only support CallerID instance methods on final or effectively final types, - // because we don't support interface stubs with CallerID. - // We also don't support a CallerID method overriding a method or implementing an interface. - return true; - } - else if (RequiresDynamicReflectionCallerClass(classFile.Name, method.Name, method.Signature)) - { - // We don't support CallerID for virtual methods that can be overridden or implement an interface, - // so these methods will do a dynamic stack walk if when Reflection.getCallerClass() is used. - return false; - } - else - { - // If we end up here, we either have to add support or add them to the white-list in the above clause - // to allow them to fall back to dynamic stack walking. - wrapper.ClassLoader.Diagnostics.CallerSensitiveOnUnsupportedMethod(classFile.Name, method.Name, method.Signature); - return false; - } - } - - static bool HasInterfaceMethod(RuntimeJavaType tw, string name, string signature) - { - for (; tw != null; tw = tw.BaseTypeWrapper) - { - foreach (var iface in tw.Interfaces) - { - if (iface.GetMethodWrapper(name, signature, false) != null) - { - return true; - } - if (HasInterfaceMethod(iface, name, signature)) - { - return true; - } - } - } - - return false; - } + bool SupportsCallerID(ClassFile.Method method) + { + if ((classFile.Name == "sun.reflect.Reflection" && method.Name == "getCallerClass") || (classFile.Name == "java.lang.SecurityManager" && method.Name == "checkMemberAccess")) + { + // ignore CallerSensitive on methods that don't need CallerID parameter + return false; + } + else if (method.IsStatic) + { + return true; + } + else if ((classFile.IsFinal || classFile.Name == "java.lang.Runtime" || classFile.Name == "java.io.ObjectStreamClass") && wrapper.BaseTypeWrapper.GetMethodWrapper(method.Name, method.Signature, true) == null && !HasInterfaceMethod(wrapper, method.Name, method.Signature)) + { + // We only support CallerID instance methods on final or effectively final types, + // because we don't support interface stubs with CallerID. + // We also don't support a CallerID method overriding a method or implementing an interface. + return true; + } + else if (RequiresDynamicReflectionCallerClass(classFile.Name, method.Name, method.Signature)) + { + // We don't support CallerID for virtual methods that can be overridden or implement an interface, + // so these methods will do a dynamic stack walk if when Reflection.getCallerClass() is used. + return false; + } + else + { + // If we end up here, we either have to add support or add them to the white-list in the above clause + // to allow them to fall back to dynamic stack walking. + wrapper.ClassLoader.Diagnostics.CallerSensitiveOnUnsupportedMethod(classFile.Name, method.Name, method.Signature); + return false; + } + } + + static bool HasInterfaceMethod(RuntimeJavaType tw, string name, string signature) + { + for (; tw != null; tw = tw.BaseTypeWrapper) + { + foreach (var iface in tw.Interfaces) + { + if (iface.GetMethodWrapper(name, signature, false) != null) + { + return true; + } + if (HasInterfaceMethod(iface, name, signature)) + { + return true; + } + } + } + + return false; + } #endif internal void CreateStep2() { #if IMPORTER - if (typeBuilder != null) - { - // in the static compiler we need to create the TypeBuilder from outer to inner - // and to avoid having to sort the classes this way, we instead call CreateStep2 - // on demand for outer wrappers and this necessitates us to keep track of - // whether we've already been called - return; - } + if (typeBuilder != null) + { + // in the static compiler we need to create the TypeBuilder from outer to inner + // and to avoid having to sort the classes this way, we instead call CreateStep2 + // on demand for outer wrappers and this necessitates us to keep track of + // whether we've already been called + return; + } #endif // this method is not allowed to throw exceptions (if it does, the runtime will abort) @@ -280,121 +280,121 @@ internal void CreateStep2() typeAttribs |= TypeAttributes.BeforeFieldInit; #if IMPORTER - bool cantNest = false; - bool setModifiers = false; - TypeBuilder enclosing = null; - string enclosingClassName = null; - // we only compile inner classes as nested types in the static compiler, because it has a higher cost - // and doesn't buy us anything in dynamic mode (and if fact, due to an FXBUG it would make handling - // the TypeResolve event very hard) - var outerClass = getOuterClass(); - if (outerClass.outerClass.IsNotNil) - { - enclosingClassName = classFile.GetConstantPoolClass(outerClass.outerClass); - } - else if (f.EnclosingMethod != null) - { - enclosingClassName = f.EnclosingMethod[0]; - } - - if (enclosingClassName != null) - { - if (!CheckInnerOuterNames(f.Name, enclosingClassName)) - { - wrapper.ClassLoader.Diagnostics.GenericCompilerWarning($"Incorrect {(outerClass.outerClass.IsNotNil ? "InnerClasses" : "EnclosingMethod")} attribute on {f.Name}"); - } - else - { - try - { - enclosingClassWrapper = wrapper.classLoader.TryLoadClassByName(enclosingClassName) as RuntimeByteCodeJavaType; - } - catch (RetargetableJavaException x) - { - wrapper.ClassLoader.Diagnostics.GenericCompilerWarning($"Unable to load outer class {enclosingClassName} for inner class {f.Name} ({x.GetType().Name}: {x.Message})"); - } - - if (enclosingClassWrapper != null) - { - // make sure the relationship is reciprocal (otherwise we run the risk of - // baking the outer type before the inner type) and that the inner and outer - // class live in the same class loader (when doing a multi target compilation, - // it is possible to split the two classes across assemblies) - var oimpl = enclosingClassWrapper.impl as JavaTypeImpl; - if (oimpl != null && enclosingClassWrapper.ClassLoader == wrapper.ClassLoader) - { - var outerClassFile = oimpl.classFile; - var outerInnerClasses = outerClassFile.InnerClasses; - if (outerInnerClasses == null) - { - enclosingClassWrapper = null; - } - else - { - var ok = false; - for (int i = 0; i < outerInnerClasses.Length; i++) - { - if (((outerInnerClasses[i].outerClass.IsNotNil && outerClassFile.GetConstantPoolClass(outerInnerClasses[i].outerClass) == outerClassFile.Name) || (outerInnerClasses[i].outerClass.IsNil && outerClass.outerClass.IsNil)) && outerInnerClasses[i].innerClass.IsNotNil && outerClassFile.GetConstantPoolClass(outerInnerClasses[i].innerClass) == f.Name) - { - ok = true; - break; - } - } - - if (!ok) - { - enclosingClassWrapper = null; - } - } - } - else - { - enclosingClassWrapper = null; - } - - if (enclosingClassWrapper != null) - { - enclosingClassWrapper.CreateStep2(); - enclosing = oimpl.typeBuilder; - if (outerClass.outerClass.IsNil) - { - // we need to record that we're not an inner classes, but an enclosed class - typeAttribs |= TypeAttributes.SpecialName; - } - } - else - { - wrapper.ClassLoader.Diagnostics.GenericCompilerWarning($"Non-reciprocal inner class {f.Name}"); - } - } - } - } - - if (f.IsPublic) - { - if (enclosing != null) - { - if (enclosingClassWrapper.IsPublic) - { - typeAttribs |= TypeAttributes.NestedPublic; - } - else - { - // We're a public type nested inside a non-public type, this means that we can't compile this type as a nested type, - // because that would mean it wouldn't be visible outside the assembly. - cantNest = true; - typeAttribs |= TypeAttributes.Public; - } - } - else - { - typeAttribs |= TypeAttributes.Public; - } - } - else if (enclosing != null) - { - typeAttribs |= TypeAttributes.NestedAssembly; - } + bool cantNest = false; + bool setModifiers = false; + TypeBuilder enclosing = null; + string enclosingClassName = null; + // we only compile inner classes as nested types in the static compiler, because it has a higher cost + // and doesn't buy us anything in dynamic mode (and if fact, due to an FXBUG it would make handling + // the TypeResolve event very hard) + var outerClass = getOuterClass(); + if (outerClass.outerClass.IsNotNil) + { + enclosingClassName = classFile.GetConstantPoolClass(outerClass.outerClass); + } + else if (f.EnclosingMethod != null) + { + enclosingClassName = f.EnclosingMethod[0]; + } + + if (enclosingClassName != null) + { + if (!CheckInnerOuterNames(f.Name, enclosingClassName)) + { + wrapper.ClassLoader.Diagnostics.GenericCompilerWarning($"Incorrect {(outerClass.outerClass.IsNotNil ? "InnerClasses" : "EnclosingMethod")} attribute on {f.Name}"); + } + else + { + try + { + enclosingClassWrapper = wrapper.classLoader.TryLoadClassByName(enclosingClassName) as RuntimeByteCodeJavaType; + } + catch (RetargetableJavaException x) + { + wrapper.ClassLoader.Diagnostics.GenericCompilerWarning($"Unable to load outer class {enclosingClassName} for inner class {f.Name} ({x.GetType().Name}: {x.Message})"); + } + + if (enclosingClassWrapper != null) + { + // make sure the relationship is reciprocal (otherwise we run the risk of + // baking the outer type before the inner type) and that the inner and outer + // class live in the same class loader (when doing a multi target compilation, + // it is possible to split the two classes across assemblies) + var oimpl = enclosingClassWrapper.impl as JavaTypeImpl; + if (oimpl != null && enclosingClassWrapper.ClassLoader == wrapper.ClassLoader) + { + var outerClassFile = oimpl.classFile; + var outerInnerClasses = outerClassFile.InnerClasses; + if (outerInnerClasses == null) + { + enclosingClassWrapper = null; + } + else + { + var ok = false; + for (int i = 0; i < outerInnerClasses.Length; i++) + { + if (((outerInnerClasses[i].outerClass.IsNotNil && outerClassFile.GetConstantPoolClass(outerInnerClasses[i].outerClass) == outerClassFile.Name) || (outerInnerClasses[i].outerClass.IsNil && outerClass.outerClass.IsNil)) && outerInnerClasses[i].innerClass.IsNotNil && outerClassFile.GetConstantPoolClass(outerInnerClasses[i].innerClass) == f.Name) + { + ok = true; + break; + } + } + + if (!ok) + { + enclosingClassWrapper = null; + } + } + } + else + { + enclosingClassWrapper = null; + } + + if (enclosingClassWrapper != null) + { + enclosingClassWrapper.CreateStep2(); + enclosing = oimpl.typeBuilder; + if (outerClass.outerClass.IsNil) + { + // we need to record that we're not an inner classes, but an enclosed class + typeAttribs |= TypeAttributes.SpecialName; + } + } + else + { + wrapper.ClassLoader.Diagnostics.GenericCompilerWarning($"Non-reciprocal inner class {f.Name}"); + } + } + } + } + + if (f.IsPublic) + { + if (enclosing != null) + { + if (enclosingClassWrapper.IsPublic) + { + typeAttribs |= TypeAttributes.NestedPublic; + } + else + { + // We're a public type nested inside a non-public type, this means that we can't compile this type as a nested type, + // because that would mean it wouldn't be visible outside the assembly. + cantNest = true; + typeAttribs |= TypeAttributes.Public; + } + } + else + { + typeAttribs |= TypeAttributes.Public; + } + } + else if (enclosing != null) + { + typeAttribs |= TypeAttributes.NestedAssembly; + } #else // IMPORTER if (f.IsPublic) { @@ -405,34 +405,34 @@ internal void CreateStep2() { typeAttribs |= TypeAttributes.Interface | TypeAttributes.Abstract; #if IMPORTER - // if any "meaningless" bits are set, preserve them - setModifiers |= (f.Modifiers & (Modifiers)0x99CE) != 0; - // by default we assume interfaces are abstract, so in the exceptional case we need a ModifiersAttribute - setModifiers |= (f.Modifiers & Modifiers.Abstract) == 0; - if (enclosing != null && !cantNest) - { - if (wrapper.IsGhost) - { - // TODO this is low priority, since the current Java class library doesn't define any ghost interfaces - // as inner classes - throw new NotImplementedException(); - } - - // LAMESPEC the CLI spec says interfaces cannot contain nested types (Part.II, 9.6), but that rule isn't enforced - // (and broken by J# as well), so we'll just ignore it too. - typeBuilder = enclosing.DefineNestedType(AllocNestedTypeName(enclosingClassWrapper.Name, f.Name), typeAttribs); - } - else - { - if (wrapper.IsGhost) - { - typeBuilder = wrapper.DefineGhostType(mangledTypeName, typeAttribs); - } - else - { - typeBuilder = wrapper.classLoader.GetTypeWrapperFactory().ModuleBuilder.DefineType(mangledTypeName, typeAttribs); - } - } + // if any "meaningless" bits are set, preserve them + setModifiers |= (f.Modifiers & (Modifiers)0x99CE) != 0; + // by default we assume interfaces are abstract, so in the exceptional case we need a ModifiersAttribute + setModifiers |= (f.Modifiers & Modifiers.Abstract) == 0; + if (enclosing != null && !cantNest) + { + if (wrapper.IsGhost) + { + // TODO this is low priority, since the current Java class library doesn't define any ghost interfaces + // as inner classes + throw new NotImplementedException(); + } + + // LAMESPEC the CLI spec says interfaces cannot contain nested types (Part.II, 9.6), but that rule isn't enforced + // (and broken by J# as well), so we'll just ignore it too. + typeBuilder = enclosing.DefineNestedType(AllocNestedTypeName(enclosingClassWrapper.Name, f.Name), typeAttribs); + } + else + { + if (wrapper.IsGhost) + { + typeBuilder = wrapper.DefineGhostType(mangledTypeName, typeAttribs); + } + else + { + typeBuilder = wrapper.classLoader.GetTypeWrapperFactory().ModuleBuilder.DefineType(mangledTypeName, typeAttribs); + } + } #else // IMPORTER typeBuilder = wrapper.classLoader.GetTypeWrapperFactory().ModuleBuilder.DefineType(mangledTypeName, typeAttribs); #endif // IMPORTER @@ -441,17 +441,17 @@ internal void CreateStep2() { typeAttribs |= TypeAttributes.Class; #if IMPORTER - // if any "meaningless" bits are set, preserve them - setModifiers |= (f.Modifiers & (Modifiers)0x99CE) != 0; - // by default we assume ACC_SUPER for classes, so in the exceptional case we need a ModifiersAttribute - setModifiers |= !f.IsSuper; - if (enclosing != null && !cantNest) - { - // LAMESPEC the CLI spec says interfaces cannot contain nested types (Part.II, 9.6), but that rule isn't enforced - // (and broken by J# as well), so we'll just ignore it too. - typeBuilder = enclosing.DefineNestedType(AllocNestedTypeName(enclosingClassWrapper.Name, f.Name), typeAttribs); - } - else + // if any "meaningless" bits are set, preserve them + setModifiers |= (f.Modifiers & (Modifiers)0x99CE) != 0; + // by default we assume ACC_SUPER for classes, so in the exceptional case we need a ModifiersAttribute + setModifiers |= !f.IsSuper; + if (enclosing != null && !cantNest) + { + // LAMESPEC the CLI spec says interfaces cannot contain nested types (Part.II, 9.6), but that rule isn't enforced + // (and broken by J# as well), so we'll just ignore it too. + typeBuilder = enclosing.DefineNestedType(AllocNestedTypeName(enclosingClassWrapper.Name, f.Name), typeAttribs); + } + else #endif // IMPORTER { typeBuilder = wrapper.classLoader.GetTypeWrapperFactory().ModuleBuilder.DefineType(mangledTypeName, typeAttribs); @@ -459,113 +459,113 @@ internal void CreateStep2() } #if IMPORTER - // When we're statically compiling, we associate the typeBuilder with the wrapper. This enables types in referenced assemblies to refer back to - // types that we're currently compiling (i.e. a cyclic dependency between the currently assembly we're compiling and a referenced assembly). - wrapper.Context.ClassLoaderFactory.SetWrapperForType(typeBuilder, wrapper); - - if (outerClass.outerClass.IsNotNil) - { - if (enclosing != null && cantNest) - { - wrapper.Context.AttributeHelper.SetNonNestedInnerClass(enclosing, f.Name); - } - if (enclosing == null || cantNest) - { - wrapper.Context.AttributeHelper.SetNonNestedOuterClass(typeBuilder, enclosingClassName); - } - } - - if (classFile.InnerClasses != null) - { - foreach (var inner in classFile.InnerClasses) - { - var name = classFile.GetConstantPoolClass(inner.innerClass); - var exists = false; - - try - { - exists = wrapper.ClassLoader.TryLoadClassByName(name) != null; - } - catch (RetargetableJavaException) - { - - } - - if (!exists) - { - wrapper.Context.AttributeHelper.SetNonNestedInnerClass(typeBuilder, name); - } - } - } - - if (typeBuilder.FullName != wrapper.Name && wrapper.Name.Replace('$', '+') != typeBuilder.FullName) - { - wrapper.classLoader.AddNameMapping(wrapper.Name, typeBuilder.FullName); - } - - if (f.IsAnnotation && Annotation.HasRetentionPolicyRuntime(f.Annotations)) - { - annotationBuilder = new AnnotationBuilder(wrapper.Context, this, enclosing); - wrapper.SetAnnotation(annotationBuilder); - } - - // For Java 5 Enum types, we generate a nested .NET enum. - // This is primarily to support annotations that take enum parameters. - if (f.IsEnum && f.IsPublic) - { - AddCliEnum(); - } - - AddInnerClassAttribute(enclosing != null, outerClass.innerClass.IsNotNil, mangledTypeName, outerClass.accessFlags); - if (classFile.DeprecatedAttribute && !Annotation.HasObsoleteAttribute(classFile.Annotations)) - { - wrapper.Context.AttributeHelper.SetDeprecatedAttribute(typeBuilder); - } - - if (classFile.GenericSignature != null) - { - wrapper.Context.AttributeHelper.SetSignatureAttribute(typeBuilder, classFile.GenericSignature); - } - if (classFile.EnclosingMethod != null) - { - if (outerClass.outerClass.IsNil && enclosing != null && !cantNest) - { - // we don't need to record the enclosing type, if we're compiling the current type as a nested type because of the EnclosingMethod attribute - wrapper.Context.AttributeHelper.SetEnclosingMethodAttribute(typeBuilder, null, classFile.EnclosingMethod[1], classFile.EnclosingMethod[2]); - } - else - { - wrapper.Context.AttributeHelper.SetEnclosingMethodAttribute(typeBuilder, classFile.EnclosingMethod[0], classFile.EnclosingMethod[1], classFile.EnclosingMethod[2]); - } - } - - if (classFile.RuntimeVisibleTypeAnnotations.Count > 0) - wrapper.Context.AttributeHelper.SetRuntimeVisibleTypeAnnotationsAttribute(typeBuilder, in classFile.RuntimeVisibleTypeAnnotations); - - if (wrapper.classLoader.EmitStackTraceInfo) - { - if (f.SourceFileAttribute != null) - { - if ((enclosingClassWrapper == null && f.SourceFileAttribute == typeBuilder.Name + ".java") - || (enclosingClassWrapper != null && f.SourceFileAttribute == enclosingClassWrapper.sourceFileName)) - { - // we don't need to record the name because it matches our heuristic - } - else - { - wrapper.Context.AttributeHelper.SetSourceFile(typeBuilder, f.SourceFileAttribute); - } - } - else - { - wrapper.Context.AttributeHelper.SetSourceFile(typeBuilder, null); - } - } - // NOTE in Whidbey we can (and should) use CompilerGeneratedAttribute to mark Synthetic types - if (setModifiers || classFile.IsInternal || (classFile.Modifiers & (Modifiers.Synthetic | Modifiers.Annotation | Modifiers.Enum)) != 0) - { - wrapper.Context.AttributeHelper.SetModifiers(typeBuilder, classFile.Modifiers, classFile.IsInternal); - } + // When we're statically compiling, we associate the typeBuilder with the wrapper. This enables types in referenced assemblies to refer back to + // types that we're currently compiling (i.e. a cyclic dependency between the currently assembly we're compiling and a referenced assembly). + wrapper.Context.ClassLoaderFactory.SetWrapperForType(typeBuilder, wrapper); + + if (outerClass.outerClass.IsNotNil) + { + if (enclosing != null && cantNest) + { + wrapper.Context.AttributeHelper.SetNonNestedInnerClass(enclosing, f.Name); + } + if (enclosing == null || cantNest) + { + wrapper.Context.AttributeHelper.SetNonNestedOuterClass(typeBuilder, enclosingClassName); + } + } + + if (classFile.InnerClasses != null) + { + foreach (var inner in classFile.InnerClasses) + { + var name = classFile.GetConstantPoolClass(inner.innerClass); + var exists = false; + + try + { + exists = wrapper.ClassLoader.TryLoadClassByName(name) != null; + } + catch (RetargetableJavaException) + { + + } + + if (!exists) + { + wrapper.Context.AttributeHelper.SetNonNestedInnerClass(typeBuilder, name); + } + } + } + + if (typeBuilder.FullName != wrapper.Name && wrapper.Name.Replace('$', '+') != typeBuilder.FullName) + { + wrapper.classLoader.AddNameMapping(wrapper.Name, typeBuilder.FullName); + } + + if (f.IsAnnotation && Annotation.HasRetentionPolicyRuntime(f.Annotations)) + { + annotationBuilder = new AnnotationBuilder(wrapper.Context, this, enclosing); + wrapper.SetAnnotation(annotationBuilder); + } + + // For Java 5 Enum types, we generate a nested .NET enum. + // This is primarily to support annotations that take enum parameters. + if (f.IsEnum && f.IsPublic) + { + AddCliEnum(); + } + + AddInnerClassAttribute(enclosing != null, outerClass.innerClass.IsNotNil, mangledTypeName, outerClass.accessFlags); + if (classFile.DeprecatedAttribute && !Annotation.HasObsoleteAttribute(classFile.Annotations)) + { + wrapper.Context.AttributeHelper.SetDeprecatedAttribute(typeBuilder); + } + + if (classFile.GenericSignature != null) + { + wrapper.Context.AttributeHelper.SetSignatureAttribute(typeBuilder, classFile.GenericSignature); + } + if (classFile.EnclosingMethod != null) + { + if (outerClass.outerClass.IsNil && enclosing != null && !cantNest) + { + // we don't need to record the enclosing type, if we're compiling the current type as a nested type because of the EnclosingMethod attribute + wrapper.Context.AttributeHelper.SetEnclosingMethodAttribute(typeBuilder, null, classFile.EnclosingMethod[1], classFile.EnclosingMethod[2]); + } + else + { + wrapper.Context.AttributeHelper.SetEnclosingMethodAttribute(typeBuilder, classFile.EnclosingMethod[0], classFile.EnclosingMethod[1], classFile.EnclosingMethod[2]); + } + } + + if (classFile.RuntimeVisibleTypeAnnotations.Count > 0) + wrapper.Context.AttributeHelper.SetRuntimeVisibleTypeAnnotationsAttribute(typeBuilder, in classFile.RuntimeVisibleTypeAnnotations); + + if (wrapper.classLoader.EmitStackTraceInfo) + { + if (f.SourceFileAttribute != null) + { + if ((enclosingClassWrapper == null && f.SourceFileAttribute == typeBuilder.Name + ".java") + || (enclosingClassWrapper != null && f.SourceFileAttribute == enclosingClassWrapper.sourceFileName)) + { + // we don't need to record the name because it matches our heuristic + } + else + { + wrapper.Context.AttributeHelper.SetSourceFile(typeBuilder, f.SourceFileAttribute); + } + } + else + { + wrapper.Context.AttributeHelper.SetSourceFile(typeBuilder, null); + } + } + // NOTE in Whidbey we can (and should) use CompilerGeneratedAttribute to mark Synthetic types + if (setModifiers || classFile.IsInternal || (classFile.Modifiers & (Modifiers.Synthetic | Modifiers.Annotation | Modifiers.Enum)) != 0) + { + wrapper.Context.AttributeHelper.SetModifiers(typeBuilder, classFile.Modifiers, classFile.IsInternal); + } #endif // IMPORTER if (hasclinit) { @@ -582,7 +582,7 @@ internal void CreateStep2() } } #if IMPORTER - finally { } + finally { } #else catch (Exception x) { @@ -593,50 +593,49 @@ internal void CreateStep2() #if IMPORTER - private void AddInnerClassAttribute(bool isNestedType, bool isInnerClass, string mangledTypeName, Modifiers innerClassFlags) - { - string name = classFile.Name; - - if (isNestedType) - { - if (name == enclosingClassWrapper.Name + "$" + typeBuilder.Name) - { - name = null; - } - } - else if (name == mangledTypeName) - { - name = null; - } - - if ((isInnerClass && RuntimeManagedByteCodeJavaType.PredictReflectiveModifiers(wrapper) != innerClassFlags) || name != null) - { - // HACK we abuse the InnerClassAttribute to record to real name for non-inner classes as well - wrapper.Context.AttributeHelper.SetInnerClass(typeBuilder, name, isInnerClass ? innerClassFlags : wrapper.Modifiers); - } - } - - private void AddCliEnum() - { - ImportClassLoader ccl = wrapper.classLoader; - string name = "__Enum"; - while (!ccl.ReserveName(classFile.Name + "$" + name)) - { - name += "_"; - } - enumBuilder = typeBuilder.DefineNestedType(name, TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.NestedPublic | TypeAttributes.Serializable, wrapper.Context.Types.Enum); - wrapper.Context.AttributeHelper.HideFromJava(enumBuilder); - enumBuilder.DefineField("value__", wrapper.Context.Types.Int32, FieldAttributes.Public | FieldAttributes.SpecialName | FieldAttributes.RTSpecialName); - for (int i = 0; i < classFile.Fields.Length; i++) - { - if (classFile.Fields[i].IsEnum) - { - FieldBuilder fieldBuilder = enumBuilder.DefineField(classFile.Fields[i].Name, enumBuilder, FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal); - fieldBuilder.SetConstant(i); - } - } - wrapper.SetEnumType(enumBuilder); - } + private void AddInnerClassAttribute(bool isNestedType, bool isInnerClass, string mangledTypeName, Modifiers innerClassFlags) + { + string name = classFile.Name; + + if (isNestedType) + { + if (name == enclosingClassWrapper.Name + "$" + typeBuilder.Name) + { + name = null; + } + } + else if (name == mangledTypeName) + { + name = null; + } + + if ((isInnerClass && RuntimeManagedByteCodeJavaType.PredictReflectiveModifiers(wrapper) != innerClassFlags) || name != null) + { + // HACK we abuse the InnerClassAttribute to record to real name for non-inner classes as well + wrapper.Context.AttributeHelper.SetInnerClass(typeBuilder, name, isInnerClass ? innerClassFlags : wrapper.Modifiers); + } + } + + void AddCliEnum() + { + var ccl = wrapper.classLoader; + string name = "__Enum"; + while (!ccl.ReserveName(classFile.Name + "$" + name)) + name += "_"; + + enumBuilder = typeBuilder.DefineNestedType(name, TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.NestedPublic | TypeAttributes.Serializable, wrapper.Context.Types.Enum.AsReflection()); + wrapper.Context.AttributeHelper.HideFromJava(enumBuilder); + enumBuilder.DefineField("value__", wrapper.Context.Types.Int32.AsReflection(), FieldAttributes.Public | FieldAttributes.SpecialName | FieldAttributes.RTSpecialName); + for (int i = 0; i < classFile.Fields.Length; i++) + { + if (classFile.Fields[i].IsEnum) + { + FieldBuilder fieldBuilder = enumBuilder.DefineField(classFile.Fields[i].Name, enumBuilder, FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal); + fieldBuilder.SetConstant(i); + } + } + wrapper.SetEnumType(enumBuilder); + } #endif void AddClinitTrigger() @@ -686,110 +685,110 @@ private static bool HasStructLayoutAttributeAnnotation(ClassFile c) } #if IMPORTER - private ClassFile.InnerClass getOuterClass() - { - ClassFile.InnerClass[] innerClasses = classFile.InnerClasses; - if (innerClasses != null) - { - for (int j = 0; j < innerClasses.Length; j++) - { - if (innerClasses[j].innerClass.IsNotNil && classFile.GetConstantPoolClass(innerClasses[j].innerClass) == classFile.Name) - { - return innerClasses[j]; - } - } - } - return new ClassFile.InnerClass(); - } - - private bool IsSideEffectFreeStaticInitializerOrNoop(ClassFile.Method m, out bool noop) - { - if (m.ExceptionTable.Length != 0) - { - noop = false; - return false; - } - noop = true; - for (int i = 0; i < m.Instructions.Length; i++) - { - NormalizedByteCode bc; - while ((bc = m.Instructions[i].NormalizedOpCode) == NormalizedByteCode.__goto) - { - int target = m.Instructions[i].TargetIndex; - if (target <= i) - { - // backward branch means we can't do anything - noop = false; - return false; - } - // we must skip the unused instructions because the "remove assertions" optimization - // uses a goto to remove the (now unused) code - i = target; - } - if (bc == NormalizedByteCode.__getstatic || bc == NormalizedByteCode.__putstatic) - { - ClassFile.ConstantPoolItemFieldref fld = classFile.SafeGetFieldref(m.Instructions[i].Arg1); - if (fld == null || fld.Class != classFile.Name) - { - noop = false; - return false; - } - // don't allow getstatic to load non-primitive fields, because that would - // cause the verifier to try to load the type - if (bc == NormalizedByteCode.__getstatic && "L[".IndexOf(fld.Signature[0]) != -1) - { - noop = false; - return false; - } - ClassFile.Field field = classFile.GetField(fld.Name, fld.Signature); - if (field == null) - { - noop = false; - return false; - } - if (bc == NormalizedByteCode.__putstatic) - { - if (field.IsProperty && field.PropertySetter != null) - { - noop = false; - return false; - } - } - else if (field.IsProperty && field.PropertyGetter != null) - { - noop = false; - return false; - } - } - else if (ByteCodeMetaData.CanThrowException(bc)) - { - noop = false; - return false; - } - else if (bc == NormalizedByteCode.__aconst_null - || (bc == NormalizedByteCode.__iconst && m.Instructions[i].Arg1 == 0) - || bc == NormalizedByteCode.__return - || bc == NormalizedByteCode.__nop) - { - // valid instructions in a potential noop - } - else - { - noop = false; - } - } - // the method needs to be verifiable to be side effect free, since we already analysed it, - // we know that the verifier won't try to load any types (which isn't allowed at this time) - try - { - wrapper.Context.MethodAnalyzerFactory.Create(null, wrapper, null, classFile, m, wrapper.classLoader); - return true; - } - catch (VerifyError) - { - return false; - } - } + private ClassFile.InnerClass getOuterClass() + { + ClassFile.InnerClass[] innerClasses = classFile.InnerClasses; + if (innerClasses != null) + { + for (int j = 0; j < innerClasses.Length; j++) + { + if (innerClasses[j].innerClass.IsNotNil && classFile.GetConstantPoolClass(innerClasses[j].innerClass) == classFile.Name) + { + return innerClasses[j]; + } + } + } + return new ClassFile.InnerClass(); + } + + private bool IsSideEffectFreeStaticInitializerOrNoop(ClassFile.Method m, out bool noop) + { + if (m.ExceptionTable.Length != 0) + { + noop = false; + return false; + } + noop = true; + for (int i = 0; i < m.Instructions.Length; i++) + { + NormalizedByteCode bc; + while ((bc = m.Instructions[i].NormalizedOpCode) == NormalizedByteCode.__goto) + { + int target = m.Instructions[i].TargetIndex; + if (target <= i) + { + // backward branch means we can't do anything + noop = false; + return false; + } + // we must skip the unused instructions because the "remove assertions" optimization + // uses a goto to remove the (now unused) code + i = target; + } + if (bc == NormalizedByteCode.__getstatic || bc == NormalizedByteCode.__putstatic) + { + ClassFile.ConstantPoolItemFieldref fld = classFile.SafeGetFieldref(m.Instructions[i].Arg1); + if (fld == null || fld.Class != classFile.Name) + { + noop = false; + return false; + } + // don't allow getstatic to load non-primitive fields, because that would + // cause the verifier to try to load the type + if (bc == NormalizedByteCode.__getstatic && "L[".IndexOf(fld.Signature[0]) != -1) + { + noop = false; + return false; + } + ClassFile.Field field = classFile.GetField(fld.Name, fld.Signature); + if (field == null) + { + noop = false; + return false; + } + if (bc == NormalizedByteCode.__putstatic) + { + if (field.IsProperty && field.PropertySetter != null) + { + noop = false; + return false; + } + } + else if (field.IsProperty && field.PropertyGetter != null) + { + noop = false; + return false; + } + } + else if (ByteCodeMetaData.CanThrowException(bc)) + { + noop = false; + return false; + } + else if (bc == NormalizedByteCode.__aconst_null + || (bc == NormalizedByteCode.__iconst && m.Instructions[i].Arg1 == 0) + || bc == NormalizedByteCode.__return + || bc == NormalizedByteCode.__nop) + { + // valid instructions in a potential noop + } + else + { + noop = false; + } + } + // the method needs to be verifiable to be side effect free, since we already analysed it, + // we know that the verifier won't try to load any types (which isn't allowed at this time) + try + { + wrapper.Context.MethodAnalyzerFactory.Create(null, wrapper, null, classFile, m, wrapper.classLoader); + return true; + } + catch (VerifyError) + { + return false; + } + } #endif // IMPORTER private RuntimeJavaMethod GetMethodWrapperDuringCtor(RuntimeJavaType lookup, IList methods, string name, string sig) @@ -862,35 +861,34 @@ private void AddMirandaMethods(List methods, List outer.Length + 1 && inner[outer.Length] == '$' && inner.StartsWith(outer, StringComparison.Ordinal); - } - - private string AllocNestedTypeName(string outer, string inner) - { - Debug.Assert(CheckInnerOuterNames(inner, outer)); - nestedTypeNames ??= new ConcurrentDictionary(); - return DynamicClassLoaderFactory.TypeNameMangleImpl(nestedTypeNames, inner.Substring(outer.Length + 1), null); - } + private static bool CheckInnerOuterNames(string inner, string outer) + { + // do some sanity checks on the inner/outer class names + return inner.Length > outer.Length + 1 && inner[outer.Length] == '$' && inner.StartsWith(outer, StringComparison.Ordinal); + } + + private string AllocNestedTypeName(string outer, string inner) + { + Debug.Assert(CheckInnerOuterNames(inner, outer)); + nestedTypeNames ??= new ConcurrentDictionary(); + return DynamicClassLoaderFactory.TypeNameMangleImpl(nestedTypeNames, inner.Substring(outer.Length + 1), null); + } #endif @@ -922,7 +920,7 @@ private static void CheckLoaderConstraints(RuntimeJavaMethod mw, RuntimeJavaMeth else { #if IMPORTER - StaticCompiler.LinkageError("Method \"{2}.{3}{4}\" has a return type \"{0}\" and tries to override method \"{5}.{3}{4}\" that has a return type \"{1}\"", mw.ReturnType, baseMethod.ReturnType, mw.DeclaringType.Name, mw.Name, mw.Signature, baseMethod.DeclaringType.Name); + StaticCompiler.LinkageError("Method \"{2}.{3}{4}\" has a return type \"{0}\" and tries to override method \"{5}.{3}{4}\" that has a return type \"{1}\"", mw.ReturnType, baseMethod.ReturnType, mw.DeclaringType.Name, mw.Name, mw.Signature, baseMethod.DeclaringType.Name); #else throw new LinkageError("Loader constraints violated"); #endif @@ -945,7 +943,7 @@ private static void CheckLoaderConstraints(RuntimeJavaMethod mw, RuntimeJavaMeth else { #if IMPORTER - StaticCompiler.LinkageError("Method \"{2}.{3}{4}\" has an argument type \"{0}\" and tries to override method \"{5}.{3}{4}\" that has an argument type \"{1}\"", here[i], there[i], mw.DeclaringType.Name, mw.Name, mw.Signature, baseMethod.DeclaringType.Name); + StaticCompiler.LinkageError("Method \"{2}.{3}{4}\" has an argument type \"{0}\" and tries to override method \"{5}.{3}{4}\" that has an argument type \"{1}\"", here[i], there[i], mw.DeclaringType.Name, mw.Name, mw.Signature, baseMethod.DeclaringType.Name); #else throw new LinkageError("Loader constraints violated"); #endif @@ -975,75 +973,75 @@ internal override FieldInfo LinkField(RuntimeJavaField fw) } int fieldIndex = GetFieldIndex(fw); #if IMPORTER - if (wrapper.ClassLoader.RemoveUnusedFields - && fw.IsPrivate - && fw.IsStatic - && fw.IsFinal - && !fw.IsSerialVersionUID - && classFile.Fields[fieldIndex].Annotations == null - && !classFile.IsReferenced(classFile.Fields[fieldIndex])) - { - // unused, so we skip it - wrapper.ClassLoader.Diagnostics.GenericCompilerInfo($"Unused field {wrapper.Name}::{fw.Name}"); - return null; - } - - // for compatibility with broken Java code that assumes that reflection returns the fields in class declaration - // order, we emit the fields in class declaration order in the .NET metadata (and then when we retrieve them - // using .NET reflection, we sort on metadata token.) - if (fieldIndex > 0) - { - if (!fields[fieldIndex - 1].IsLinked) - { - for (int i = 0; i < fieldIndex; i++) - { - fields[i].Link(); - } - } - } - - if (fieldIndex >= classFile.Fields.Length) - { - // this must be a field defined in map.xml - FieldAttributes fieldAttribs = 0; - if (fw.IsPublic) - { - fieldAttribs |= FieldAttributes.Public; - } - else if (fw.IsProtected) - { - fieldAttribs |= FieldAttributes.FamORAssem; - } - else if (fw.IsPrivate) - { - fieldAttribs |= FieldAttributes.Private; - } - else - { - fieldAttribs |= FieldAttributes.Assembly; - } - if (fw.IsStatic) - { - fieldAttribs |= FieldAttributes.Static; - } - if (fw.IsFinal) - { - fieldAttribs |= FieldAttributes.InitOnly; - } - return DefineField(fw.Name, fw.FieldTypeWrapper, fieldAttribs, fw.IsVolatile); - } -#endif // IMPORTER - FieldBuilder field; - ClassFile.Field fld = classFile.Fields[fieldIndex]; - FieldAttributes attribs = 0; - string realFieldName = UnicodeUtil.EscapeInvalidSurrogates(fld.Name); - if (!ReferenceEquals(realFieldName, fld.Name)) - { - attribs |= FieldAttributes.SpecialName; + if (wrapper.ClassLoader.RemoveUnusedFields + && fw.IsPrivate + && fw.IsStatic + && fw.IsFinal + && !fw.IsSerialVersionUID + && classFile.Fields[fieldIndex].Annotations == null + && !classFile.IsReferenced(classFile.Fields[fieldIndex])) + { + // unused, so we skip it + wrapper.ClassLoader.Diagnostics.GenericCompilerInfo($"Unused field {wrapper.Name}::{fw.Name}"); + return null; } - MethodAttributes methodAttribs = MethodAttributes.HideBySig; -#if IMPORTER - bool setModifiers = fld.IsInternal || (fld.Modifiers & (Modifiers.Synthetic | Modifiers.Enum)) != 0; + + // for compatibility with broken Java code that assumes that reflection returns the fields in class declaration + // order, we emit the fields in class declaration order in the .NET metadata (and then when we retrieve them + // using .NET reflection, we sort on metadata token.) + if (fieldIndex > 0) + { + if (!fields[fieldIndex - 1].IsLinked) + { + for (int i = 0; i < fieldIndex; i++) + { + fields[i].Link(); + } + } + } + + if (fieldIndex >= classFile.Fields.Length) + { + // this must be a field defined in map.xml + FieldAttributes fieldAttribs = 0; + if (fw.IsPublic) + { + fieldAttribs |= FieldAttributes.Public; + } + else if (fw.IsProtected) + { + fieldAttribs |= FieldAttributes.FamORAssem; + } + else if (fw.IsPrivate) + { + fieldAttribs |= FieldAttributes.Private; + } + else + { + fieldAttribs |= FieldAttributes.Assembly; + } + if (fw.IsStatic) + { + fieldAttribs |= FieldAttributes.Static; + } + if (fw.IsFinal) + { + fieldAttribs |= FieldAttributes.InitOnly; + } + return DefineField(fw.Name, fw.FieldTypeWrapper, fieldAttribs, fw.IsVolatile); + } +#endif // IMPORTER + FieldBuilder field; + ClassFile.Field fld = classFile.Fields[fieldIndex]; + FieldAttributes attribs = 0; + string realFieldName = UnicodeUtil.EscapeInvalidSurrogates(fld.Name); + if (!ReferenceEquals(realFieldName, fld.Name)) + { + attribs |= FieldAttributes.SpecialName; + } + MethodAttributes methodAttribs = MethodAttributes.HideBySig; +#if IMPORTER + bool setModifiers = fld.IsInternal || (fld.Modifiers & (Modifiers.Synthetic | Modifiers.Enum)) != 0; #endif if (fld.IsPrivate) { @@ -1083,28 +1081,28 @@ internal override FieldInfo LinkField(RuntimeJavaField fw) else { #if IMPORTER - if (wrapper.IsPublic && wrapper.NeedsType2AccessStub(fw)) - { - // this field is going to get a type 2 access stub, so we hide the actual field - attribs &= ~FieldAttributes.FieldAccessMask; - attribs |= FieldAttributes.Assembly; - // instead of adding HideFromJava we rename the field to avoid confusing broken compilers - // see https://sourceforge.net/tracker/?func=detail&atid=525264&aid=3056721&group_id=69637 - // additional note: now that we maintain the ordering of the fields, we need to recognize - // these fields so that we know where to insert the corresponding accessor property FieldWrapper. - realFieldName = NamePrefix.Type2AccessStubBackingField + realFieldName; - } - else if (fld.IsFinal) - { - if (wrapper.IsInterface || wrapper.classLoader.StrictFinalFieldSemantics) - { - attribs |= FieldAttributes.InitOnly; - } - else - { - setModifiers = true; - } - } + if (wrapper.IsPublic && wrapper.NeedsType2AccessStub(fw)) + { + // this field is going to get a type 2 access stub, so we hide the actual field + attribs &= ~FieldAttributes.FieldAccessMask; + attribs |= FieldAttributes.Assembly; + // instead of adding HideFromJava we rename the field to avoid confusing broken compilers + // see https://sourceforge.net/tracker/?func=detail&atid=525264&aid=3056721&group_id=69637 + // additional note: now that we maintain the ordering of the fields, we need to recognize + // these fields so that we know where to insert the corresponding accessor property FieldWrapper. + realFieldName = NamePrefix.Type2AccessStubBackingField + realFieldName; + } + else if (fld.IsFinal) + { + if (wrapper.IsInterface || wrapper.classLoader.StrictFinalFieldSemantics) + { + attribs |= FieldAttributes.InitOnly; + } + else + { + setModifiers = true; + } + } #else if (fld.IsFinal && wrapper.IsInterface) { @@ -1120,21 +1118,21 @@ internal override FieldInfo LinkField(RuntimeJavaField fw) field.SetCustomAttribute(transientAttrib); } #if IMPORTER - { - // if the Java modifiers cannot be expressed in .NET, we emit the Modifiers attribute to store - // the Java modifiers - if (setModifiers) - wrapper.Context.AttributeHelper.SetModifiers(field, fld.Modifiers, fld.IsInternal); + { + // if the Java modifiers cannot be expressed in .NET, we emit the Modifiers attribute to store + // the Java modifiers + if (setModifiers) + wrapper.Context.AttributeHelper.SetModifiers(field, fld.Modifiers, fld.IsInternal); - if (fld.DeprecatedAttribute && !Annotation.HasObsoleteAttribute(fld.Annotations)) - wrapper.Context.AttributeHelper.SetDeprecatedAttribute(field); + if (fld.DeprecatedAttribute && !Annotation.HasObsoleteAttribute(fld.Annotations)) + wrapper.Context.AttributeHelper.SetDeprecatedAttribute(field); - if (fld.GenericSignature != null) - wrapper.Context.AttributeHelper.SetSignatureAttribute(field, fld.GenericSignature); + if (fld.GenericSignature != null) + wrapper.Context.AttributeHelper.SetSignatureAttribute(field, fld.GenericSignature); - if (fld.RuntimeVisibleTypeAnnotations.Count > 0) - wrapper.Context.AttributeHelper.SetRuntimeVisibleTypeAnnotationsAttribute(field, in fld.RuntimeVisibleTypeAnnotations); - } + if (fld.RuntimeVisibleTypeAnnotations.Count > 0) + wrapper.Context.AttributeHelper.SetRuntimeVisibleTypeAnnotationsAttribute(field, in fld.RuntimeVisibleTypeAnnotations); + } #endif return field; @@ -1142,7 +1140,7 @@ internal override FieldInfo LinkField(RuntimeJavaField fw) FieldBuilder DefineField(string name, RuntimeJavaType tw, FieldAttributes attribs, bool isVolatile) { - var modreq = isVolatile ? [wrapper.Context.Types.IsVolatile] : Type.EmptyTypes; + var modreq = isVolatile ? [wrapper.Context.Types.IsVolatile] : []; return typeBuilder.DefineField(name, tw.TypeAsSignatureType, modreq, wrapper.GetModOpt(tw, false), attribs); } @@ -1152,746 +1150,749 @@ internal override void EmitRunClassConstructor(CodeEmitter ilgen) ilgen.Emit(OpCodes.Call, clinitMethod); } - internal override DynamicImpl Finish() - { - var baseTypeWrapper = wrapper.BaseTypeWrapper; - if (baseTypeWrapper != null) - { - baseTypeWrapper.Finish(); - baseTypeWrapper.LinkAll(); + internal override DynamicImpl Finish() + { + var baseTypeWrapper = wrapper.BaseTypeWrapper; + if (baseTypeWrapper != null) + { + baseTypeWrapper.Finish(); + baseTypeWrapper.LinkAll(); + } + + // NOTE there is a bug in the CLR (.NET 1.0 & 1.1 [1.2 is not yet available]) that + // causes the AppDomain.TypeResolve event to receive the incorrect type name for nested types. + // The Name in the ResolveEventArgs contains only the nested type name, not the full type name, + // for example, if the type being resolved is "MyOuterType+MyInnerType", then the event only + // receives "MyInnerType" as the name. Since we only compile inner classes as nested types + // when we're statically compiling, we can only run into this bug when we're statically compiling. + // NOTE To work around this bug, we have to make sure that all types that are going to be + // required in finished form, are finished explicitly here. It isn't clear what other types are + // required to be finished. I instrumented a static compilation of classpath.dll and this + // turned up no other cases of the TypeResolve event firing. + foreach (RuntimeJavaType iface in wrapper.interfaces) + { + iface.Finish(); + iface.LinkAll(); + } + + // make sure all classes are loaded, before we start finishing the type. During finishing, we + // may not run any Java code, because that might result in a request to finish the type that we + // are in the process of finishing, and this would be a problem. + // Prevent infinity recursion for broken class loaders by keeping a recursion count and falling + // back to late binding if we recurse more than twice. + var mode = System.Threading.Interlocked.Increment(ref recursionCount) > 2 || (JVM.DisableEagerClassLoading && wrapper.Name != "sun.reflect.misc.Trampoline") + ? LoadMode.ReturnUnloadable + : LoadMode.Link; + try + { + classFile.Link(wrapper, mode); + + for (int i = 0; i < fields.Length; i++) + fields[i].Link(mode); + + for (int i = 0; i < methods.Length; i++) + methods[i].Link(mode); + } + finally + { + System.Threading.Interlocked.Decrement(ref recursionCount); + } + + // this is the correct lock, FinishCore doesn't call any user code and mutates global state, + // so it needs to be protected by a lock. + lock (this) + { + FinishedTypeImpl impl; + try + { + // call FinishCore in the finally to avoid Thread.Abort interrupting the thread + } + finally + { + impl = FinishCore(); + } + return impl; + } + } + + FinishedTypeImpl FinishCore() + { + // it is possible that the loading of the referenced classes triggered a finish of us, + // if that happens, we just return + if (finishedType != null) + return finishedType; + + if (finishInProgress) + throw new InvalidOperationException("Recursive finish attempt for " + wrapper.Name); + + finishInProgress = true; + wrapper.ClassLoader.Diagnostics.GenericCompilerTrace($"Finishing: {wrapper.Name}"); + Profiler.Enter("JavaTypeImpl.Finish.Core"); + + try + { + RuntimeJavaType declaringTypeWrapper = null; + var innerClassesTypeWrappers = Array.Empty(); + + // if we're an inner class, we need to attach an InnerClass attribute + ClassFile.InnerClass[] innerclasses = classFile.InnerClasses; + if (innerclasses != null) + { + // TODO consider not pre-computing innerClassesTypeWrappers and declaringTypeWrapper here + var wrappers = new List(); + for (int i = 0; i < innerclasses.Length; i++) + { + if (innerclasses[i].innerClass.IsNotNil && innerclasses[i].outerClass.IsNotNil) + { + if (classFile.GetConstantPoolClassType(innerclasses[i].outerClass) == wrapper) + { + wrappers.Add(classFile.GetConstantPoolClassType(innerclasses[i].innerClass)); + } + if (classFile.GetConstantPoolClassType(innerclasses[i].innerClass) == wrapper) + { + declaringTypeWrapper = classFile.GetConstantPoolClassType(innerclasses[i].outerClass); + } + } + } + innerClassesTypeWrappers = wrappers.ToArray(); +#if IMPORTER + // before we bake our type, we need to link any inner annotations to allow them to create their attribute type (as a nested type) + foreach (var tw in innerClassesTypeWrappers) + { + var dtw = tw as RuntimeByteCodeJavaType; + if (dtw != null) + { + var impl = dtw.impl as JavaTypeImpl; + if (impl != null) + if (impl.annotationBuilder != null) + impl.annotationBuilder.Link(); + } + } +#endif + } +#if IMPORTER + + if (annotationBuilder != null) + { + var cab = new CustomAttributeBuilder(wrapper.Context.Resolver.ResolveRuntimeType(typeof(AnnotationAttributeAttribute).FullName).AsReflection().GetConstructor(new Type[] { wrapper.Context.Types.String }), new object[] { UnicodeUtil.EscapeInvalidSurrogates(annotationBuilder.AttributeTypeName) }); + typeBuilder.SetCustomAttribute(cab); + } + + if (!wrapper.IsInterface && wrapper.IsMapUnsafeException) + { + // mark all exceptions that are unsafe for mapping with a custom attribute, + // so that at runtime we can quickly assertain if an exception type can be + // caught without filtering + wrapper.Context.AttributeHelper.SetExceptionIsUnsafeForMapping(typeBuilder); + } +#endif + + var context = new FinishContext(wrapper.Context, host, classFile, wrapper, typeBuilder); + var type = context.FinishImpl(); + +#if IMPORTER + if (annotationBuilder != null) + { + annotationBuilder.Finish(this); + } + if (enumBuilder != null) + { + enumBuilder.CreateType(); + } + if (privateInterfaceMethods != null) + { + privateInterfaceMethods.CreateType(); + } +#endif + var finishedClinitMethod = (MethodInfo)clinitMethod; +#if !IMPORTER + if (finishedClinitMethod != null) + { + // In dynamic mode, we may need to emit a call to this method from a DynamicMethod which doesn't support calling unfinished methods, + // so we must resolve to the real method here. + finishedClinitMethod = type.GetMethod("__", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); + } +#endif + + finishedType = new FinishedTypeImpl(type, innerClassesTypeWrappers, declaringTypeWrapper, wrapper.ReflectiveModifiers, Metadata.Create(classFile), finishedClinitMethod, finalizeMethod, host); + return finishedType; + } +#if !IMPORTER + catch (Exception x) + { + throw new InternalException($"Exception during finishing of: {wrapper.Name}", x); + } +#endif + finally + { + Profiler.Leave("JavaTypeImpl.Finish.Core"); + } + } + +#if IMPORTER + + private bool IsValidAnnotationElementType(string type) + { + if (type[0] == '[') + type = type.Substring(1); + + switch (type) + { + case "Z": + case "B": + case "S": + case "C": + case "I": + case "J": + case "F": + case "D": + case "Ljava.lang.String;": + case "Ljava.lang.Class;": + return true; + } + + if (type.StartsWith("L") && type.EndsWith(";")) + { + try + { + var tw = wrapper.ClassLoader.TryLoadClassByName(type.Substring(1, type.Length - 2)); + if (tw != null) + { + if ((tw.Modifiers & Modifiers.Annotation) != 0) + return true; + + if ((tw.Modifiers & Modifiers.Enum) != 0) + { + var enumType = wrapper.Context.ClassLoaderFactory.GetBootstrapClassLoader().TryLoadClassByName("java.lang.Enum"); + if (enumType != null && tw.IsSubTypeOf(enumType)) + return true; + } + } + } + catch + { + + } + } + + return false; + } + + sealed class AnnotationBuilder : Annotation + { + + readonly RuntimeContext context; + + JavaTypeImpl impl; + TypeBuilder outer; + TypeBuilder annotationTypeBuilder; + TypeBuilder attributeTypeBuilder; + MethodBuilder defineConstructor; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + internal AnnotationBuilder(RuntimeContext context, JavaTypeImpl o, TypeBuilder outer) + { + this.context = context; + this.impl = o; + this.outer = outer; + } + + internal void Link() + { + if (impl == null) + { + return; + } + JavaTypeImpl o = impl; + impl = null; + + // Make sure the annotation type only has valid methods + for (int i = 0; i < o.methods.Length; i++) + { + if (!o.methods[i].IsStatic) + { + if (!o.methods[i].Signature.StartsWith("()")) + { + return; + } + if (!o.IsValidAnnotationElementType(o.methods[i].Signature.Substring(2))) + { + return; + } + } + } + + // we only set annotationTypeBuilder if we're valid + annotationTypeBuilder = o.typeBuilder; + + var annotationAttributeBaseType = context.ClassLoaderFactory.LoadClassCritical("ikvm.internal.AnnotationAttributeBase"); + + // make sure we don't clash with another class name + var ccl = o.wrapper.classLoader; + string name = UnicodeUtil.EscapeInvalidSurrogates(o.classFile.Name); + while (!ccl.ReserveName(name + "Attribute")) + { + name += "_"; + } + + var typeAttributes = TypeAttributes.Class | TypeAttributes.Sealed; + if (o.enclosingClassWrapper != null) + { + if (o.wrapper.IsPublic) + { + typeAttributes |= TypeAttributes.NestedPublic; + } + else + { + typeAttributes |= TypeAttributes.NestedAssembly; + } + attributeTypeBuilder = outer.DefineNestedType(o.AllocNestedTypeName(o.enclosingClassWrapper.Name, name + "Attribute"), typeAttributes, annotationAttributeBaseType.TypeAsBaseType); + } + else + { + if (o.wrapper.IsPublic) + { + typeAttributes |= TypeAttributes.Public; + } + else + { + typeAttributes |= TypeAttributes.NotPublic; + } + attributeTypeBuilder = o.wrapper.classLoader.GetTypeWrapperFactory().ModuleBuilder.DefineType(name + "Attribute", typeAttributes, annotationAttributeBaseType.TypeAsBaseType); + } + if (o.wrapper.IsPublic) + { + // In the Java world, the class appears as a non-public proxy class + context.AttributeHelper.SetModifiers(attributeTypeBuilder, Modifiers.Final, false); + } + + // NOTE we "abuse" the InnerClassAttribute to add a custom attribute to name the class "$Proxy[Annotation]" in the Java world + int dotindex = o.classFile.Name.LastIndexOf('.') + 1; + context.AttributeHelper.SetInnerClass(attributeTypeBuilder, o.classFile.Name.Substring(0, dotindex) + "$Proxy" + o.classFile.Name.Substring(dotindex), Modifiers.Final); + attributeTypeBuilder.AddInterfaceImplementation(o.typeBuilder); + context.AttributeHelper.SetImplementsAttribute(attributeTypeBuilder, new RuntimeJavaType[] { o.wrapper }); + + if (o.classFile.Annotations != null) + { + CustomAttributeBuilder attributeUsageAttribute = null; + bool hasAttributeUsageAttribute = false; + foreach (object[] def in o.classFile.Annotations) + { + if (def[1].Equals("Ljava/lang/annotation/Target;") && !hasAttributeUsageAttribute) + { + for (int i = 2; i < def.Length; i += 2) + { + if (def[i].Equals("value")) + { + object[] val = def[i + 1] as object[]; + if (val != null + && val.Length > 0 + && val[0].Equals(AnnotationDefaultAttribute.TAG_ARRAY)) + { + AttributeTargets targets = 0; + for (int j = 1; j < val.Length; j++) + { + object[] eval = val[j] as object[]; + if (eval != null + && eval.Length == 3 + && eval[0].Equals(AnnotationDefaultAttribute.TAG_ENUM) + && eval[1].Equals("Ljava/lang/annotation/ElementType;")) + { + switch ((string)eval[2]) + { + case "ANNOTATION_TYPE": + targets |= AttributeTargets.Interface; + break; + case "CONSTRUCTOR": + targets |= AttributeTargets.Constructor; + break; + case "FIELD": + targets |= AttributeTargets.Field; + break; + case "LOCAL_VARIABLE": + break; + case "METHOD": + targets |= AttributeTargets.Method; + break; + case "PACKAGE": + targets |= AttributeTargets.Interface; + break; + case "PARAMETER": + targets |= AttributeTargets.Parameter; + break; + case "TYPE": + targets |= AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Struct | AttributeTargets.Delegate | AttributeTargets.Enum; + break; + } + } + } + + attributeUsageAttribute = new CustomAttributeBuilder(context.Resolver.ResolveCoreType(typeof(AttributeUsageAttribute).FullName).GetConstructor([context.Resolver.ResolveCoreType(typeof(AttributeTargets).FullName)]).AsReflection(), [targets]); + } + } + } + } + else + { + // apply any .NET custom attributes that are on the annotation to the custom attribute we synthesize + // (for example, to allow AttributeUsageAttribute to be overridden) + Annotation annotation = Annotation.Load(o.wrapper, def); + if (annotation != null && annotation.IsCustomAttribute) + { + annotation.Apply(o.wrapper.ClassLoader, attributeTypeBuilder, def); + } + if (def[1].Equals("Lcli/System/AttributeUsageAttribute$Annotation;")) + { + hasAttributeUsageAttribute = true; + } + } + } + if (attributeUsageAttribute != null && !hasAttributeUsageAttribute) + { + attributeTypeBuilder.SetCustomAttribute(attributeUsageAttribute); + } + } + + defineConstructor = ReflectUtil.DefineConstructor(attributeTypeBuilder, MethodAttributes.Public, new Type[] { context.Resolver.ResolveCoreType(typeof(object).FullName).MakeArrayType().AsReflection() }); + context.AttributeHelper.SetEditorBrowsableNever(defineConstructor); } - // NOTE there is a bug in the CLR (.NET 1.0 & 1.1 [1.2 is not yet available]) that - // causes the AppDomain.TypeResolve event to receive the incorrect type name for nested types. - // The Name in the ResolveEventArgs contains only the nested type name, not the full type name, - // for example, if the type being resolved is "MyOuterType+MyInnerType", then the event only - // receives "MyInnerType" as the name. Since we only compile inner classes as nested types - // when we're statically compiling, we can only run into this bug when we're statically compiling. - // NOTE To work around this bug, we have to make sure that all types that are going to be - // required in finished form, are finished explicitly here. It isn't clear what other types are - // required to be finished. I instrumented a static compilation of classpath.dll and this - // turned up no other cases of the TypeResolve event firing. - foreach (RuntimeJavaType iface in wrapper.interfaces) + private static Type TypeWrapperToAnnotationParameterType(RuntimeJavaType tw) { - iface.Finish(); - iface.LinkAll(); + bool isArray = false; + if (tw.IsArray) + { + isArray = true; + tw = tw.ElementTypeWrapper; + } + if (tw.Annotation != null) + { + // we don't support Annotation args + return null; + } + else + { + Type argType; + if (tw == tw.Context.JavaBase.TypeOfJavaLangClass) + { + argType = tw.Context.Types.Type; + } + else if (tw.EnumType != null) // is it a Java enum? + { + argType = tw.EnumType; + } + else if (IsDotNetEnum(tw)) + { + argType = tw.DeclaringTypeWrapper.TypeAsSignatureType; + } + else + { + argType = tw.TypeAsSignatureType; + } + if (isArray) + { + argType = RuntimeArrayJavaType.MakeArrayType(argType, 1); + } + return argType; + } } - // make sure all classes are loaded, before we start finishing the type. During finishing, we - // may not run any Java code, because that might result in a request to finish the type that we - // are in the process of finishing, and this would be a problem. - // Prevent infinity recursion for broken class loaders by keeping a recursion count and falling - // back to late binding if we recurse more than twice. - var mode = System.Threading.Interlocked.Increment(ref recursionCount) > 2 || (JVM.DisableEagerClassLoading && wrapper.Name != "sun.reflect.misc.Trampoline") - ? LoadMode.ReturnUnloadable - : LoadMode.Link; - try + private static bool IsDotNetEnum(RuntimeJavaType tw) { - classFile.Link(wrapper, mode); - - for (int i = 0; i < fields.Length; i++) - fields[i].Link(mode); - - for (int i = 0; i < methods.Length; i++) - methods[i].Link(mode); + return tw.IsFakeNestedType && (tw.Modifiers & Modifiers.Enum) != 0; } - finally + + internal string AttributeTypeName { - System.Threading.Interlocked.Decrement(ref recursionCount); + get + { + Link(); + if (attributeTypeBuilder != null) + { + return attributeTypeBuilder.FullName; + } + return null; + } } - // this is the correct lock, FinishCore doesn't call any user code and mutates global state, - // so it needs to be protected by a lock. - lock (this) + private static void EmitSetValueCall(RuntimeJavaType annotationAttributeBaseType, CodeEmitter ilgen, string name, RuntimeJavaType tw, int argIndex) { - FinishedTypeImpl impl; - try + ilgen.Emit(OpCodes.Ldarg_0); + ilgen.Emit(OpCodes.Ldstr, name); + ilgen.EmitLdarg(argIndex); + if (tw.TypeAsSignatureType.IsValueType) { - // call FinishCore in the finally to avoid Thread.Abort interrupting the thread + ilgen.Emit(OpCodes.Box, tw.TypeAsSignatureType); } - finally + else if (tw.EnumType != null) // is it a Java enum? { - impl = FinishCore(); + ilgen.Emit(OpCodes.Box, tw.EnumType); } - return impl; + else if (IsDotNetEnum(tw)) + { + ilgen.Emit(OpCodes.Box, tw.DeclaringTypeWrapper.TypeAsSignatureType); + } + var setValueMethod = annotationAttributeBaseType.GetMethodWrapper("setValue", "(Ljava.lang.String;Ljava.lang.Object;)V", false); + setValueMethod.Link(); + setValueMethod.EmitCall(ilgen); } - } - FinishedTypeImpl FinishCore() - { - // it is possible that the loading of the referenced classes triggered a finish of us, - // if that happens, we just return - if (finishedType != null) - return finishedType; + internal void Finish(JavaTypeImpl o) + { + Link(); - if (finishInProgress) - throw new InvalidOperationException("Recursive finish attempt for " + wrapper.Name); + // not a valid annotation type + if (annotationTypeBuilder == null) + return; - finishInProgress = true; - wrapper.ClassLoader.Diagnostics.GenericCompilerTrace($"Finishing: {wrapper.Name}"); - Profiler.Enter("JavaTypeImpl.Finish.Core"); + var annotationAttributeBaseType = context.ClassLoaderFactory.LoadClassCritical("ikvm.internal.AnnotationAttributeBase"); + annotationAttributeBaseType.Finish(); - try - { - RuntimeJavaType declaringTypeWrapper = null; - var innerClassesTypeWrappers = Array.Empty(); + var requiredArgCount = 0; + var valueArg = -1; + var unsupported = false; + for (int i = 0; i < o.methods.Length; i++) + { + if (!o.methods[i].IsStatic) + { + if (valueArg == -1 && o.methods[i].Name == "value") + valueArg = i; - // if we're an inner class, we need to attach an InnerClass attribute - ClassFile.InnerClass[] innerclasses = classFile.InnerClasses; - if (innerclasses != null) + if (o.classFile.Methods[i].AnnotationDefault == null) + { + if (TypeWrapperToAnnotationParameterType(o.methods[i].ReturnType) == null) + { + unsupported = true; + break; + } + + requiredArgCount++; + } + } + } + + var defaultConstructor = ReflectUtil.DefineConstructor(attributeTypeBuilder, unsupported || requiredArgCount > 0 ? MethodAttributes.Private : MethodAttributes.Public, []); + CodeEmitter ilgen; + + if (!unsupported) { - // TODO consider not pre-computing innerClassesTypeWrappers and declaringTypeWrapper here - var wrappers = new List(); - for (int i = 0; i < innerclasses.Length; i++) + if (requiredArgCount > 0) { - if (innerclasses[i].innerClass.IsNotNil && innerclasses[i].outerClass.IsNotNil) + var args = new Type[requiredArgCount]; + for (int i = 0, j = 0; i < o.methods.Length; i++) { - if (classFile.GetConstantPoolClassType(innerclasses[i].outerClass) == wrapper) + if (!o.methods[i].IsStatic) { - wrappers.Add(classFile.GetConstantPoolClassType(innerclasses[i].innerClass)); + if (o.classFile.Methods[i].AnnotationDefault == null) + { + args[j++] = TypeWrapperToAnnotationParameterType(o.methods[i].ReturnType); + } } - if (classFile.GetConstantPoolClassType(innerclasses[i].innerClass) == wrapper) + } + + var reqArgConstructor = ReflectUtil.DefineConstructor(attributeTypeBuilder, MethodAttributes.Public, args); + context.AttributeHelper.HideFromJava(reqArgConstructor); + ilgen = context.CodeEmitterFactory.Create(reqArgConstructor); + ilgen.Emit(OpCodes.Ldarg_0); + ilgen.Emit(OpCodes.Call, defaultConstructor); + + for (int i = 0, j = 0; i < o.methods.Length; i++) + { + if (!o.methods[i].IsStatic) { - declaringTypeWrapper = classFile.GetConstantPoolClassType(innerclasses[i].outerClass); + if (o.classFile.Methods[i].AnnotationDefault == null) + { + reqArgConstructor.DefineParameter(++j, ParameterAttributes.None, o.methods[i].Name); + EmitSetValueCall(annotationAttributeBaseType, ilgen, o.methods[i].Name, o.methods[i].ReturnType, j); + } } } + + ilgen.Emit(OpCodes.Ret); + ilgen.DoEmit(); + } + else if (valueArg != -1) + { + // We don't have any required parameters, but we do have an optional "value" parameter, + // so we create an additional constructor (the default constructor will be public in this case) + // that accepts the value parameter. + Type argType = TypeWrapperToAnnotationParameterType(o.methods[valueArg].ReturnType); + if (argType != null) + { + MethodBuilder cb = ReflectUtil.DefineConstructor(attributeTypeBuilder, MethodAttributes.Public, new Type[] { argType }); + context.AttributeHelper.HideFromJava(cb); + cb.DefineParameter(1, ParameterAttributes.None, "value"); + ilgen = context.CodeEmitterFactory.Create(cb); + ilgen.Emit(OpCodes.Ldarg_0); + ilgen.Emit(OpCodes.Call, defaultConstructor); + EmitSetValueCall(annotationAttributeBaseType, ilgen, "value", o.methods[valueArg].ReturnType, 1); + ilgen.Emit(OpCodes.Ret); + ilgen.DoEmit(); + } } - innerClassesTypeWrappers = wrappers.ToArray(); -#if IMPORTER - // before we bake our type, we need to link any inner annotations to allow them to create their attribute type (as a nested type) - foreach (var tw in innerClassesTypeWrappers) - { - var dtw = tw as RuntimeByteCodeJavaType; - if (dtw != null) - { - var impl = dtw.impl as JavaTypeImpl; - if (impl != null) - if (impl.annotationBuilder != null) - impl.annotationBuilder.Link(); - } - } -#endif } -#if IMPORTER - - if (annotationBuilder != null) - { - var cab = new CustomAttributeBuilder(wrapper.Context.Resolver.ResolveRuntimeType(typeof(AnnotationAttributeAttribute).FullName).AsReflection().GetConstructor(new Type[] { wrapper.Context.Types.String }), new object[] { UnicodeUtil.EscapeInvalidSurrogates(annotationBuilder.AttributeTypeName) }); - typeBuilder.SetCustomAttribute(cab); - } - - if (!wrapper.IsInterface && wrapper.IsMapUnsafeException) - { - // mark all exceptions that are unsafe for mapping with a custom attribute, - // so that at runtime we can quickly assertain if an exception type can be - // caught without filtering - wrapper.Context.AttributeHelper.SetExceptionIsUnsafeForMapping(typeBuilder); - } -#endif - - var context = new FinishContext(wrapper.Context, host, classFile, wrapper, typeBuilder); - var type = context.FinishImpl(); -#if IMPORTER - if (annotationBuilder != null) - { - annotationBuilder.Finish(this); - } - if (enumBuilder != null) - { - enumBuilder.CreateType(); - } - if (privateInterfaceMethods != null) - { - privateInterfaceMethods.CreateType(); - } -#endif - var finishedClinitMethod = (MethodInfo)clinitMethod; -#if !IMPORTER - if (finishedClinitMethod != null) + ilgen = context.CodeEmitterFactory.Create(defaultConstructor); + ilgen.Emit(OpCodes.Ldarg_0); + o.wrapper.EmitClassLiteral(ilgen); + annotationAttributeBaseType.GetMethodWrapper("", "(Ljava.lang.Class;)V", false).EmitCall(ilgen); + ilgen.Emit(OpCodes.Ret); + ilgen.DoEmit(); + + ilgen = context.CodeEmitterFactory.Create(defineConstructor); + ilgen.Emit(OpCodes.Ldarg_0); + ilgen.Emit(OpCodes.Call, defaultConstructor); + ilgen.Emit(OpCodes.Ldarg_0); + ilgen.Emit(OpCodes.Ldarg_1); + annotationAttributeBaseType.GetMethodWrapper("setDefinition", "([Ljava.lang.Object;)V", false).EmitCall(ilgen); + ilgen.Emit(OpCodes.Ret); + ilgen.DoEmit(); + + var getValueMethod = annotationAttributeBaseType.GetMethodWrapper("getValue", "(Ljava.lang.String;)Ljava.lang.Object;", false); + var getByteValueMethod = annotationAttributeBaseType.GetMethodWrapper("getByteValue", "(Ljava.lang.String;)B", false); + var getBooleanValueMethod = annotationAttributeBaseType.GetMethodWrapper("getBooleanValue", "(Ljava.lang.String;)Z", false); + var getCharValueMethod = annotationAttributeBaseType.GetMethodWrapper("getCharValue", "(Ljava.lang.String;)C", false); + var getShortValueMethod = annotationAttributeBaseType.GetMethodWrapper("getShortValue", "(Ljava.lang.String;)S", false); + var getIntValueMethod = annotationAttributeBaseType.GetMethodWrapper("getIntValue", "(Ljava.lang.String;)I", false); + var getFloatValueMethod = annotationAttributeBaseType.GetMethodWrapper("getFloatValue", "(Ljava.lang.String;)F", false); + var getLongValueMethod = annotationAttributeBaseType.GetMethodWrapper("getLongValue", "(Ljava.lang.String;)J", false); + var getDoubleValueMethod = annotationAttributeBaseType.GetMethodWrapper("getDoubleValue", "(Ljava.lang.String;)D", false); + for (int i = 0; i < o.methods.Length; i++) { - // In dynamic mode, we may need to emit a call to this method from a DynamicMethod which doesn't support calling unfinished methods, - // so we must resolve to the real method here. - finishedClinitMethod = type.GetMethod("__", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); + // skip and non-virtual interface methods introduced in Java 8 + if (o.methods[i].IsVirtual) + { + MethodBuilder mb = o.methods[i].GetDefineMethodHelper().DefineMethod(o.wrapper, attributeTypeBuilder, o.methods[i].Name, MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.NewSlot); + attributeTypeBuilder.DefineMethodOverride(mb, (MethodInfo)o.methods[i].GetMethod()); + ilgen = context.CodeEmitterFactory.Create(mb); + ilgen.Emit(OpCodes.Ldarg_0); + ilgen.Emit(OpCodes.Ldstr, o.methods[i].Name); + if (o.methods[i].ReturnType.IsPrimitive) + { + if (o.methods[i].ReturnType == context.PrimitiveJavaTypeFactory.BYTE) + { + getByteValueMethod.EmitCall(ilgen); + } + else if (o.methods[i].ReturnType == context.PrimitiveJavaTypeFactory.BOOLEAN) + { + getBooleanValueMethod.EmitCall(ilgen); + } + else if (o.methods[i].ReturnType == context.PrimitiveJavaTypeFactory.CHAR) + { + getCharValueMethod.EmitCall(ilgen); + } + else if (o.methods[i].ReturnType == context.PrimitiveJavaTypeFactory.SHORT) + { + getShortValueMethod.EmitCall(ilgen); + } + else if (o.methods[i].ReturnType == context.PrimitiveJavaTypeFactory.INT) + { + getIntValueMethod.EmitCall(ilgen); + } + else if (o.methods[i].ReturnType == context.PrimitiveJavaTypeFactory.FLOAT) + { + getFloatValueMethod.EmitCall(ilgen); + } + else if (o.methods[i].ReturnType == context.PrimitiveJavaTypeFactory.LONG) + { + getLongValueMethod.EmitCall(ilgen); + } + else if (o.methods[i].ReturnType == context.PrimitiveJavaTypeFactory.DOUBLE) + { + getDoubleValueMethod.EmitCall(ilgen); + } + else + { + throw new InvalidOperationException(); + } + } + else + { + getValueMethod.EmitCall(ilgen); + o.methods[i].ReturnType.EmitCheckcast(ilgen); + } + ilgen.Emit(OpCodes.Ret); + ilgen.DoEmit(); + + if (o.classFile.Methods[i].AnnotationDefault != null + && !(o.methods[i].Name == "value" && requiredArgCount == 0)) + { + // now add a .NET property for this annotation optional parameter + Type argType = TypeWrapperToAnnotationParameterType(o.methods[i].ReturnType); + if (argType != null) + { + PropertyBuilder pb = attributeTypeBuilder.DefineProperty(o.methods[i].Name, PropertyAttributes.None, argType, []); + context.AttributeHelper.HideFromJava(pb); + MethodBuilder setter = attributeTypeBuilder.DefineMethod("set_" + o.methods[i].Name, MethodAttributes.Public, context.Types.Void, new Type[] { argType }); + context.AttributeHelper.HideFromJava(setter); + pb.SetSetMethod(setter); + ilgen = context.CodeEmitterFactory.Create(setter); + EmitSetValueCall(annotationAttributeBaseType, ilgen, o.methods[i].Name, o.methods[i].ReturnType, 1); + ilgen.Emit(OpCodes.Ret); + ilgen.DoEmit(); + MethodBuilder getter = attributeTypeBuilder.DefineMethod("get_" + o.methods[i].Name, MethodAttributes.Public, argType, []); + context.AttributeHelper.HideFromJava(getter); + pb.SetGetMethod(getter); + // TODO implement the getter method + ilgen = context.CodeEmitterFactory.Create(getter); + ilgen.ThrowException(context.Resolver.ResolveCoreType(typeof(NotImplementedException).FullName).AsReflection()); + ilgen.DoEmit(); + } + } + } } -#endif + attributeTypeBuilder.CreateType(); + } - finishedType = new FinishedTypeImpl(type, innerClassesTypeWrappers, declaringTypeWrapper, wrapper.ReflectiveModifiers, Metadata.Create(classFile), finishedClinitMethod, finalizeMethod, host); - return finishedType; + private CustomAttributeBuilder MakeCustomAttributeBuilder(RuntimeClassLoader loader, object annotation) + { + Link(); + ConstructorInfo ctor = defineConstructor != null + ? defineConstructor.__AsConstructorInfo() + : context.Resolver.ResolveRuntimeType("IKVM.Attributes.DynamicAnnotationAttribute").AsReflection().GetConstructor(new Type[] { context.Types.Object.MakeArrayType() }); + return new CustomAttributeBuilder(ctor, new object[] { AnnotationDefaultAttribute.Escape(QualifyClassNames(loader, annotation)) }); } -#if !IMPORTER - catch (Exception x) + + internal override void Apply(RuntimeClassLoader loader, TypeBuilder tb, object annotation) { - throw new InternalException($"Exception during finishing of: {wrapper.Name}", x); + tb.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); } -#endif - finally + + internal override void Apply(RuntimeClassLoader loader, MethodBuilder mb, object annotation) { - Profiler.Leave("JavaTypeImpl.Finish.Core"); + mb.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); } - } -#if IMPORTER + internal override void Apply(RuntimeClassLoader loader, FieldBuilder fb, object annotation) + { + fb.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); + } + + internal override void Apply(RuntimeClassLoader loader, ParameterBuilder pb, object annotation) + { + pb.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); + } - private bool IsValidAnnotationElementType(string type) - { - if (type[0] == '[') - type = type.Substring(1); - - switch (type) - { - case "Z": - case "B": - case "S": - case "C": - case "I": - case "J": - case "F": - case "D": - case "Ljava.lang.String;": - case "Ljava.lang.Class;": - return true; - } - - if (type.StartsWith("L") && type.EndsWith(";")) - { - try - { - var tw = wrapper.ClassLoader.TryLoadClassByName(type.Substring(1, type.Length - 2)); - if (tw != null) - { - if ((tw.Modifiers & Modifiers.Annotation) != 0) - return true; - - if ((tw.Modifiers & Modifiers.Enum) != 0) - { - var enumType = wrapper.Context.ClassLoaderFactory.GetBootstrapClassLoader().TryLoadClassByName("java.lang.Enum"); - if (enumType != null && tw.IsSubTypeOf(enumType)) - return true; - } - } - } - catch - { - - } - } - - return false; - } - - sealed class AnnotationBuilder : Annotation - { - - readonly RuntimeContext context; - - JavaTypeImpl impl; - TypeBuilder outer; - TypeBuilder annotationTypeBuilder; - TypeBuilder attributeTypeBuilder; - MethodBuilder defineConstructor; - - /// - /// Initializes a new instance. - /// - /// - /// - /// - internal AnnotationBuilder(RuntimeContext context, JavaTypeImpl o, TypeBuilder outer) - { - this.context = context; - this.impl = o; - this.outer = outer; - } - - internal void Link() - { - if (impl == null) - { - return; - } - JavaTypeImpl o = impl; - impl = null; - - // Make sure the annotation type only has valid methods - for (int i = 0; i < o.methods.Length; i++) - { - if (!o.methods[i].IsStatic) - { - if (!o.methods[i].Signature.StartsWith("()")) - { - return; - } - if (!o.IsValidAnnotationElementType(o.methods[i].Signature.Substring(2))) - { - return; - } - } - } - - // we only set annotationTypeBuilder if we're valid - annotationTypeBuilder = o.typeBuilder; - - var annotationAttributeBaseType = context.ClassLoaderFactory.LoadClassCritical("ikvm.internal.AnnotationAttributeBase"); - - // make sure we don't clash with another class name - var ccl = o.wrapper.classLoader; - string name = UnicodeUtil.EscapeInvalidSurrogates(o.classFile.Name); - while (!ccl.ReserveName(name + "Attribute")) - { - name += "_"; - } - - var typeAttributes = TypeAttributes.Class | TypeAttributes.Sealed; - if (o.enclosingClassWrapper != null) - { - if (o.wrapper.IsPublic) - { - typeAttributes |= TypeAttributes.NestedPublic; - } - else - { - typeAttributes |= TypeAttributes.NestedAssembly; - } - attributeTypeBuilder = outer.DefineNestedType(o.AllocNestedTypeName(o.enclosingClassWrapper.Name, name + "Attribute"), typeAttributes, annotationAttributeBaseType.TypeAsBaseType); - } - else - { - if (o.wrapper.IsPublic) - { - typeAttributes |= TypeAttributes.Public; - } - else - { - typeAttributes |= TypeAttributes.NotPublic; - } - attributeTypeBuilder = o.wrapper.classLoader.GetTypeWrapperFactory().ModuleBuilder.DefineType(name + "Attribute", typeAttributes, annotationAttributeBaseType.TypeAsBaseType); - } - if (o.wrapper.IsPublic) - { - // In the Java world, the class appears as a non-public proxy class - context.AttributeHelper.SetModifiers(attributeTypeBuilder, Modifiers.Final, false); - } - - // NOTE we "abuse" the InnerClassAttribute to add a custom attribute to name the class "$Proxy[Annotation]" in the Java world - int dotindex = o.classFile.Name.LastIndexOf('.') + 1; - context.AttributeHelper.SetInnerClass(attributeTypeBuilder, o.classFile.Name.Substring(0, dotindex) + "$Proxy" + o.classFile.Name.Substring(dotindex), Modifiers.Final); - attributeTypeBuilder.AddInterfaceImplementation(o.typeBuilder); - context.AttributeHelper.SetImplementsAttribute(attributeTypeBuilder, new RuntimeJavaType[] { o.wrapper }); - - if (o.classFile.Annotations != null) - { - CustomAttributeBuilder attributeUsageAttribute = null; - bool hasAttributeUsageAttribute = false; - foreach (object[] def in o.classFile.Annotations) - { - if (def[1].Equals("Ljava/lang/annotation/Target;") && !hasAttributeUsageAttribute) - { - for (int i = 2; i < def.Length; i += 2) - { - if (def[i].Equals("value")) - { - object[] val = def[i + 1] as object[]; - if (val != null - && val.Length > 0 - && val[0].Equals(AnnotationDefaultAttribute.TAG_ARRAY)) - { - AttributeTargets targets = 0; - for (int j = 1; j < val.Length; j++) - { - object[] eval = val[j] as object[]; - if (eval != null - && eval.Length == 3 - && eval[0].Equals(AnnotationDefaultAttribute.TAG_ENUM) - && eval[1].Equals("Ljava/lang/annotation/ElementType;")) - { - switch ((string)eval[2]) - { - case "ANNOTATION_TYPE": - targets |= AttributeTargets.Interface; - break; - case "CONSTRUCTOR": - targets |= AttributeTargets.Constructor; - break; - case "FIELD": - targets |= AttributeTargets.Field; - break; - case "LOCAL_VARIABLE": - break; - case "METHOD": - targets |= AttributeTargets.Method; - break; - case "PACKAGE": - targets |= AttributeTargets.Interface; - break; - case "PARAMETER": - targets |= AttributeTargets.Parameter; - break; - case "TYPE": - targets |= AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Struct | AttributeTargets.Delegate | AttributeTargets.Enum; - break; - } - } - } - - attributeUsageAttribute = new CustomAttributeBuilder(context.Resolver.ResolveCoreType(typeof(AttributeUsageAttribute).FullName).GetConstructor([context.Resolver.ResolveCoreType(typeof(AttributeTargets).FullName)]).AsReflection(), [targets]); - } - } - } - } - else - { - // apply any .NET custom attributes that are on the annotation to the custom attribute we synthesize - // (for example, to allow AttributeUsageAttribute to be overridden) - Annotation annotation = Annotation.Load(o.wrapper, def); - if (annotation != null && annotation.IsCustomAttribute) - { - annotation.Apply(o.wrapper.ClassLoader, attributeTypeBuilder, def); - } - if (def[1].Equals("Lcli/System/AttributeUsageAttribute$Annotation;")) - { - hasAttributeUsageAttribute = true; - } - } - } - if (attributeUsageAttribute != null && !hasAttributeUsageAttribute) - { - attributeTypeBuilder.SetCustomAttribute(attributeUsageAttribute); - } - } - - defineConstructor = ReflectUtil.DefineConstructor(attributeTypeBuilder, MethodAttributes.Public, new Type[] { context.Resolver.ResolveCoreType(typeof(object).FullName).MakeArrayType().AsReflection() }); - context.AttributeHelper.SetEditorBrowsableNever(defineConstructor); - } - - private static Type TypeWrapperToAnnotationParameterType(RuntimeJavaType tw) - { - bool isArray = false; - if (tw.IsArray) - { - isArray = true; - tw = tw.ElementTypeWrapper; - } - if (tw.Annotation != null) - { - // we don't support Annotation args - return null; - } - else - { - Type argType; - if (tw == tw.Context.JavaBase.TypeOfJavaLangClass) - { - argType = tw.Context.Types.Type; - } - else if (tw.EnumType != null) // is it a Java enum? - { - argType = tw.EnumType; - } - else if (IsDotNetEnum(tw)) - { - argType = tw.DeclaringTypeWrapper.TypeAsSignatureType; - } - else - { - argType = tw.TypeAsSignatureType; - } - if (isArray) - { - argType = RuntimeArrayJavaType.MakeArrayType(argType, 1); - } - return argType; - } - } - - private static bool IsDotNetEnum(RuntimeJavaType tw) - { - return tw.IsFakeNestedType && (tw.Modifiers & Modifiers.Enum) != 0; - } - - internal string AttributeTypeName - { - get - { - Link(); - if (attributeTypeBuilder != null) - { - return attributeTypeBuilder.FullName; - } - return null; - } - } - - private static void EmitSetValueCall(RuntimeJavaType annotationAttributeBaseType, CodeEmitter ilgen, string name, RuntimeJavaType tw, int argIndex) - { - ilgen.Emit(OpCodes.Ldarg_0); - ilgen.Emit(OpCodes.Ldstr, name); - ilgen.EmitLdarg(argIndex); - if (tw.TypeAsSignatureType.IsValueType) - { - ilgen.Emit(OpCodes.Box, tw.TypeAsSignatureType); - } - else if (tw.EnumType != null) // is it a Java enum? - { - ilgen.Emit(OpCodes.Box, tw.EnumType); - } - else if (IsDotNetEnum(tw)) - { - ilgen.Emit(OpCodes.Box, tw.DeclaringTypeWrapper.TypeAsSignatureType); - } - var setValueMethod = annotationAttributeBaseType.GetMethodWrapper("setValue", "(Ljava.lang.String;Ljava.lang.Object;)V", false); - setValueMethod.Link(); - setValueMethod.EmitCall(ilgen); - } - - internal void Finish(JavaTypeImpl o) - { - Link(); - if (annotationTypeBuilder == null) - { - // not a valid annotation type - return; - } - RuntimeJavaType annotationAttributeBaseType = context.ClassLoaderFactory.LoadClassCritical("ikvm.internal.AnnotationAttributeBase"); - annotationAttributeBaseType.Finish(); - - int requiredArgCount = 0; - int valueArg = -1; - bool unsupported = false; - for (int i = 0; i < o.methods.Length; i++) - { - if (!o.methods[i].IsStatic) - { - if (valueArg == -1 && o.methods[i].Name == "value") - { - valueArg = i; - } - if (o.classFile.Methods[i].AnnotationDefault == null) - { - if (TypeWrapperToAnnotationParameterType(o.methods[i].ReturnType) == null) - { - unsupported = true; - break; - } - requiredArgCount++; - } - } - } - - MethodBuilder defaultConstructor = ReflectUtil.DefineConstructor(attributeTypeBuilder, unsupported || requiredArgCount > 0 ? MethodAttributes.Private : MethodAttributes.Public, Type.EmptyTypes); - CodeEmitter ilgen; - - if (!unsupported) - { - if (requiredArgCount > 0) - { - Type[] args = new Type[requiredArgCount]; - for (int i = 0, j = 0; i < o.methods.Length; i++) - { - if (!o.methods[i].IsStatic) - { - if (o.classFile.Methods[i].AnnotationDefault == null) - { - args[j++] = TypeWrapperToAnnotationParameterType(o.methods[i].ReturnType); - } - } - } - MethodBuilder reqArgConstructor = ReflectUtil.DefineConstructor(attributeTypeBuilder, MethodAttributes.Public, args); - context.AttributeHelper.HideFromJava(reqArgConstructor); - ilgen = context.CodeEmitterFactory.Create(reqArgConstructor); - ilgen.Emit(OpCodes.Ldarg_0); - ilgen.Emit(OpCodes.Call, defaultConstructor); - for (int i = 0, j = 0; i < o.methods.Length; i++) - { - if (!o.methods[i].IsStatic) - { - if (o.classFile.Methods[i].AnnotationDefault == null) - { - reqArgConstructor.DefineParameter(++j, ParameterAttributes.None, o.methods[i].Name); - EmitSetValueCall(annotationAttributeBaseType, ilgen, o.methods[i].Name, o.methods[i].ReturnType, j); - } - } - } - ilgen.Emit(OpCodes.Ret); - ilgen.DoEmit(); - } - else if (valueArg != -1) - { - // We don't have any required parameters, but we do have an optional "value" parameter, - // so we create an additional constructor (the default constructor will be public in this case) - // that accepts the value parameter. - Type argType = TypeWrapperToAnnotationParameterType(o.methods[valueArg].ReturnType); - if (argType != null) - { - MethodBuilder cb = ReflectUtil.DefineConstructor(attributeTypeBuilder, MethodAttributes.Public, new Type[] { argType }); - context.AttributeHelper.HideFromJava(cb); - cb.DefineParameter(1, ParameterAttributes.None, "value"); - ilgen = context.CodeEmitterFactory.Create(cb); - ilgen.Emit(OpCodes.Ldarg_0); - ilgen.Emit(OpCodes.Call, defaultConstructor); - EmitSetValueCall(annotationAttributeBaseType, ilgen, "value", o.methods[valueArg].ReturnType, 1); - ilgen.Emit(OpCodes.Ret); - ilgen.DoEmit(); - } - } - } - - ilgen = context.CodeEmitterFactory.Create(defaultConstructor); - ilgen.Emit(OpCodes.Ldarg_0); - o.wrapper.EmitClassLiteral(ilgen); - annotationAttributeBaseType.GetMethodWrapper("", "(Ljava.lang.Class;)V", false).EmitCall(ilgen); - ilgen.Emit(OpCodes.Ret); - ilgen.DoEmit(); - - ilgen = context.CodeEmitterFactory.Create(defineConstructor); - ilgen.Emit(OpCodes.Ldarg_0); - ilgen.Emit(OpCodes.Call, defaultConstructor); - ilgen.Emit(OpCodes.Ldarg_0); - ilgen.Emit(OpCodes.Ldarg_1); - annotationAttributeBaseType.GetMethodWrapper("setDefinition", "([Ljava.lang.Object;)V", false).EmitCall(ilgen); - ilgen.Emit(OpCodes.Ret); - ilgen.DoEmit(); - - var getValueMethod = annotationAttributeBaseType.GetMethodWrapper("getValue", "(Ljava.lang.String;)Ljava.lang.Object;", false); - var getByteValueMethod = annotationAttributeBaseType.GetMethodWrapper("getByteValue", "(Ljava.lang.String;)B", false); - var getBooleanValueMethod = annotationAttributeBaseType.GetMethodWrapper("getBooleanValue", "(Ljava.lang.String;)Z", false); - var getCharValueMethod = annotationAttributeBaseType.GetMethodWrapper("getCharValue", "(Ljava.lang.String;)C", false); - var getShortValueMethod = annotationAttributeBaseType.GetMethodWrapper("getShortValue", "(Ljava.lang.String;)S", false); - var getIntValueMethod = annotationAttributeBaseType.GetMethodWrapper("getIntValue", "(Ljava.lang.String;)I", false); - var getFloatValueMethod = annotationAttributeBaseType.GetMethodWrapper("getFloatValue", "(Ljava.lang.String;)F", false); - var getLongValueMethod = annotationAttributeBaseType.GetMethodWrapper("getLongValue", "(Ljava.lang.String;)J", false); - var getDoubleValueMethod = annotationAttributeBaseType.GetMethodWrapper("getDoubleValue", "(Ljava.lang.String;)D", false); - for (int i = 0; i < o.methods.Length; i++) - { - // skip and non-virtual interface methods introduced in Java 8 - if (o.methods[i].IsVirtual) - { - MethodBuilder mb = o.methods[i].GetDefineMethodHelper().DefineMethod(o.wrapper, attributeTypeBuilder, o.methods[i].Name, MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.NewSlot); - attributeTypeBuilder.DefineMethodOverride(mb, (MethodInfo)o.methods[i].GetMethod()); - ilgen = context.CodeEmitterFactory.Create(mb); - ilgen.Emit(OpCodes.Ldarg_0); - ilgen.Emit(OpCodes.Ldstr, o.methods[i].Name); - if (o.methods[i].ReturnType.IsPrimitive) - { - if (o.methods[i].ReturnType == context.PrimitiveJavaTypeFactory.BYTE) - { - getByteValueMethod.EmitCall(ilgen); - } - else if (o.methods[i].ReturnType == context.PrimitiveJavaTypeFactory.BOOLEAN) - { - getBooleanValueMethod.EmitCall(ilgen); - } - else if (o.methods[i].ReturnType == context.PrimitiveJavaTypeFactory.CHAR) - { - getCharValueMethod.EmitCall(ilgen); - } - else if (o.methods[i].ReturnType == context.PrimitiveJavaTypeFactory.SHORT) - { - getShortValueMethod.EmitCall(ilgen); - } - else if (o.methods[i].ReturnType == context.PrimitiveJavaTypeFactory.INT) - { - getIntValueMethod.EmitCall(ilgen); - } - else if (o.methods[i].ReturnType == context.PrimitiveJavaTypeFactory.FLOAT) - { - getFloatValueMethod.EmitCall(ilgen); - } - else if (o.methods[i].ReturnType == context.PrimitiveJavaTypeFactory.LONG) - { - getLongValueMethod.EmitCall(ilgen); - } - else if (o.methods[i].ReturnType == context.PrimitiveJavaTypeFactory.DOUBLE) - { - getDoubleValueMethod.EmitCall(ilgen); - } - else - { - throw new InvalidOperationException(); - } - } - else - { - getValueMethod.EmitCall(ilgen); - o.methods[i].ReturnType.EmitCheckcast(ilgen); - } - ilgen.Emit(OpCodes.Ret); - ilgen.DoEmit(); - - if (o.classFile.Methods[i].AnnotationDefault != null - && !(o.methods[i].Name == "value" && requiredArgCount == 0)) - { - // now add a .NET property for this annotation optional parameter - Type argType = TypeWrapperToAnnotationParameterType(o.methods[i].ReturnType); - if (argType != null) - { - PropertyBuilder pb = attributeTypeBuilder.DefineProperty(o.methods[i].Name, PropertyAttributes.None, argType, Type.EmptyTypes); - context.AttributeHelper.HideFromJava(pb); - MethodBuilder setter = attributeTypeBuilder.DefineMethod("set_" + o.methods[i].Name, MethodAttributes.Public, context.Types.Void, new Type[] { argType }); - context.AttributeHelper.HideFromJava(setter); - pb.SetSetMethod(setter); - ilgen = context.CodeEmitterFactory.Create(setter); - EmitSetValueCall(annotationAttributeBaseType, ilgen, o.methods[i].Name, o.methods[i].ReturnType, 1); - ilgen.Emit(OpCodes.Ret); - ilgen.DoEmit(); - MethodBuilder getter = attributeTypeBuilder.DefineMethod("get_" + o.methods[i].Name, MethodAttributes.Public, argType, Type.EmptyTypes); - context.AttributeHelper.HideFromJava(getter); - pb.SetGetMethod(getter); - // TODO implement the getter method - ilgen = context.CodeEmitterFactory.Create(getter); - ilgen.ThrowException(context.Resolver.ResolveCoreType(typeof(NotImplementedException).FullName).AsReflection()); - ilgen.DoEmit(); - } - } - } - } - attributeTypeBuilder.CreateType(); - } - - private CustomAttributeBuilder MakeCustomAttributeBuilder(RuntimeClassLoader loader, object annotation) - { - Link(); - ConstructorInfo ctor = defineConstructor != null - ? defineConstructor.__AsConstructorInfo() - : context.Resolver.ResolveRuntimeType("IKVM.Attributes.DynamicAnnotationAttribute").AsReflection().GetConstructor(new Type[] { context.Types.Object.MakeArrayType() }); - return new CustomAttributeBuilder(ctor, new object[] { AnnotationDefaultAttribute.Escape(QualifyClassNames(loader, annotation)) }); - } - - internal override void Apply(RuntimeClassLoader loader, TypeBuilder tb, object annotation) - { - tb.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); - } - - internal override void Apply(RuntimeClassLoader loader, MethodBuilder mb, object annotation) - { - mb.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); - } - - internal override void Apply(RuntimeClassLoader loader, FieldBuilder fb, object annotation) - { - fb.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); - } - - internal override void Apply(RuntimeClassLoader loader, ParameterBuilder pb, object annotation) - { - pb.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); - } - - internal override void Apply(RuntimeClassLoader loader, AssemblyBuilder ab, object annotation) - { - ab.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); - } - - internal override void Apply(RuntimeClassLoader loader, PropertyBuilder pb, object annotation) - { - pb.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); - } - - internal override bool IsCustomAttribute - { - get { return false; } - } - } + internal override void Apply(RuntimeClassLoader loader, AssemblyBuilder ab, object annotation) + { + ab.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); + } + + internal override void Apply(RuntimeClassLoader loader, PropertyBuilder pb, object annotation) + { + pb.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); + } + + internal override bool IsCustomAttribute + { + get { return false; } + } + } #endif // IMPORTER internal override RuntimeJavaType[] InnerClasses @@ -2291,7 +2292,7 @@ static MethodInfo GetBaseFinalizeMethod(RuntimeJavaType wrapper) } var type = wrapper.TypeAsBaseType; - var baseFinalize = type.GetMethod("__", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, Type.EmptyTypes, null); + var baseFinalize = type.GetMethod("__", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, [], null); if (baseFinalize != null) return baseFinalize; @@ -2455,11 +2456,11 @@ internal override MethodBase LinkMethod(RuntimeJavaMethod mw) wrapper.EmitLevel4Warning(mmw.IsConflictError ? HardError.IncompatibleClassChangeError : HardError.AbstractMethodError, message); } #if IMPORTER - if (wrapper.IsInterface && !mmw.IsAbstract) - { - // even though we're not visible to reflection we need to record the fact that we have a default implementation - wrapper.Context.AttributeHelper.SetModifiers(mb, mmw.Modifiers, false); - } + if (wrapper.IsInterface && !mmw.IsAbstract) + { + // even though we're not visible to reflection we need to record the fact that we have a default implementation + wrapper.Context.AttributeHelper.SetModifiers(mb, mmw.Modifiers, false); + } #endif return mb; } @@ -2502,50 +2503,50 @@ internal override MethodBase LinkMethod(RuntimeJavaMethod mw) methods[index].SetDeclaredExceptions(exceptions); #if IMPORTER - wrapper.Context.AttributeHelper.SetThrowsAttribute(method, exceptions); - - if (setModifiers || m.IsInternal || (m.Modifiers & (Modifiers.Synthetic | Modifiers.Bridge)) != 0) - wrapper.Context.AttributeHelper.SetModifiers(method, m.Modifiers, m.IsInternal); - - // synthetic and bridge methods should not be visible to the user and set as compiler generated - if ((m.Modifiers & (Modifiers.Synthetic | Modifiers.Bridge)) != 0 && (m.IsPublic || m.IsProtected) && wrapper.IsPublic && !IsAccessBridge(classFile, m)) - { - wrapper.Context.AttributeHelper.SetCompilerGenerated(method); - wrapper.Context.AttributeHelper.SetEditorBrowsableNever(method); - } - - // ensure deprecated attribute appears on method if obsolete not specified - if (m.DeprecatedAttribute && !Annotation.HasObsoleteAttribute(m.Annotations)) - { - wrapper.Context.AttributeHelper.SetDeprecatedAttribute(method); - } - - // apply .NET attribute to record Java generic signature - if (m.GenericSignature != null) - { - wrapper.Context.AttributeHelper.SetSignatureAttribute(method, m.GenericSignature); - } - - if (wrapper.ClassLoader.NoParameterReflection) - { - // ignore MethodParameters (except to extract parameter names) - } - else if (m.MalformedMethodParameters) - { - wrapper.Context.AttributeHelper.SetMethodParametersAttribute(method, null); - } - else if (m.MethodParameters != null) - { - var modifiers = new Modifiers[m.MethodParameters.Length]; - for (int i = 0; i < modifiers.Length; i++) - modifiers[i] = (Modifiers)m.MethodParameters[i].accessFlags; - - wrapper.Context.AttributeHelper.SetMethodParametersAttribute(method, modifiers); - } - - // copy runtime visible annotations as attributes - if (m.RuntimeVisibleTypeAnnotations.Count > 0) - wrapper.Context.AttributeHelper.SetRuntimeVisibleTypeAnnotationsAttribute(method, in m.RuntimeVisibleTypeAnnotations); + wrapper.Context.AttributeHelper.SetThrowsAttribute(method, exceptions); + + if (setModifiers || m.IsInternal || (m.Modifiers & (Modifiers.Synthetic | Modifiers.Bridge)) != 0) + wrapper.Context.AttributeHelper.SetModifiers(method, m.Modifiers, m.IsInternal); + + // synthetic and bridge methods should not be visible to the user and set as compiler generated + if ((m.Modifiers & (Modifiers.Synthetic | Modifiers.Bridge)) != 0 && (m.IsPublic || m.IsProtected) && wrapper.IsPublic && !IsAccessBridge(classFile, m)) + { + wrapper.Context.AttributeHelper.SetCompilerGenerated(method); + wrapper.Context.AttributeHelper.SetEditorBrowsableNever(method); + } + + // ensure deprecated attribute appears on method if obsolete not specified + if (m.DeprecatedAttribute && !Annotation.HasObsoleteAttribute(m.Annotations)) + { + wrapper.Context.AttributeHelper.SetDeprecatedAttribute(method); + } + + // apply .NET attribute to record Java generic signature + if (m.GenericSignature != null) + { + wrapper.Context.AttributeHelper.SetSignatureAttribute(method, m.GenericSignature); + } + + if (wrapper.ClassLoader.NoParameterReflection) + { + // ignore MethodParameters (except to extract parameter names) + } + else if (m.MalformedMethodParameters) + { + wrapper.Context.AttributeHelper.SetMethodParametersAttribute(method, null); + } + else if (m.MethodParameters != null) + { + var modifiers = new Modifiers[m.MethodParameters.Length]; + for (int i = 0; i < modifiers.Length; i++) + modifiers[i] = (Modifiers)m.MethodParameters[i].accessFlags; + + wrapper.Context.AttributeHelper.SetMethodParametersAttribute(method, modifiers); + } + + // copy runtime visible annotations as attributes + if (m.RuntimeVisibleTypeAnnotations.Count > 0) + wrapper.Context.AttributeHelper.SetRuntimeVisibleTypeAnnotationsAttribute(method, in m.RuntimeVisibleTypeAnnotations); #else // IMPORTER @@ -2663,20 +2664,20 @@ MethodBuilder GenerateMethod(int index, ClassFile.Method m, ref bool setModifier attribs |= MethodAttributes.SpecialName; } #if IMPORTER - if ((m.Modifiers & Modifiers.Bridge) != 0 && (m.IsPublic || m.IsProtected) && wrapper.IsPublic) - { - string sigbase = m.Signature.Substring(0, m.Signature.LastIndexOf(')') + 1); - foreach (var mw in methods) - { - if (mw.Name == m.Name && mw.Signature.StartsWith(sigbase) && mw.Signature != m.Signature) - { - // To prevent bridge methods with covariant return types from confusing - // other .NET compilers (like C#), we rename the bridge method. - name = NamePrefix.Bridge + name; - break; - } - } - } + if ((m.Modifiers & Modifiers.Bridge) != 0 && (m.IsPublic || m.IsProtected) && wrapper.IsPublic) + { + string sigbase = m.Signature.Substring(0, m.Signature.LastIndexOf(')') + 1); + foreach (var mw in methods) + { + if (mw.Name == m.Name && mw.Signature.StartsWith(sigbase) && mw.Signature != m.Signature) + { + // To prevent bridge methods with covariant return types from confusing + // other .NET compilers (like C#), we rename the bridge method. + name = NamePrefix.Bridge + name; + break; + } + } + } #endif if ((attribs & MethodAttributes.Virtual) != 0 && !classFile.IsInterface) { @@ -2709,7 +2710,7 @@ MethodBuilder GenerateMethod(int index, ClassFile.Method m, ref bool setModifier } MethodBuilder mb = null; #if IMPORTER - mb = wrapper.DefineGhostMethod(typeBuilder, name, attribs, methods[index]); + mb = wrapper.DefineGhostMethod(typeBuilder, name, attribs, methods[index]); #endif if (mb == null) { @@ -2784,7 +2785,7 @@ MethodBuilder GenerateMethod(int index, ClassFile.Method m, ref bool setModifier tb, NamePrefix.PrivateInterfaceInstanceMethod + name, attribs | MethodAttributes.Static | MethodAttributes.SpecialName, typeBuilder, false); #if IMPORTER - wrapper.Context.AttributeHelper.SetNameSig(mb, m.Name, m.Signature); + wrapper.Context.AttributeHelper.SetNameSig(mb, m.Name, m.Signature); #endif } setModifiers = true; @@ -2825,7 +2826,7 @@ MethodBuilder GenerateMethod(int index, ClassFile.Method m, ref bool setModifier if (m.IsFinal) attr |= MethodAttributes.Final; - finalizeMethod = typeBuilder.DefineMethod(finalizeName, attr, CallingConventions.Standard, wrapper.Context.Types.Void, Type.EmptyTypes); + finalizeMethod = typeBuilder.DefineMethod(finalizeName, attr, CallingConventions.Standard, wrapper.Context.Types.Void, []); if (finalizeName != baseFinalize.Name) typeBuilder.DefineMethodOverride(finalizeMethod, baseFinalize); @@ -2858,11 +2859,11 @@ MethodBuilder GenerateMethod(int index, ClassFile.Method m, ref bool setModifier ilgen.DoEmit(); } #if IMPORTER - if (classFile.Methods[index].AnnotationDefault != null) - { - var cab = new CustomAttributeBuilder(wrapper.Context.Resolver.ResolveRuntimeType("IKVM.Attributes.AnnotationDefaultAttribute").AsReflection().GetConstructor([wrapper.Context.Types.Object]), [AnnotationDefaultAttribute.Escape(classFile.Methods[index].AnnotationDefault)]); - mb.SetCustomAttribute(cab); - } + if (classFile.Methods[index].AnnotationDefault != null) + { + var cab = new CustomAttributeBuilder(wrapper.Context.Resolver.ResolveRuntimeType("IKVM.Attributes.AnnotationDefaultAttribute").GetConstructor([wrapper.Context.Types.Object]), [AnnotationDefaultAttribute.Escape(classFile.Methods[index].AnnotationDefault)]); + mb.SetCustomAttribute(cab); + } #endif } @@ -2920,28 +2921,28 @@ private static MethodAttributes GetMethodAccess(RuntimeJavaMethod mw) } #if IMPORTER - // The classic example of an access bridge is StringBuilder.length(), the JDK 6 compiler - // generates this to work around a reflection problem (which otherwise wouldn't surface the - // length() method, because it is defined in the non-public base class AbstractStringBuilder.) - private static bool IsAccessBridge(ClassFile classFile, ClassFile.Method m) - { - // HACK this is a pretty gross hack - // We look at the method body to figure out if the bridge method calls another method with the exact - // same name/signature and if that is the case, we assume that it is an access bridge. - // This code is based on the javac algorithm in addBridgeIfNeeded(...) in com/sun/tools/javac/comp/TransTypes.java. - if ((m.Modifiers & (Modifiers.Abstract | Modifiers.Native | Modifiers.Public | Modifiers.Bridge)) == (Modifiers.Public | Modifiers.Bridge)) - { - foreach (ClassFile.Method.Instruction instr in m.Instructions) - { - if (instr.NormalizedOpCode == NormalizedByteCode.__invokespecial) - { - ClassFile.ConstantPoolItemMI cpi = classFile.SafeGetMethodref(instr.Arg1); - return cpi != null && cpi.Name == m.Name && cpi.Signature == m.Signature; - } - } - } - return false; - } + // The classic example of an access bridge is StringBuilder.length(), the JDK 6 compiler + // generates this to work around a reflection problem (which otherwise wouldn't surface the + // length() method, because it is defined in the non-public base class AbstractStringBuilder.) + private static bool IsAccessBridge(ClassFile classFile, ClassFile.Method m) + { + // HACK this is a pretty gross hack + // We look at the method body to figure out if the bridge method calls another method with the exact + // same name/signature and if that is the case, we assume that it is an access bridge. + // This code is based on the javac algorithm in addBridgeIfNeeded(...) in com/sun/tools/javac/comp/TransTypes.java. + if ((m.Modifiers & (Modifiers.Abstract | Modifiers.Native | Modifiers.Public | Modifiers.Bridge)) == (Modifiers.Public | Modifiers.Bridge)) + { + foreach (ClassFile.Method.Instruction instr in m.Instructions) + { + if (instr.NormalizedOpCode == NormalizedByteCode.__invokespecial) + { + ClassFile.ConstantPoolItemMI cpi = classFile.SafeGetMethodref(instr.Arg1); + return cpi != null && cpi.Name == m.Name && cpi.Signature == m.Signature; + } + } + } + return false; + } #endif // IMPORTER internal override Type Type diff --git a/src/IKVM.Runtime/RuntimeByteCodeJavaType.cs b/src/IKVM.Runtime/RuntimeByteCodeJavaType.cs index 35bf3c4ed..ad900b87f 100644 --- a/src/IKVM.Runtime/RuntimeByteCodeJavaType.cs +++ b/src/IKVM.Runtime/RuntimeByteCodeJavaType.cs @@ -960,7 +960,7 @@ private Type[] GetModOpt(RuntimeJavaType tw, bool mustBePublic) internal static Type[] GetModOpt(RuntimeJavaTypeFactory context, RuntimeJavaType tw, bool mustBePublic) { - Type[] modopt = Type.EmptyTypes; + Type[] modopt = []; if (tw.IsUnloadable) { if (((RuntimeUnloadableJavaType)tw).MissingType == null) diff --git a/src/IKVM.Runtime/RuntimeByteCodePropertyJavaField.cs b/src/IKVM.Runtime/RuntimeByteCodePropertyJavaField.cs index ec600f902..00a6b1c0a 100644 --- a/src/IKVM.Runtime/RuntimeByteCodePropertyJavaField.cs +++ b/src/IKVM.Runtime/RuntimeByteCodePropertyJavaField.cs @@ -110,7 +110,7 @@ internal void DoLink(TypeBuilder tb) { setter.Link(); } - pb = tb.DefineProperty(this.Name, PropertyAttributes.None, this.FieldTypeWrapper.TypeAsSignatureType, Type.EmptyTypes); + pb = tb.DefineProperty(this.Name, PropertyAttributes.None, this.FieldTypeWrapper.TypeAsSignatureType, []); if (getter != null) { pb.SetGetMethod((MethodBuilder)getter.GetMethod()); @@ -212,7 +212,7 @@ internal override object GetValue(object obj) { throw new java.lang.NoSuchMethodError(); } - return getter.Invoke(obj, new object[0]); + return getter.Invoke(obj, []); } internal override void SetValue(object obj, object value) diff --git a/src/IKVM.Runtime/RuntimeClassLoader.cs b/src/IKVM.Runtime/RuntimeClassLoader.cs index 8f7f29d52..03a426852 100644 --- a/src/IKVM.Runtime/RuntimeClassLoader.cs +++ b/src/IKVM.Runtime/RuntimeClassLoader.cs @@ -744,7 +744,7 @@ internal virtual java.lang.ClassLoader GetJavaClassLoader() internal Type[] ArgTypeListFromSig(string signature) { if (signature[1] == ')') - return Type.EmptyTypes; + return []; var javaTypes = ArgJavaTypeListFromSig(signature, LoadMode.LoadOrThrow); var types = new Type[javaTypes.Length]; diff --git a/src/IKVM.Runtime/RuntimeClassLoaderFactory.cs b/src/IKVM.Runtime/RuntimeClassLoaderFactory.cs index 1a0eb7c92..c84a9c54c 100644 --- a/src/IKVM.Runtime/RuntimeClassLoaderFactory.cs +++ b/src/IKVM.Runtime/RuntimeClassLoaderFactory.cs @@ -25,9 +25,10 @@ Jeroen Frijters using System.Collections.Generic; using System.Diagnostics; +using IKVM.CoreLib.Symbols; using IKVM.CoreLib.Diagnostics; -#if NETCOREAPP +#if NET using System.Runtime.Loader; #endif @@ -54,8 +55,8 @@ class RuntimeClassLoaderFactory readonly RuntimeContext context; readonly object wrapperLock = new object(); - internal readonly Dictionary globalTypeToTypeWrapper = new Dictionary(); - internal readonly Dictionary remappedTypes = new Dictionary(); + internal readonly Dictionary globalTypeToTypeWrapper = new Dictionary(); + internal readonly Dictionary remappedTypes = new Dictionary(); readonly List genericClassLoaders = new List(); #if IMPORTER || EXPORTER @@ -99,14 +100,14 @@ internal void SetBootstrapClassLoader(RuntimeClassLoader bootstrapClassLoader) internal void LoadRemappedTypes() { // if we're compiling the base assembly, we won't be able to resolve one - var baseAssembly = context.Resolver.ResolveBaseAssembly().AsReflection(); + var baseAssembly = context.Resolver.ResolveBaseAssembly(); if (baseAssembly != null && remappedTypes.Count == 0) { var remapped = context.AttributeHelper.GetRemappedClasses(baseAssembly); if (remapped.Length > 0) { foreach (var r in remapped) - remappedTypes.Add(r.RemappedType, r.Name); + remappedTypes.Add(context.Resolver.ResolveType(r.RemappedType), r.Name); } else { @@ -119,7 +120,7 @@ internal void LoadRemappedTypes() } } - internal bool IsRemappedType(Type type) + internal bool IsRemappedType(ITypeSymbol type) { return remappedTypes.ContainsKey(type); } @@ -171,15 +172,13 @@ internal RuntimeClassLoader GetClassLoaderWrapper(java.lang.ClassLoader javaClas /// /// /// - internal RuntimeJavaType GetJavaTypeFromType(Type type) + internal RuntimeJavaType GetJavaTypeFromType(ITypeSymbol type) { #if IMPORTER - if (type.__ContainsMissingType) - { + if (type.ContainsMissing) return new RuntimeUnloadableJavaType(context, type); - } #endif - //Tracer.Info(Tracer.Runtime, "GetWrapperFromType: {0}", type.AssemblyQualifiedName); + #if !IMPORTER RuntimeJavaType.AssertFinished(type); #endif @@ -194,7 +193,7 @@ internal RuntimeJavaType GetJavaTypeFromType(Type type) return wrapper; #if EXPORTER - if (type.__IsMissing || type.__ContainsMissingType) + if (type.IsMissing || type.ContainsMissing) { wrapper = new RuntimeUnloadableJavaType(context, type); globalTypeToTypeWrapper.Add(type, wrapper); @@ -206,12 +205,12 @@ internal RuntimeJavaType GetJavaTypeFromType(Type type) { wrapper = LoadClassCritical(remapped); } - else if (ReflectUtil.IsVector(type)) + else if (type.IsSZArray) { // it might be an array of a dynamically compiled Java type int rank = 1; - Type elem = type.GetElementType(); - while (ReflectUtil.IsVector(elem)) + var elem = type.GetElementType(); + while (elem.IsSZArray) { rank++; elem = elem.GetElementType(); diff --git a/src/IKVM.Runtime/RuntimeConstantJavaField.cs b/src/IKVM.Runtime/RuntimeConstantJavaField.cs index 269364aec..178e1a693 100644 --- a/src/IKVM.Runtime/RuntimeConstantJavaField.cs +++ b/src/IKVM.Runtime/RuntimeConstantJavaField.cs @@ -25,6 +25,8 @@ Jeroen Frijters using System.Diagnostics; using IKVM.Attributes; +using IKVM.CoreLib.Symbols; + #if IMPORTER || EXPORTER using IKVM.Reflection; @@ -64,7 +66,7 @@ sealed class RuntimeConstantJavaField : RuntimeJavaField /// /// /// - internal RuntimeConstantJavaField(RuntimeJavaType declaringType, RuntimeJavaType fieldType, string name, string sig, Modifiers modifiers, FieldInfo field, object constant, MemberFlags flags) : + internal RuntimeConstantJavaField(RuntimeJavaType declaringType, RuntimeJavaType fieldType, string name, string sig, Modifiers modifiers, IFieldSymbol field, object constant, MemberFlags flags) : base(declaringType, fieldType, name, sig, modifiers, field, flags) { if (IsStatic == false) diff --git a/src/IKVM.Runtime/RuntimeConstructorAccessStubJavaMethod.cs b/src/IKVM.Runtime/RuntimeConstructorAccessStubJavaMethod.cs index 3f54ca98c..3eb7ca57d 100644 --- a/src/IKVM.Runtime/RuntimeConstructorAccessStubJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimeConstructorAccessStubJavaMethod.cs @@ -22,14 +22,11 @@ Jeroen Frijters */ using IKVM.Attributes; +using IKVM.CoreLib.Symbols; #if IMPORTER || EXPORTER -using IKVM.Reflection; using IKVM.Reflection.Emit; - -using Type = IKVM.Reflection.Type; #else -using System.Reflection; using System.Reflection.Emit; #endif @@ -39,7 +36,7 @@ namespace IKVM.Runtime sealed class RuntimeConstructorAccessStubJavaMethod : RuntimeSmartJavaMethod { - readonly ConstructorInfo stub; + readonly IConstructorSymbol stub; /// /// Initializes a new instance. @@ -51,7 +48,7 @@ sealed class RuntimeConstructorAccessStubJavaMethod : RuntimeSmartJavaMethod /// /// /// - internal RuntimeConstructorAccessStubJavaMethod(RuntimeJavaType declaringType, string sig, ConstructorInfo core, ConstructorInfo stub, RuntimeJavaType[] parameterTypes, Modifiers modifiers, MemberFlags flags) : + internal RuntimeConstructorAccessStubJavaMethod(RuntimeJavaType declaringType, string sig, IConstructorSymbol core, IConstructorSymbol stub, RuntimeJavaType[] parameterTypes, Modifiers modifiers, MemberFlags flags) : base(declaringType, StringConstants.INIT, sig, core, declaringType.Context.PrimitiveJavaTypeFactory.VOID, parameterTypes, modifiers, flags) { this.stub = stub; diff --git a/src/IKVM.Runtime/RuntimeContext.cs b/src/IKVM.Runtime/RuntimeContext.cs index e2d770865..ef2ec783b 100644 --- a/src/IKVM.Runtime/RuntimeContext.cs +++ b/src/IKVM.Runtime/RuntimeContext.cs @@ -29,7 +29,7 @@ class RuntimeContext readonly RuntimeContextOptions options; readonly IDiagnosticHandler diagnostics; - readonly ISymbolResolver resolver; + readonly IRuntimeSymbolResolver resolver; readonly bool bootstrap; readonly ConcurrentDictionary singletons = new(); @@ -81,7 +81,7 @@ class RuntimeContext /// /// /// - public RuntimeContext(RuntimeContextOptions options, IDiagnosticHandler diagnostics, ISymbolResolver resolver, bool bootstrap, StaticCompiler staticCompiler) + public RuntimeContext(RuntimeContextOptions options, IDiagnosticHandler diagnostics, IRuntimeSymbolResolver resolver, bool bootstrap, StaticCompiler staticCompiler) { this.options = options ?? throw new ArgumentNullException(nameof(options)); this.diagnostics = diagnostics ?? throw new ArgumentNullException(nameof(diagnostics)); @@ -92,14 +92,14 @@ public RuntimeContext(RuntimeContextOptions options, IDiagnosticHandler diagnost #else - /// - /// Initializes a new instance. - /// - /// - /// - /// - /// - public RuntimeContext(RuntimeContextOptions options, IDiagnosticHandler diagnostics, ISymbolResolver resolver, bool bootstrap) + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + public RuntimeContext(RuntimeContextOptions options, IDiagnosticHandler diagnostics, IRuntimeSymbolResolver resolver, bool bootstrap) { this.options = options ?? throw new ArgumentNullException(nameof(options)); this.diagnostics = diagnostics ?? throw new ArgumentNullException(nameof(diagnostics)); @@ -143,10 +143,10 @@ T GetOrCreateSingleton(ref T value, Func create) /// public RuntimeContextOptions Options => options; - /// - /// Gets the associated with this instance of the runtime. - /// - public ISymbolResolver Resolver => resolver; + /// + /// Gets the associated with this instance of the runtime. + /// + public IRuntimeSymbolResolver Resolver => resolver; /// /// Gets whether or not the runtime is running in bootstrap mode; that is, we are compiling the Java base assembly itself. diff --git a/src/IKVM.Runtime/RuntimeDefaultInterfaceJavaMethod.cs b/src/IKVM.Runtime/RuntimeDefaultInterfaceJavaMethod.cs index 6287028aa..3350b11ea 100644 --- a/src/IKVM.Runtime/RuntimeDefaultInterfaceJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimeDefaultInterfaceJavaMethod.cs @@ -22,14 +22,11 @@ Jeroen Frijters */ using IKVM.Attributes; +using IKVM.CoreLib.Symbols; #if IMPORTER || EXPORTER -using IKVM.Reflection; using IKVM.Reflection.Emit; - -using Type = IKVM.Reflection.Type; #else -using System.Reflection; using System.Reflection.Emit; #endif @@ -39,7 +36,7 @@ namespace IKVM.Runtime sealed class RuntimeDefaultInterfaceJavaMethod : RuntimeSmartJavaMethod { - MethodInfo impl; + IMethodSymbol impl; /// /// Initializes a new instance. @@ -53,13 +50,13 @@ sealed class RuntimeDefaultInterfaceJavaMethod : RuntimeSmartJavaMethod /// /// /// - internal RuntimeDefaultInterfaceJavaMethod(RuntimeJavaType declaringType, string name, string sig, MethodInfo ifmethod, MethodInfo impl, RuntimeJavaType returnType, RuntimeJavaType[] parameterTypes, Modifiers modifiers, MemberFlags flags) : + internal RuntimeDefaultInterfaceJavaMethod(RuntimeJavaType declaringType, string name, string sig, IMethodSymbol ifmethod, IMethodSymbol impl, RuntimeJavaType returnType, RuntimeJavaType[] parameterTypes, Modifiers modifiers, MemberFlags flags) : base(declaringType, name, sig, ifmethod, returnType, parameterTypes, modifiers, flags) { this.impl = impl; } - internal static MethodInfo GetImpl(RuntimeJavaMethod mw) + internal static IMethodSymbol GetImpl(RuntimeJavaMethod mw) { var dimw = mw as RuntimeDefaultInterfaceJavaMethod; if (dimw != null) @@ -68,7 +65,7 @@ internal static MethodInfo GetImpl(RuntimeJavaMethod mw) return ((RuntimeGhostJavaMethod)mw).GetDefaultImpl(); } - internal static void SetImpl(RuntimeJavaMethod mw, MethodInfo impl) + internal static void SetImpl(RuntimeJavaMethod mw, IMethodSymbol impl) { var dimw = mw as RuntimeDefaultInterfaceJavaMethod; if (dimw != null) diff --git a/src/IKVM.Runtime/RuntimeGhostJavaMethod.cs b/src/IKVM.Runtime/RuntimeGhostJavaMethod.cs index f2a5e1702..894722bc2 100644 --- a/src/IKVM.Runtime/RuntimeGhostJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimeGhostJavaMethod.cs @@ -24,6 +24,7 @@ Jeroen Frijters using System.Diagnostics; using IKVM.Attributes; +using IKVM.CoreLib.Symbols; #if IMPORTER || EXPORTER using IKVM.Reflection; @@ -39,8 +40,8 @@ namespace IKVM.Runtime sealed class RuntimeGhostJavaMethod : RuntimeSmartJavaMethod { - MethodInfo ghostMethod; - MethodInfo defaultImpl; + IMethodSymbol ghostMethod; + IMethodSymbol defaultImpl; /// /// Initializes a new instance. @@ -54,7 +55,7 @@ sealed class RuntimeGhostJavaMethod : RuntimeSmartJavaMethod /// /// /// - internal RuntimeGhostJavaMethod(RuntimeJavaType declaringType, string name, string sig, MethodBase method, MethodInfo ghostMethod, RuntimeJavaType returnType, RuntimeJavaType[] parameterTypes, Modifiers modifiers, MemberFlags flags) : + internal RuntimeGhostJavaMethod(RuntimeJavaType declaringType, string name, string sig, IMethodBaseSymbol method, IMethodSymbol ghostMethod, RuntimeJavaType returnType, RuntimeJavaType[] parameterTypes, Modifiers modifiers, MemberFlags flags) : base(declaringType, name, sig, method, returnType, parameterTypes, modifiers, flags) { // make sure we weren't handed the ghostMethod in the wrapper value type @@ -81,17 +82,17 @@ protected override void CallvirtImpl(CodeEmitter ilgen) [HideFromJava] internal override object Invoke(object obj, object[] args) { - return InvokeAndUnwrapException(ghostMethod, DeclaringType.GhostWrap(obj), args); + return InvokeAndUnwrapException(ghostMethod.AsReflection(), DeclaringType.GhostWrap(obj), args); } #endif - internal void SetDefaultImpl(MethodInfo impl) + internal void SetDefaultImpl(IMethodSymbol impl) { this.defaultImpl = impl; } - internal MethodInfo GetDefaultImpl() + internal IMethodSymbol GetDefaultImpl() { return defaultImpl; } @@ -105,7 +106,7 @@ internal void SetGhostMethod(MethodBuilder mb) internal MethodBuilder GetGhostMethod() { - return (MethodBuilder)ghostMethod; + return (MethodBuilder)ghostMethod.AsReflection(); } #endif diff --git a/src/IKVM.Runtime/RuntimeJavaField.cs b/src/IKVM.Runtime/RuntimeJavaField.cs index 5b6a1ae85..c4cd21c80 100644 --- a/src/IKVM.Runtime/RuntimeJavaField.cs +++ b/src/IKVM.Runtime/RuntimeJavaField.cs @@ -23,16 +23,13 @@ Jeroen Frijters */ using System; using System.Diagnostics; +using System.Threading; using IKVM.Attributes; - -using System.Threading; +using IKVM.CoreLib.Symbols; #if IMPORTER || EXPORTER using IKVM.Reflection; -using IKVM.Reflection.Emit; - -using Type = IKVM.Reflection.Type; #else using System.Reflection; using System.Reflection.Emit; @@ -47,7 +44,7 @@ abstract class RuntimeJavaField : RuntimeJavaMember #if !IMPORTER && !FIRST_PASS && !EXPORTER volatile java.lang.reflect.Field reflectionField; #endif - FieldInfo field; + IFieldSymbol field; RuntimeJavaType fieldType; /// @@ -60,7 +57,7 @@ abstract class RuntimeJavaField : RuntimeJavaMember /// /// /// - internal RuntimeJavaField(RuntimeJavaType declaringType, RuntimeJavaType fieldType, string name, string sig, Modifiers modifiers, FieldInfo field, MemberFlags flags) : + internal RuntimeJavaField(RuntimeJavaType declaringType, RuntimeJavaType fieldType, string name, string sig, Modifiers modifiers, IFieldSymbol field, MemberFlags flags) : base(declaringType, name, sig, modifiers, flags) { if (name == null) @@ -97,7 +94,7 @@ this is not RuntimeConstantJavaField && /// /// /// - internal RuntimeJavaField(RuntimeJavaType declaringType, RuntimeJavaType fieldType, string name, string sig, ExModifiers modifiers, FieldInfo field) : + internal RuntimeJavaField(RuntimeJavaType declaringType, RuntimeJavaType fieldType, string name, string sig, ExModifiers modifiers, IFieldSymbol field) : this(declaringType, fieldType, name, sig, modifiers.Modifiers, field, (modifiers.IsInternal ? MemberFlags.InternalAccess : MemberFlags.None)) { @@ -118,7 +115,7 @@ void UpdateNonPublicTypeInSignatureFlag() /// Gets the CLR that forms the implementation of the field. /// /// - internal FieldInfo GetField() + internal IFieldSymbol GetField() { AssertLinked(); return field; @@ -431,7 +428,7 @@ internal bool IsSerialVersionUID } } - internal static RuntimeJavaField Create(RuntimeJavaType declaringType, RuntimeJavaType fieldType, FieldInfo fi, string name, string sig, ExModifiers modifiers) + internal static RuntimeJavaField Create(RuntimeJavaType declaringType, RuntimeJavaType fieldType, IFieldSymbol fi, string name, string sig, ExModifiers modifiers) { // volatile long & double field accesses must be made atomic if ((modifiers.Modifiers & Modifiers.Volatile) != 0 && (sig == "J" || sig == "D")) @@ -443,7 +440,7 @@ internal static RuntimeJavaField Create(RuntimeJavaType declaringType, RuntimeJa #if !IMPORTER && !EXPORTER internal virtual void ResolveField() { - var fb = field as FieldBuilder; + var fb = field.AsReflection() as FieldBuilder; if (fb != null) { #if NETFRAMEWORK @@ -511,8 +508,8 @@ Delegate CreateUnsafeGetDelegate() FieldTypeWrapper.Finish(); ResolveField(); - var ft = FieldTypeWrapper.IsPrimitive ? FieldTypeWrapper.TypeAsSignatureType : typeof(object); - var dm = DynamicMethodUtil.Create($"____{DeclaringType.Name.Replace(".", "_")}__{Name}", DeclaringType.TypeAsTBD, true, ft, new[] { typeof(object) }); + var ft = FieldTypeWrapper.IsPrimitive ? FieldTypeWrapper.TypeAsSignatureType.AsReflection() : typeof(object); + var dm = DynamicMethodUtil.Create($"____{DeclaringType.Name.Replace(".", "_")}__{Name}", DeclaringType.TypeAsTBD.AsReflection(), true, ft, [typeof(object)]); var il = JVM.Context.CodeEmitterFactory.Create(dm); if (IsStatic == false) @@ -558,8 +555,8 @@ Delegate CreateUnsafeSetDelegate() FieldTypeWrapper.Finish(); ResolveField(); - var ft = FieldTypeWrapper.IsPrimitive ? FieldTypeWrapper.TypeAsSignatureType : typeof(object); - var dm = DynamicMethodUtil.Create($"____{DeclaringType.Name.Replace(".", "_")}__{Name}", DeclaringType.TypeAsTBD, true, typeof(void), new[] { typeof(object), ft }); + var ft = FieldTypeWrapper.IsPrimitive ? FieldTypeWrapper.TypeAsSignatureType.AsReflection() : typeof(object); + var dm = DynamicMethodUtil.Create($"____{DeclaringType.Name.Replace(".", "_")}__{Name}", DeclaringType.TypeAsTBD.AsReflection(), true, typeof(void), [typeof(object), ft]); var il = JVM.Context.CodeEmitterFactory.Create(dm); if (IsStatic == false) @@ -603,8 +600,8 @@ Delegate GetUnsafeVolatileGetDelegate() Delegate CreateUnsafeVolatileGetDelegate() { ResolveField(); - var ft = FieldTypeWrapper.IsPrimitive ? FieldTypeWrapper.TypeAsSignatureType : typeof(object); - var dm = new DynamicMethod($"____{DeclaringType.Name.Replace(".", "_")}__{Name}", ft, new[] { typeof(object) }, DeclaringType.TypeAsTBD.Module, true); + var ft = FieldTypeWrapper.IsPrimitive ? FieldTypeWrapper.TypeAsSignatureType.AsReflection() : typeof(object); + var dm = new DynamicMethod($"____{DeclaringType.Name.Replace(".", "_")}__{Name}", ft, [typeof(object)], DeclaringType.TypeAsTBD.Module.AsReflection(), true); var il = JVM.Context.CodeEmitterFactory.Create(dm); if (IsStatic == false) @@ -648,8 +645,8 @@ Delegate GetUnsafeVolatileSetDelegate() Delegate CreateUnsafeVolatileSetDelegate() { ResolveField(); - var ft = FieldTypeWrapper.IsPrimitive ? FieldTypeWrapper.TypeAsSignatureType : typeof(object); - var dm = DynamicMethodUtil.Create($"____{DeclaringType.Name.Replace(".", "_")}__{Name}", DeclaringType.TypeAsTBD, true, typeof(void), new[] { typeof(object), ft }); + var ft = FieldTypeWrapper.IsPrimitive ? FieldTypeWrapper.TypeAsSignatureType.AsReflection() : typeof(object); + var dm = DynamicMethodUtil.Create($"____{DeclaringType.Name.Replace(".", "_")}__{Name}", DeclaringType.TypeAsTBD.AsReflection(), true, typeof(void), [typeof(object), ft]); var il = JVM.Context.CodeEmitterFactory.Create(dm); if (IsStatic == false) @@ -696,8 +693,8 @@ Delegate GetUnsafeCompareAndSwapDelegate() Delegate CreateUnsafeCompareAndSwapDelegate() { ResolveField(); - var ft = FieldTypeWrapper.IsPrimitive ? FieldTypeWrapper.TypeAsSignatureType : typeof(object); - var dm = DynamicMethodUtil.Create($"____{DeclaringType.Name.Replace(".", "_")}__{Name}", DeclaringType.TypeAsTBD, true, typeof(bool), new[] { typeof(object), ft, ft }); + var ft = FieldTypeWrapper.IsPrimitive ? FieldTypeWrapper.TypeAsSignatureType.AsReflection() : typeof(object); + var dm = DynamicMethodUtil.Create($"____{DeclaringType.Name.Replace(".", "_")}__{Name}", DeclaringType.TypeAsTBD.AsReflection(), true, typeof(bool), [typeof(object), ft, ft]); var il = JVM.Context.CodeEmitterFactory.Create(dm); if (IsStatic == false) diff --git a/src/IKVM.Runtime/RuntimeJavaMethod.cs b/src/IKVM.Runtime/RuntimeJavaMethod.cs index 6e752c734..2456f18ee 100644 --- a/src/IKVM.Runtime/RuntimeJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimeJavaMethod.cs @@ -27,7 +27,9 @@ Jeroen Frijters using IKVM.Attributes; using System.Linq; -using IKVM.CoreLib.Diagnostics; + +using IKVM.CoreLib.Symbols; + #if IMPORTER || EXPORTER @@ -46,7 +48,7 @@ namespace IKVM.Runtime abstract class RuntimeJavaMethod : RuntimeJavaMember { - MethodBase method; + IMethodBaseSymbol method; string[] declaredExceptions; RuntimeJavaType returnTypeWrapper; RuntimeJavaType[] parameterTypeWrappers; @@ -97,7 +99,7 @@ internal virtual bool EmitIntrinsic(EmitIntrinsicContext context) /// /// /// - internal RuntimeJavaMethod(RuntimeJavaType declaringType, string name, string sig, MethodBase method, RuntimeJavaType returnType, RuntimeJavaType[] parameterTypes, Modifiers modifiers, MemberFlags flags) : + internal RuntimeJavaMethod(RuntimeJavaType declaringType, string name, string sig, IMethodBaseSymbol method, RuntimeJavaType returnType, RuntimeJavaType[] parameterTypes, Modifiers modifiers, MemberFlags flags) : base(declaringType, name, sig, modifiers, flags) { Profiler.Count("MethodWrapper"); @@ -142,7 +144,7 @@ internal void SetDeclaredExceptions(string[] exceptions) { declaredExceptions = exceptions != null && exceptions.Length > 0 ? (string[])exceptions.Clone() : Array.Empty(); } - + /// /// Gest the declared exceptions for the method. /// @@ -225,18 +227,20 @@ internal java.lang.reflect.Executable ToMethodOrConstructor(bool copy) } #if !FIRST_PASS - private java.lang.Class[] GetExceptions() + + java.lang.Class[] GetExceptions() { - string[] classes = declaredExceptions; - Type[] types = Type.EmptyTypes; + Type[] types = []; + + var classes = declaredExceptions; if (classes == null) { // NOTE if method is a MethodBuilder, GetCustomAttributes doesn't work (and if // the method had any declared exceptions, the declaredExceptions field would have // been set) - if (method != null && method is not MethodBuilder) + if (method != null && method.AsReflection() is not MethodBuilder) { - ThrowsAttribute attr = DeclaringType.Context.AttributeHelper.GetThrows(method); + var attr = DeclaringType.Context.AttributeHelper.GetThrows(method); if (attr != null) { classes = attr.classes; @@ -244,25 +248,25 @@ private java.lang.Class[] GetExceptions() } } } + if (classes != null) { - java.lang.Class[] array = new java.lang.Class[classes.Length]; + var array = new java.lang.Class[classes.Length]; for (int i = 0; i < classes.Length; i++) - { array[i] = this.DeclaringType.ClassLoader.LoadClassByName(classes[i]).ClassObject; - } + return array; } else { - java.lang.Class[] array = new java.lang.Class[types.Length]; + var array = new java.lang.Class[types.Length]; for (int i = 0; i < types.Length; i++) - { array[i] = types[i]; - } + return array; } } + #endif // !FIRST_PASS internal static RuntimeJavaMethod FromExecutable(java.lang.reflect.Executable executable) @@ -381,7 +385,7 @@ internal DefineMethodHelper GetDefineMethodHelper() } #endif - internal Type ReturnTypeForDefineMethod + internal ITypeSymbol ReturnTypeForDefineMethod { get { @@ -389,23 +393,20 @@ internal Type ReturnTypeForDefineMethod } } - internal Type[] GetParametersForDefineMethod() + internal ITypeSymbol[] GetParametersForDefineMethod() { - RuntimeJavaType[] wrappers = GetParameters(); - int len = wrappers.Length; + var wrappers = GetParameters(); + var len = wrappers.Length; if (HasCallerID) - { len++; - } - Type[] temp = new Type[len]; + + var temp = new ITypeSymbol[len]; for (int i = 0; i < wrappers.Length; i++) - { temp[i] = wrappers[i].TypeAsSignatureType; - } + if (HasCallerID) - { temp[len - 1] = DeclaringType.Context.JavaBase.TypeOfIkvmInternalCallerID.TypeAsSignatureType; - } + return temp; } @@ -413,7 +414,7 @@ internal Type[] GetParametersForDefineMethod() // for Java types, this is the method that contains the compiled Java bytecode // for remapped types, this is the mbCore method (not the helper) // Note that for some artificial methods (notably wrap() in enums), method is null - internal MethodBase GetMethod() + internal IMethodBaseSymbol GetMethod() { AssertLinked(); return method; @@ -451,7 +452,7 @@ internal bool RequiresNonVirtualDispatcher #if !IMPORTER && !EXPORTER - internal Type GetDelegateType() + internal ITypeSymbol GetDelegateType() { var paramTypes = GetParameters(); if (paramTypes.Length > MethodHandleUtil.MaxArity) @@ -460,7 +461,7 @@ internal Type GetDelegateType() if (type == null) type = DeclaringType.ClassLoader.GetTypeWrapperFactory().DefineDelegate(paramTypes.Length, ReturnType == DeclaringType.Context.PrimitiveJavaTypeFactory.VOID); - var types = new Type[paramTypes.Length + (ReturnType == DeclaringType.Context.PrimitiveJavaTypeFactory.VOID ? 0 : 1)]; + var types = new ITypeSymbol[paramTypes.Length + (ReturnType == DeclaringType.Context.PrimitiveJavaTypeFactory.VOID ? 0 : 1)]; for (int i = 0; i < paramTypes.Length; i++) types[i] = paramTypes[i].TypeAsSignatureType; @@ -482,7 +483,7 @@ internal void ResolveMethod() throw new NotImplementedException(); #else // if we've still got the builder object, we need to replace it with the real thing before we can call it - var mb = method as MethodBuilder; + var mb = method.AsReflection() as MethodBuilder; if (mb != null) { #if NETFRAMEWORK @@ -537,14 +538,14 @@ internal virtual object InvokeNonvirtualRemapped(object obj, object[] args) /// /// [HideFromJava] - protected static object InvokeAndUnwrapException(MethodBase mb, object obj, object[] args) + protected static object InvokeAndUnwrapException(IMethodBaseSymbol mb, object obj, object[] args) { #if FIRST_PASS throw new NotImplementedException(); #else try { - return mb.Invoke(obj, args); + return mb.AsReflection().Invoke(obj, args); } catch (TargetInvocationException e) { diff --git a/src/IKVM.Runtime/RuntimeJavaType.cs b/src/IKVM.Runtime/RuntimeJavaType.cs index e16b87889..ff32a1673 100644 --- a/src/IKVM.Runtime/RuntimeJavaType.cs +++ b/src/IKVM.Runtime/RuntimeJavaType.cs @@ -22,17 +22,19 @@ Jeroen Frijters */ using System; -using System.Collections.Generic; using System.Diagnostics; +using System.Linq; using IKVM.Attributes; using IKVM.CoreLib.Diagnostics; +using IKVM.CoreLib.Symbols; #if IMPORTER || EXPORTER using IKVM.Reflection; using IKVM.Reflection.Emit; using Type = IKVM.Reflection.Type; + #else using System.Reflection; using System.Reflection.Emit; @@ -106,11 +108,12 @@ internal void EmitClassLiteral(CodeEmitter ilgen) if (!this.IsFastClassLiteralSafe || IsForbiddenTypeParameterType(type)) { int rank = 0; - while (ReflectUtil.IsVector(type)) + while (type.IsSZArray) { rank++; type = type.GetElementType(); } + if (rank == 0) { ilgen.Emit(OpCodes.Ldtoken, type); @@ -125,18 +128,18 @@ internal void EmitClassLiteral(CodeEmitter ilgen) } else { - var classLiteralType = Context.Resolver.ResolveRuntimeType("IKVM.Runtime.ClassLiteral`1").AsReflection().MakeGenericType(type); + var classLiteralType = Context.Resolver.ResolveRuntimeType("IKVM.Runtime.ClassLiteral`1").MakeGenericType(type); ilgen.Emit(OpCodes.Call, classLiteralType.GetProperty("Value").GetMethod); } } #endif - private Type GetClassLiteralType() + ITypeSymbol GetClassLiteralType() { - Debug.Assert(!this.IsPrimitive); + Debug.Assert(IsPrimitive == false); - RuntimeJavaType tw = this; + var tw = this; if (tw.IsGhostArray) { var rank = tw.ArrayRank; @@ -151,16 +154,14 @@ private Type GetClassLiteralType() } } - bool IsForbiddenTypeParameterType(Type type) + bool IsForbiddenTypeParameterType(ITypeSymbol type) { // these are the types that may not be used as a type argument when instantiating a generic type return type == context.Types.Void -#if NETFRAMEWORK - || type == context.Resolver.ResolveCoreType(typeof(ArgIterator).FullName).AsReflection() -#endif - || type == context.Resolver.ResolveCoreType(typeof(RuntimeArgumentHandle).FullName).AsReflection() - || type == context.Resolver.ResolveCoreType(typeof(TypedReference).FullName).AsReflection() - || type.ContainsGenericParameters + || type == context.Resolver.ResolveCoreType(typeof(ArgIterator).FullName) + || type == context.Resolver.ResolveCoreType(typeof(RuntimeArgumentHandle).FullName) + || type == context.Resolver.ResolveCoreType(typeof(TypedReference).FullName) + || type.ContainsGenericParameters || type.IsByRef; } @@ -247,9 +248,9 @@ private void LazyInitClass() #if !FIRST_PASS java.lang.Class clazz; // note that this has to be the same check as in EmitClassLiteral - if (!this.IsFastClassLiteralSafe) + if (!IsFastClassLiteralSafe) { - if (this.IsPrimitive) + if (IsPrimitive) { clazz = GetPrimitiveClass(); } @@ -260,53 +261,37 @@ private void LazyInitClass() } else { - Type type = GetClassLiteralType(); + var type = GetClassLiteralType(); if (IsForbiddenTypeParameterType(type)) - { - clazz = new java.lang.Class(type); - } + clazz = new java.lang.Class(type.AsReflection()); else - { - clazz = (java.lang.Class)typeof(ClassLiteral<>).MakeGenericType(type).GetProperty("Value").GetGetMethod().Invoke(null, Array.Empty()); - } + clazz = (java.lang.Class)typeof(ClassLiteral<>).MakeGenericType(type.AsReflection()).GetProperty("Value").GetGetMethod().Invoke(null, []); } + clazz.typeWrapper = this; - // MONOBUG Interlocked.Exchange is broken on Mono, so we use CompareExchange System.Threading.Interlocked.CompareExchange(ref classObject, clazz, null); #endif } } } -#if __MonoCS__ - // MONOBUG this method is to work around an mcs bug - internal static void SetTypeWrapperHack(object clazz, TypeWrapper type) - { -#if !FIRST_PASS - typeof(java.lang.Class).GetField("typeWrapper", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(clazz, type); -#endif - } -#endif - #if !FIRST_PASS - private static void ResolvePrimitiveTypeWrapperClasses(RuntimeContext context) + static void ResolvePrimitiveTypeWrapperClasses(RuntimeContext context) { // note that we're evaluating all ClassObject properties for the side effect // (to initialize and associate the ClassObject with the TypeWrapper) - if (context.PrimitiveJavaTypeFactory.BYTE.ClassObject == null - || context.PrimitiveJavaTypeFactory.CHAR.ClassObject == null - || context.PrimitiveJavaTypeFactory.DOUBLE.ClassObject == null - || context.PrimitiveJavaTypeFactory.FLOAT.ClassObject == null - || context.PrimitiveJavaTypeFactory.INT.ClassObject == null - || context.PrimitiveJavaTypeFactory.LONG.ClassObject == null - || context.PrimitiveJavaTypeFactory.SHORT.ClassObject == null - || context.PrimitiveJavaTypeFactory.BOOLEAN.ClassObject == null - || context.PrimitiveJavaTypeFactory.VOID.ClassObject == null) - { + if (context.PrimitiveJavaTypeFactory.BYTE.ClassObject == null || + context.PrimitiveJavaTypeFactory.CHAR.ClassObject == null || + context.PrimitiveJavaTypeFactory.DOUBLE.ClassObject == null || + context.PrimitiveJavaTypeFactory.FLOAT.ClassObject == null || + context.PrimitiveJavaTypeFactory.INT.ClassObject == null || + context.PrimitiveJavaTypeFactory.LONG.ClassObject == null || + context.PrimitiveJavaTypeFactory.SHORT.ClassObject == null || + context.PrimitiveJavaTypeFactory.BOOLEAN.ClassObject == null || + context.PrimitiveJavaTypeFactory.VOID.ClassObject == null) throw new InvalidOperationException(); - } } #endif @@ -326,10 +311,11 @@ internal static RuntimeJavaType FromClass(java.lang.Class clazz) return FromClass(clazz); } - if (type == typeof(void) || type.IsPrimitive || JVM.Context.ClassLoaderFactory.IsRemappedType(type)) - tw = JVM.Context.ManagedJavaTypeFactory.GetJavaTypeFromManagedType(type); + var symbol = JVM.Context.Resolver.ResolveType(type); + if (type == typeof(void) || type.IsPrimitive || JVM.Context.ClassLoaderFactory.IsRemappedType(symbol)) + tw = JVM.Context.ManagedJavaTypeFactory.GetJavaTypeFromManagedType(symbol); else - tw = JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(type); + tw = JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(symbol); clazz.typeWrapper = tw; } @@ -467,29 +453,11 @@ internal virtual bool IsGhost } // is this an array type of which the ultimate element type is a ghost? - internal bool IsGhostArray - { - get - { - return !IsUnloadable && IsArray && (ElementTypeWrapper.IsGhost || ElementTypeWrapper.IsGhostArray); - } - } + internal bool IsGhostArray => !IsUnloadable && IsArray && (ElementTypeWrapper.IsGhost || ElementTypeWrapper.IsGhostArray); - internal virtual FieldInfo GhostRefField - { - get - { - throw new InvalidOperationException(); - } - } + internal virtual IFieldSymbol GhostRefField => throw new InvalidOperationException(); - internal virtual bool IsRemapped - { - get - { - return false; - } - } + internal virtual bool IsRemapped => false; internal bool IsArray { @@ -558,7 +526,7 @@ internal bool IsIntOnStackPrimitive } } - private static bool IsJavaPrimitive(RuntimeContext context, Type type) + private static bool IsJavaPrimitive(RuntimeContext context, ITypeSymbol type) { return type == context.PrimitiveJavaTypeFactory.BOOLEAN.TypeAsTBD || type == context.PrimitiveJavaTypeFactory.BYTE.TypeAsTBD @@ -789,26 +757,26 @@ internal RuntimeJavaField[] GetFields() #if IMPORTER - private static bool CheckMissingBaseTypes(RuntimeContext context, Type type) + static bool CheckMissingBaseTypes(RuntimeContext context, ITypeSymbol type) { while (type != null) { - if (type.__ContainsMissingType) + if (type.ContainsMissing) { context.StaticCompiler.IssueMissingTypeMessage(type); return false; } - bool ok = true; - foreach (Type iface in type.__GetDeclaredInterfaces()) - { + + var ok = true; + foreach (var iface in type.GetInterfaces(false)) ok &= CheckMissingBaseTypes(context, iface); - } + if (!ok) - { return false; - } + type = type.BaseType; } + return true; } @@ -821,6 +789,7 @@ internal RuntimeJavaMethod GetMethodWrapper(string name, string sig, bool inheri var _name = string.IsInterned(name); var _sig = string.IsInterned(sig); + foreach (var mw in methods) { // NOTE we can use ref equality, because names and signatures are always interned by MemberWrapper @@ -947,12 +916,12 @@ static bool MatchingPackageNames(string name1, string name2) return string.CompareOrdinal(name1, skip1, name2, skip2, index1 - skip1) == 0; } - internal abstract Type TypeAsTBD + internal abstract ITypeSymbol TypeAsTBD { get; } - internal Type TypeAsSignatureType + internal ITypeSymbol TypeAsSignatureType { get { @@ -966,11 +935,11 @@ internal Type TypeAsSignatureType } } - internal Type TypeAsPublicSignatureType => (IsPublic ? this : GetPublicBaseTypeWrapper()).TypeAsSignatureType; + internal ITypeSymbol TypeAsPublicSignatureType => (IsPublic ? this : GetPublicBaseTypeWrapper()).TypeAsSignatureType; - internal virtual Type TypeAsBaseType => TypeAsTBD; + internal virtual ITypeSymbol TypeAsBaseType => TypeAsTBD; - internal Type TypeAsLocalOrStackType + internal ITypeSymbol TypeAsLocalOrStackType { get { @@ -991,7 +960,7 @@ internal Type TypeAsLocalOrStackType } /** Use this if the type is used as an array or array element */ - internal Type TypeAsArrayType + internal ITypeSymbol TypeAsArrayType { get { @@ -1005,7 +974,7 @@ internal Type TypeAsArrayType } } - internal Type TypeAsExceptionType + internal ITypeSymbol TypeAsExceptionType { get { @@ -1223,29 +1192,28 @@ internal void LinkAll() } #if !IMPORTER + [Conditional("DEBUG")] - internal static void AssertFinished(Type type) + internal static void AssertFinished(ITypeSymbol type) { if (type != null) { while (type.HasElementType) - { type = type.GetElementType(); - } - Debug.Assert(!(type is TypeBuilder)); + + Debug.Assert(!(type.AsReflection() is TypeBuilder)); } } + #endif #if !IMPORTER && !EXPORTER internal void RunClassInit() { - Type t = IsRemapped ? TypeAsBaseType : TypeAsTBD; + var t = IsRemapped ? TypeAsBaseType : TypeAsTBD; if (t != null) - { - System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(t.TypeHandle); - } + System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(t.AsReflection().TypeHandle); } #endif @@ -1270,6 +1238,7 @@ internal void EmitConvSignatureTypeToStackType(CodeEmitter ilgen) { if (IsUnloadable) { + } else if (this == context.PrimitiveJavaTypeFactory.BYTE) { @@ -1281,7 +1250,7 @@ internal void EmitConvSignatureTypeToStackType(CodeEmitter ilgen) } else if (IsGhost) { - CodeEmitterLocal local = ilgen.DeclareLocal(TypeAsSignatureType); + var local = ilgen.DeclareLocal(TypeAsSignatureType); ilgen.Emit(OpCodes.Stloc, local); ilgen.Emit(OpCodes.Ldloca, local); ilgen.Emit(OpCodes.Ldfld, GhostRefField); @@ -1442,13 +1411,13 @@ internal virtual void EmitStind(CodeEmitter il) #endif // NOTE don't call this method, call MethodWrapper.Link instead - internal virtual MethodBase LinkMethod(RuntimeJavaMethod mw) + internal virtual IMethodBaseSymbol LinkMethod(RuntimeJavaMethod mw) { return mw.GetMethod(); } // NOTE don't call this method, call FieldWrapper.Link instead - internal virtual FieldInfo LinkField(RuntimeJavaField fw) + internal virtual IFieldSymbol LinkField(RuntimeJavaField fw) { return fw.GetField(); } @@ -1517,57 +1486,33 @@ internal virtual int GetSourceLineNumber(MethodBase mb, int ilOffset) internal virtual object GetAnnotationDefault(RuntimeJavaMethod mw) { - MethodBase mb = mw.GetMethod(); + var mb = mw.GetMethod(); if (mb != null) { - object[] attr = mb.GetCustomAttributes(typeof(AnnotationDefaultAttribute), false); - if (attr.Length == 1) - { - return JVM.NewAnnotationElementValue(mw.DeclaringType.ClassLoader.GetJavaClassLoader(), mw.ReturnType.ClassObject, ((AnnotationDefaultAttribute)attr[0]).Value); - } + var attr = mb.AsReflection().GetCustomAttribute(); + if (attr != null) + return JVM.NewAnnotationElementValue(mw.DeclaringType.ClassLoader.GetJavaClassLoader(), mw.ReturnType.ClassObject, attr.Value); } + return null; } + #endif // !IMPORTER && !EXPORTER internal virtual Annotation Annotation => null; - internal virtual Type EnumType => null; + internal virtual ITypeSymbol EnumType => null; - private static Type[] GetInterfaces(Type type) + static ITypeSymbol[] GetInterfaces(ITypeSymbol type) { -#if IMPORTER || EXPORTER - List list = new List(); - for (; type != null && !type.__IsMissing; type = type.BaseType) - { - AddInterfaces(list, type); - } - return list.ToArray(); -#else - return type.GetInterfaces(); -#endif - } + var ifaces = type.GetInterfaces(); + if (ifaces.Any(i => i.IsMissing)) + ifaces = ifaces.Where(i => i.IsMissing == false).ToArray(); -#if IMPORTER || EXPORTER - - private static void AddInterfaces(List list, Type type) - { - foreach (var iface in type.__GetDeclaredInterfaces()) - { - if (!list.Contains(iface)) - { - list.Add(iface); - if (!iface.__IsMissing) - { - AddInterfaces(list, iface); - } - } - } + return ifaces; } -#endif - - protected static RuntimeJavaType[] GetImplementedInterfacesAsTypeWrappers(RuntimeContext context, Type type) + protected static RuntimeJavaType[] GetImplementedInterfacesAsTypeWrappers(RuntimeContext context, ITypeSymbol type) { var interfaceTypes = GetInterfaces(type); var interfaces = new RuntimeJavaType[interfaceTypes.Length]; @@ -1617,12 +1562,14 @@ internal RuntimeJavaType GetPublicBaseTypeWrapper() #if !EXPORTER // return the constructor used for automagic .NET serialization - internal virtual MethodBase GetSerializationConstructor() + internal virtual IMethodBaseSymbol GetSerializationConstructor() { - return TypeAsBaseType.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, [context.Resolver.ResolveCoreType(typeof(System.Runtime.Serialization.SerializationInfo).FullName).AsReflection(), context.Resolver.ResolveCoreType(typeof(System.Runtime.Serialization.StreamingContext).FullName).AsReflection()], null); + return TypeAsBaseType.GetConstructor( + System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance, + [context.Resolver.ResolveCoreType(typeof(System.Runtime.Serialization.SerializationInfo).FullName), context.Resolver.ResolveCoreType(typeof(System.Runtime.Serialization.StreamingContext).FullName)]); } - internal virtual MethodBase GetBaseSerializationConstructor() + internal virtual IMethodBaseSymbol GetBaseSerializationConstructor() { return BaseTypeWrapper.GetSerializationConstructor(); } @@ -1630,6 +1577,7 @@ internal virtual MethodBase GetBaseSerializationConstructor() #endif #if !IMPORTER && !EXPORTER + internal virtual object GhostWrap(object obj) { return obj; @@ -1639,6 +1587,7 @@ internal virtual object GhostUnwrap(object obj) { return obj; } + #endif internal bool IsDynamic @@ -1671,11 +1620,14 @@ internal virtual byte[] GetFieldRawTypeAnnotations(RuntimeJavaField fw) } #if !IMPORTER && !EXPORTER + internal virtual RuntimeJavaType Host { get { return null; } } + #endif + } } diff --git a/src/IKVM.Runtime/RuntimeJavaTypeFactory.cs b/src/IKVM.Runtime/RuntimeJavaTypeFactory.cs index e9d01832e..1da4591ce 100644 --- a/src/IKVM.Runtime/RuntimeJavaTypeFactory.cs +++ b/src/IKVM.Runtime/RuntimeJavaTypeFactory.cs @@ -21,18 +21,15 @@ Jeroen Frijters jeroen@frijters.net */ - -using System; using System.Collections.Generic; +using IKVM.CoreLib.Symbols; + #if IMPORTER || EXPORTER -using IKVM.Reflection; using IKVM.Reflection.Emit; -using Type = IKVM.Reflection.Type; using ProtectionDomain = System.Object; #else -using System.Reflection; using System.Reflection.Emit; using ProtectionDomain = java.security.ProtectionDomain; @@ -54,9 +51,9 @@ abstract class RuntimeJavaTypeFactory internal abstract string AllocMangledName(RuntimeByteCodeJavaType tw); - internal abstract Type DefineUnloadable(string name); + internal abstract ITypeSymbol DefineUnloadable(string name); - internal abstract Type DefineDelegate(int parameterCount, bool returnVoid); + internal abstract ITypeSymbol DefineDelegate(int parameterCount, bool returnVoid); internal abstract bool HasInternalAccess { get; } diff --git a/src/IKVM.Runtime/RuntimeManagedByteCodeAccessStubJavaField.cs b/src/IKVM.Runtime/RuntimeManagedByteCodeAccessStubJavaField.cs index 5f7b3a646..624b90831 100644 --- a/src/IKVM.Runtime/RuntimeManagedByteCodeAccessStubJavaField.cs +++ b/src/IKVM.Runtime/RuntimeManagedByteCodeAccessStubJavaField.cs @@ -22,6 +22,8 @@ Jeroen Frijters */ using IKVM.Attributes; +using IKVM.CoreLib.Symbols; + #if IMPORTER || EXPORTER using IKVM.Reflection; @@ -39,10 +41,10 @@ namespace IKVM.Runtime sealed class RuntimeManagedByteCodeAccessStubJavaField : RuntimeJavaField { - readonly MethodInfo getter; - readonly MethodInfo setter; + readonly IMethodSymbol getter; + readonly IMethodSymbol setter; - static Modifiers GetModifiers(PropertyInfo property) + static Modifiers GetModifiers(IPropertySymbol property) { // NOTE we only support the subset of modifiers that is expected for "access stub" properties var getter = property.GetGetMethod(true); @@ -61,7 +63,7 @@ static Modifiers GetModifiers(PropertyInfo property) /// /// /// - internal RuntimeManagedByteCodeAccessStubJavaField(RuntimeJavaType wrapper, PropertyInfo property, RuntimeJavaType propertyType) : + internal RuntimeManagedByteCodeAccessStubJavaField(RuntimeJavaType wrapper, IPropertySymbol property, RuntimeJavaType propertyType) : this(wrapper, property, null, propertyType, GetModifiers(property), MemberFlags.HideFromReflection | MemberFlags.AccessStub) { @@ -74,7 +76,7 @@ internal RuntimeManagedByteCodeAccessStubJavaField(RuntimeJavaType wrapper, Prop /// /// /// - internal RuntimeManagedByteCodeAccessStubJavaField(RuntimeJavaType wrapper, PropertyInfo property, FieldInfo field, RuntimeJavaType propertyType) : + internal RuntimeManagedByteCodeAccessStubJavaField(RuntimeJavaType wrapper, IPropertySymbol property, IFieldSymbol field, RuntimeJavaType propertyType) : this(wrapper, property, field, propertyType, wrapper.Context.AttributeHelper.GetModifiersAttribute(property).Modifiers, MemberFlags.AccessStub) { @@ -89,7 +91,7 @@ internal RuntimeManagedByteCodeAccessStubJavaField(RuntimeJavaType wrapper, Prop /// /// /// - private RuntimeManagedByteCodeAccessStubJavaField(RuntimeJavaType wrapper, PropertyInfo property, FieldInfo field, RuntimeJavaType propertyType, Modifiers modifiers, MemberFlags flags) : + private RuntimeManagedByteCodeAccessStubJavaField(RuntimeJavaType wrapper, IPropertySymbol property, IFieldSymbol field, RuntimeJavaType propertyType, Modifiers modifiers, MemberFlags flags) : base(wrapper, propertyType, property.Name, propertyType.SigName, modifiers, field, flags) { this.getter = property.GetGetMethod(true); diff --git a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.DelegateConstructorJavaMethod.cs b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.DelegateConstructorJavaMethod.cs index d9ca62389..da72483ac 100644 --- a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.DelegateConstructorJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.DelegateConstructorJavaMethod.cs @@ -21,6 +21,7 @@ Jeroen Frijters jeroen@frijters.net */ +using IKVM.CoreLib.Symbols; #if IMPORTER || EXPORTER using IKVM.Reflection; @@ -41,8 +42,8 @@ partial class RuntimeManagedByteCodeJavaType sealed class DelegateConstructorJavaMethod : RuntimeJavaMethod { - readonly ConstructorInfo constructor; - MethodInfo invoke; + readonly IConstructorSymbol constructor; + IMethodSymbol invoke; /// /// Initializes a new instance. @@ -51,7 +52,7 @@ sealed class DelegateConstructorJavaMethod : RuntimeJavaMethod /// /// DelegateConstructorJavaMethod(RuntimeJavaType tw, RuntimeJavaType iface, ExModifiers mods) : - base(tw, StringConstants.INIT, "(" + iface.SigName + ")V", null, tw.Context.PrimitiveJavaTypeFactory.VOID, new RuntimeJavaType[] { iface }, mods.Modifiers, mods.IsInternal ? MemberFlags.InternalAccess : MemberFlags.None) + base(tw, StringConstants.INIT, "(" + iface.SigName + ")V", null, tw.Context.PrimitiveJavaTypeFactory.VOID, [iface], mods.Modifiers, mods.IsInternal ? MemberFlags.InternalAccess : MemberFlags.None) { } @@ -61,17 +62,17 @@ sealed class DelegateConstructorJavaMethod : RuntimeJavaMethod /// /// /// - internal DelegateConstructorJavaMethod(RuntimeJavaType tw, MethodBase method) : + internal DelegateConstructorJavaMethod(RuntimeJavaType tw, IMethodBaseSymbol method) : this(tw, tw.ClassLoader.LoadClassByName(tw.Name + RuntimeManagedJavaType.DelegateInterfaceSuffix), tw.Context.AttributeHelper.GetModifiers(method, false)) { - constructor = (ConstructorInfo)method; + constructor = (IConstructorSymbol)method; } protected override void DoLinkMethod() { var mw = GetParameters()[0].GetMethods()[0]; mw.Link(); - invoke = (MethodInfo)mw.GetMethod(); + invoke = (IMethodSymbol)mw.GetMethod(); } #if EMITTERS diff --git a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.GhostJavaType.cs b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.GhostJavaType.cs index ebbefa4c0..db1e75101 100644 --- a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.GhostJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.GhostJavaType.cs @@ -21,15 +21,7 @@ Jeroen Frijters jeroen@frijters.net */ -using System; - -#if IMPORTER || EXPORTER -using IKVM.Reflection; - -using Type = IKVM.Reflection.Type; -#else -using System.Reflection; -#endif +using IKVM.CoreLib.Symbols; namespace IKVM.Runtime { @@ -40,8 +32,8 @@ partial class RuntimeManagedByteCodeJavaType public sealed class GhostJavaType : RuntimeManagedByteCodeJavaType { - volatile FieldInfo ghostRefField; - volatile Type typeAsBaseType; + volatile IFieldSymbol ghostRefField; + volatile ITypeSymbol typeAsBaseType; /// /// Initializes a new instance. @@ -49,33 +41,15 @@ public sealed class GhostJavaType : RuntimeManagedByteCodeJavaType /// /// /// - internal GhostJavaType(RuntimeContext context, string name, Type type) : + internal GhostJavaType(RuntimeContext context, string name, ITypeSymbol type) : base(context, name, type) { } - internal override Type TypeAsBaseType - { - get - { - if (typeAsBaseType == null) - typeAsBaseType = type.GetNestedType("__Interface"); + internal override ITypeSymbol TypeAsBaseType => typeAsBaseType ??= type.GetNestedType("__Interface"); - return typeAsBaseType; - } - } - - internal override FieldInfo GhostRefField - { - get - { - if (ghostRefField == null) - ghostRefField = type.GetField("__"); - - return ghostRefField; - } - } + internal override IFieldSymbol GhostRefField => ghostRefField ??= type.GetField("__"); internal override bool IsGhost => true; @@ -83,12 +57,12 @@ internal override FieldInfo GhostRefField internal override object GhostWrap(object obj) { - return type.GetMethod("Cast").Invoke(null, new object[] { obj }); + return type.GetMethod("Cast").AsReflection().Invoke(null, [obj]); } internal override object GhostUnwrap(object obj) { - return type.GetMethod("ToObject").Invoke(obj, new object[0]); + return type.GetMethod("ToObject").AsReflection().Invoke(obj, []); } #endif diff --git a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.RemappedJavaMethod.cs b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.RemappedJavaMethod.cs index 985828ac4..6202c7511 100644 --- a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.RemappedJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.RemappedJavaMethod.cs @@ -24,14 +24,11 @@ Jeroen Frijters using System.Diagnostics; using IKVM.Attributes; +using IKVM.CoreLib.Symbols; #if IMPORTER || EXPORTER -using IKVM.Reflection; using IKVM.Reflection.Emit; - -using Type = IKVM.Reflection.Type; #else -using System.Reflection; using System.Reflection.Emit; #endif @@ -44,9 +41,9 @@ partial class RuntimeManagedByteCodeJavaType sealed class RemappedJavaMethod : RuntimeSmartJavaMethod { - readonly MethodInfo mbHelper; + readonly IMethodSymbol mbHelper; #if !IMPORTER - readonly MethodInfo mbNonvirtualHelper; + readonly IMethodSymbol mbNonvirtualHelper; #endif /// @@ -62,7 +59,7 @@ sealed class RemappedJavaMethod : RuntimeSmartJavaMethod /// /// /// - internal RemappedJavaMethod(RuntimeJavaType declaringType, string name, string sig, MethodBase method, RuntimeJavaType returnType, RuntimeJavaType[] parameterTypes, ExModifiers modifiers, bool hideFromReflection, MethodInfo mbHelper, MethodInfo mbNonvirtualHelper) : + internal RemappedJavaMethod(RuntimeJavaType declaringType, string name, string sig, IMethodBaseSymbol method, RuntimeJavaType returnType, RuntimeJavaType[] parameterTypes, ExModifiers modifiers, bool hideFromReflection, IMethodSymbol mbHelper, IMethodSymbol mbNonvirtualHelper) : base(declaringType, name, sig, method, returnType, parameterTypes, modifiers.Modifiers, (modifiers.IsInternal ? MemberFlags.InternalAccess : MemberFlags.None) | (hideFromReflection ? MemberFlags.HideFromReflection : MemberFlags.None)) { this.mbHelper = mbHelper; @@ -76,7 +73,7 @@ internal RemappedJavaMethod(RuntimeJavaType declaringType, string name, string s protected override void CallImpl(CodeEmitter ilgen) { var mb = GetMethod(); - var mi = mb as MethodInfo; + var mi = mb as IMethodSymbol; if (mi != null) { if (!IsStatic && IsFinal) @@ -114,7 +111,7 @@ protected override void CallvirtImpl(CodeEmitter ilgen) protected override void NewobjImpl(CodeEmitter ilgen) { var mb = GetMethod(); - var mi = mb as MethodInfo; + var mi = mb as IMethodSymbol; if (mi != null) { Debug.Assert(mi.Name == "newhelper"); @@ -157,25 +154,27 @@ internal override object CreateInstance(object[] args) internal override object InvokeNonvirtualRemapped(object obj, object[] args) { var mi = mbNonvirtualHelper ?? mbHelper; - return mi.Invoke(null, ArrayUtil.Concat(obj, args)); + return mi.AsReflection().Invoke(null, ArrayUtil.Concat(obj, args)); } + #endif // !IMPORTER && !FIRST_PASS && !EXPORTER #if EMITTERS + internal override void EmitCallvirtReflect(CodeEmitter ilgen) { var mb = mbHelper ?? GetMethod(); ilgen.Emit(mb.IsStatic ? OpCodes.Call : OpCodes.Callvirt, mb); } + #endif // EMITTERS internal string GetGenericSignature() { - SignatureAttribute attr = DeclaringType.Context.AttributeHelper.GetSignature(mbHelper != null ? mbHelper : GetMethod()); + var attr = DeclaringType.Context.AttributeHelper.GetSignature(mbHelper != null ? mbHelper : GetMethod()); if (attr != null) - { return attr.Signature; - } + return null; } diff --git a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.RemappedJavaType.cs b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.RemappedJavaType.cs index 2f004376c..8e03fb335 100644 --- a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.RemappedJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.RemappedJavaType.cs @@ -25,6 +25,8 @@ Jeroen Frijters using System.Collections.Generic; using IKVM.Attributes; +using IKVM.CoreLib.Symbols; + #if IMPORTER || EXPORTER using IKVM.Reflection; @@ -44,7 +46,7 @@ partial class RuntimeManagedByteCodeJavaType internal sealed class RemappedJavaType : RuntimeManagedByteCodeJavaType { - readonly Type remappedType; + readonly ITypeSymbol remappedType; /// /// initializes a new instance. @@ -53,20 +55,25 @@ internal sealed class RemappedJavaType : RuntimeManagedByteCodeJavaType /// /// /// - internal RemappedJavaType(RuntimeContext context, string name, Type type) : + internal RemappedJavaType(RuntimeContext context, string name, ITypeSymbol type) : base(context, name, type) { var attr = Context.AttributeHelper.GetRemappedType(type) ?? throw new InvalidOperationException(); - remappedType = attr.Type; + remappedType = Context.Resolver.ResolveType(attr.Type); } - internal override Type TypeAsTBD => remappedType; + internal override ITypeSymbol TypeAsTBD => remappedType; internal override bool IsRemapped => true; protected override void LazyPublishMethods() { - const BindingFlags bindingFlags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance; + const System.Reflection.BindingFlags bindingFlags = + System.Reflection.BindingFlags.DeclaredOnly | + System.Reflection.BindingFlags.Public | + System.Reflection.BindingFlags.NonPublic | + System.Reflection.BindingFlags.Static | + System.Reflection.BindingFlags.Instance; var list = new List(); @@ -79,7 +86,7 @@ protected override void LazyPublishMethods() // if we're a remapped interface, we need to get the methods from the real interface if (remappedType.IsInterface) { - var nestedHelper = type.GetNestedType("__Helper", BindingFlags.Public | BindingFlags.Static); + var nestedHelper = type.GetNestedType("__Helper", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static); foreach (var m in Context.AttributeHelper.GetRemappedInterfaceMethods(type)) { var method = remappedType.GetMethod(m.MappedTo); @@ -104,7 +111,7 @@ protected override void LazyPublishMethods() SetMethods(list.ToArray()); } - private void AddMethod(List list, MethodBase method) + private void AddMethod(List list, IMethodBaseSymbol method) { var flags = Context.AttributeHelper.GetHideFromJavaFlags(method); if ((flags & HideFromJavaFlags.Code) == 0 && (remappedType.IsSealed || !method.Name.StartsWith("instancehelper_")) && (!remappedType.IsSealed || method.IsStatic)) @@ -114,39 +121,38 @@ private void AddMethod(List list, MethodBase method) protected override void LazyPublishFields() { var list = new List(); - var fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance); + var fields = type.GetFields(System.Reflection.BindingFlags.DeclaredOnly | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Instance); foreach (var field in fields) { - HideFromJavaFlags hideFromJavaFlags = Context.AttributeHelper.GetHideFromJavaFlags(field); + var hideFromJavaFlags = Context.AttributeHelper.GetHideFromJavaFlags(field); if ((hideFromJavaFlags & HideFromJavaFlags.Code) == 0) list.Add(CreateFieldWrapper(field, hideFromJavaFlags)); } + SetFields(list.ToArray()); } - RuntimeJavaMethod CreateRemappedMethodWrapper(MethodBase mb, HideFromJavaFlags hideFromJavaflags) + RuntimeJavaMethod CreateRemappedMethodWrapper(IMethodBaseSymbol mb, HideFromJavaFlags hideFromJavaflags) { var modifiers = Context.AttributeHelper.GetModifiers(mb, false); var flags = MemberFlags.None; GetNameSigFromMethodBase(mb, out var name, out var sig, out var retType, out var paramTypes, ref flags); - var mbHelper = mb as MethodInfo; + var mbHelper = mb as IMethodSymbol; var hideFromReflection = mbHelper != null && (hideFromJavaflags & HideFromJavaFlags.Reflection) != 0; - MethodInfo mbNonvirtualHelper = null; + IMethodSymbol mbNonvirtualHelper = null; if (!mb.IsStatic && !mb.IsConstructor) { - ParameterInfo[] parameters = mb.GetParameters(); - Type[] argTypes = new Type[parameters.Length + 1]; + var parameters = mb.GetParameters(); + var argTypes = new ITypeSymbol[parameters.Length + 1]; argTypes[0] = remappedType; for (int i = 0; i < parameters.Length; i++) - { argTypes[i + 1] = parameters[i].ParameterType; - } - MethodInfo helper = type.GetMethod("instancehelper_" + mb.Name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static, null, argTypes, null); + + var helper = type.GetMethod("instancehelper_" + mb.Name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static, null, argTypes, null); if (helper != null) - { mbHelper = helper; - } + mbNonvirtualHelper = type.GetMethod("nonvirtualhelper/" + mb.Name, BindingFlags.NonPublic | BindingFlags.Static, null, argTypes, null); } diff --git a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs index 82ee77df5..a0a349676 100644 --- a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs @@ -29,12 +29,20 @@ Jeroen Frijters using IKVM.Attributes; using IKVM.Runtime.Syntax; using IKVM.ByteCode; +using IKVM.CoreLib.Symbols; +using com.sun.org.apache.bcel.@internal.generic; +using System.Linq; + + + #if IMPORTER || EXPORTER using IKVM.Reflection; using IKVM.Reflection.Emit; using Type = IKVM.Reflection.Type; +using System.Runtime.Serialization.Formatters; + #else using System.Reflection; using System.Reflection.Emit; @@ -67,22 +75,16 @@ public RuntimeManagedByteCodeJavaTypeFactory(RuntimeContext context) /// /// /// - public RuntimeManagedByteCodeJavaType newInstance(string name, Type type) + public RuntimeManagedByteCodeJavaType newInstance(string name, ITypeSymbol type) { // TODO since ghost and remapped types can only exist in the core library assembly, we probably // should be able to remove the Type.IsDefined() tests in most cases if (type.IsValueType && context.AttributeHelper.IsGhostInterface(type)) - { return new RuntimeManagedByteCodeJavaType.GhostJavaType(context, name, type); - } else if (context.AttributeHelper.IsRemappedType(type)) - { return new RuntimeManagedByteCodeJavaType.RemappedJavaType(context, name, type); - } else - { return new RuntimeManagedByteCodeJavaType(context, name, type); - } } } @@ -93,11 +95,11 @@ public RuntimeManagedByteCodeJavaType newInstance(string name, Type type) internal partial class RuntimeManagedByteCodeJavaType : RuntimeJavaType { - readonly Type type; + readonly ITypeSymbol type; RuntimeJavaType baseTypeWrapper; volatile RuntimeJavaType[] interfaces; - MethodInfo clinitMethod; + IMethodSymbol clinitMethod; volatile bool clinitMethodSet; Modifiers reflectiveModifiers; @@ -107,7 +109,7 @@ internal partial class RuntimeManagedByteCodeJavaType : RuntimeJavaType /// /// /// - internal static JavaTypeName? GetName(RuntimeContext context, Type type) + internal static JavaTypeName? GetName(RuntimeContext context, ITypeSymbol type) { if (type.HasElementType) return null; @@ -132,7 +134,7 @@ internal partial class RuntimeManagedByteCodeJavaType : RuntimeJavaType return TypeNameUtil.Unescape(type.FullName); } - static RuntimeJavaType GetBaseTypeWrapper(RuntimeContext context, Type type) + static RuntimeJavaType GetBaseTypeWrapper(RuntimeContext context, ITypeSymbol type) { if (type.IsInterface || context.AttributeHelper.IsGhostInterface(type)) { @@ -148,7 +150,7 @@ static RuntimeJavaType GetBaseTypeWrapper(RuntimeContext context, Type type) var attr = context.AttributeHelper.GetRemappedType(type); if (attr != null) { - if (attr.Type == context.Types.Object) + if (context.Resolver.ResolveType(attr.Type) == context.Types.Object) return null; else return context.JavaBase.TypeOfJavaLangObject; @@ -188,10 +190,10 @@ public RuntimeManagedByteCodeJavaType(RuntimeContext context, ExModifiers exmod, /// /// /// - public RuntimeManagedByteCodeJavaType(RuntimeContext context, string name, Type type) : + public RuntimeManagedByteCodeJavaType(RuntimeContext context, string name, ITypeSymbol type) : this(context, GetModifiers(context, type), name) { - Debug.Assert(!(type is TypeBuilder)); + Debug.Assert(!(type.AsReflection() is TypeBuilder)); Debug.Assert(!type.Name.EndsWith("[]")); this.type = type; @@ -210,7 +212,7 @@ internal override RuntimeJavaType BaseTypeWrapper internal override RuntimeClassLoader ClassLoader => Context.AssemblyClassLoaderFactory.FromAssembly(type.Assembly); - static ExModifiers GetModifiers(RuntimeContext context, Type type) + static ExModifiers GetModifiers(RuntimeContext context, ITypeSymbol type) { ModifiersAttribute attr = context.AttributeHelper.GetModifiersAttribute(type); if (attr != null) @@ -252,14 +254,22 @@ internal override bool HasStaticInitializer { try { - clinitMethod = type.GetMethod("__", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); + clinitMethod = type.GetMethod("__", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic); } #if IMPORTER - catch (IKVM.Reflection.MissingMemberException) { } + catch (IKVM.Reflection.MissingMemberException) + { + + } #endif - finally { } + finally + { + + } + clinitMethodSet = true; } + return clinitMethod != null; } } @@ -326,19 +336,19 @@ private RuntimeJavaType[] GetInterfaces() return interfaceWrappers; } - private bool IsNestedTypeAnonymousOrLocalClass(Type type) + private bool IsNestedTypeAnonymousOrLocalClass(ITypeSymbol type) { - switch (type.Attributes & (TypeAttributes.SpecialName | TypeAttributes.VisibilityMask)) + switch (type.Attributes & (System.Reflection.TypeAttributes.SpecialName | System.Reflection.TypeAttributes.VisibilityMask)) { - case TypeAttributes.SpecialName | TypeAttributes.NestedPublic: - case TypeAttributes.SpecialName | TypeAttributes.NestedAssembly: + case System.Reflection.TypeAttributes.SpecialName | System.Reflection.TypeAttributes.NestedPublic: + case System.Reflection.TypeAttributes.SpecialName | System.Reflection.TypeAttributes.NestedAssembly: return Context.AttributeHelper.HasEnclosingMethodAttribute(type); default: return false; } } - private bool IsAnnotationAttribute(Type type) + private bool IsAnnotationAttribute(ITypeSymbol type) { return type.Name.EndsWith("Attribute", StringComparison.Ordinal) && type.IsClass && type.BaseType.FullName == "ikvm.internal.AnnotationAttributeBase"; } @@ -348,7 +358,8 @@ internal override RuntimeJavaType[] InnerClasses get { var wrappers = new List(); - foreach (var nested in type.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly)) + + foreach (var nested in type.GetNestedTypes(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.DeclaredOnly)) { if (IsAnnotationAttribute(nested)) { @@ -368,10 +379,9 @@ internal override RuntimeJavaType[] InnerClasses wrappers.Add(Context.ClassLoaderFactory.GetJavaTypeFromType(nested)); } } + foreach (string s in Context.AttributeHelper.GetNonNestedInnerClasses(type)) - { wrappers.Add(ClassLoader.LoadClassByName(s)); - } return wrappers.ToArray(); } @@ -382,19 +392,15 @@ internal override RuntimeJavaType DeclaringTypeWrapper get { if (IsNestedTypeAnonymousOrLocalClass(type)) - { return null; - } - Type declaringType = type.DeclaringType; + + var declaringType = type.DeclaringType; if (declaringType != null) - { return Context.ClassLoaderFactory.GetJavaTypeFromType(declaringType); - } - string decl = Context.AttributeHelper.GetNonNestedOuterClasses(type); + + var decl = Context.AttributeHelper.GetNonNestedOuterClasses(type); if (decl != null) - { return ClassLoader.LoadClassByName(decl); - } return null; } @@ -407,14 +413,12 @@ private static bool IsAnonymousClassName(string name) if (index > 1 && index < name.Length) { while (index < name.Length) - { if ("0123456789".IndexOf(name[index++]) == -1) - { return false; - } - } + return true; } + return false; } @@ -423,14 +427,14 @@ private static bool IsAnonymousClassName(string name) // The heuristics are based on javac from Java 7. internal static Modifiers PredictReflectiveModifiers(RuntimeJavaType tw) { - Modifiers modifiers = Modifiers.Static | (tw.Modifiers & (Modifiers.Public | Modifiers.Abstract | Modifiers.Interface)); + var modifiers = Modifiers.Static | (tw.Modifiers & (Modifiers.Public | Modifiers.Abstract | Modifiers.Interface)); + // javac marks anonymous classes as final, but the InnerClasses attribute access_flags does not have the ACC_FINAL flag set if (tw.IsFinal && !IsAnonymousClassName(tw.Name)) - { modifiers |= Modifiers.Final; - } + // javac uses the this$0 field to store the outer instance reference for non-static inner classes - foreach (RuntimeJavaField fw in tw.GetFields()) + foreach (var fw in tw.GetFields()) { if (fw.Name == "this$0") { @@ -438,6 +442,7 @@ internal static Modifiers PredictReflectiveModifiers(RuntimeJavaType tw) break; } } + return modifiers; } @@ -448,7 +453,8 @@ internal override Modifiers ReflectiveModifiers if (reflectiveModifiers == 0) { Modifiers mods; - InnerClassAttribute attr = Context.AttributeHelper.GetInnerClass(type); + var attr = Context.AttributeHelper.GetInnerClass(type); + if (attr != null) { // the mask comes from RECOGNIZED_INNER_CLASS_MODIFIERS in src/hotspot/share/vm/classfile/classFileParser.cpp @@ -465,17 +471,18 @@ internal override Modifiers ReflectiveModifiers // (minus ACC_SUPER) mods = Modifiers & (Modifiers)0x7611; } + if (IsInterface) - { mods |= Modifiers.Abstract; - } + reflectiveModifiers = mods; } + return reflectiveModifiers; } } - internal override Type TypeAsBaseType + internal override ITypeSymbol TypeAsBaseType { get { @@ -483,7 +490,7 @@ internal override Type TypeAsBaseType } } - private void SigTypePatchUp(string sigtype, ref RuntimeJavaType type) + void SigTypePatchUp(string sigtype, ref RuntimeJavaType type) { if (sigtype != type.SigName) { @@ -497,9 +504,7 @@ private void SigTypePatchUp(string sigtype, ref RuntimeJavaType type) { type = Context.ManagedJavaTypeFactory.GetJavaTypeFromManagedType(type.TypeAsTBD); if (sigtype != type.SigName) - { throw new InvalidOperationException(); - } } else if (type.IsNonPrimitiveValueType) { @@ -511,12 +516,11 @@ private void SigTypePatchUp(string sigtype, ref RuntimeJavaType type) else { if (sigtype[0] == 'L') - { sigtype = sigtype.Substring(1, sigtype.Length - 2); - } + try { - RuntimeJavaType tw = ClassLoader.TryLoadClassByName(sigtype); + var tw = ClassLoader.TryLoadClassByName(sigtype); if (tw != null && tw.IsRemapped) { type = tw; @@ -525,15 +529,17 @@ private void SigTypePatchUp(string sigtype, ref RuntimeJavaType type) } catch (RetargetableJavaException) { + } + type = new RuntimeUnloadableJavaType(Context, sigtype); } } } - private static void ParseSig(string sig, out string[] sigparam, out string sigret) + static void ParseSig(string sig, out string[] sigparam, out string sigret) { - List list = new List(); + var list = new List(); int pos = 1; for (; ; ) { @@ -576,7 +582,7 @@ private static void ParseSig(string sig, out string[] sigparam, out string sigre } } - private static bool IsCallerID(RuntimeContext context, Type type) + static bool IsCallerID(RuntimeContext context, ITypeSymbol type) { #if EXPORTER return type.FullName == "ikvm.internal.CallerID"; @@ -585,27 +591,19 @@ private static bool IsCallerID(RuntimeContext context, Type type) #endif } - private static bool IsCallerSensitive(MethodBase mb) + static bool IsCallerSensitive(IMethodBaseSymbol mb) { -#if FIRST_PASS - return false; -#elif IMPORTER || EXPORTER - foreach (CustomAttributeData cad in mb.GetCustomAttributesData()) - { + foreach (var cad in mb.GetCustomAttributes()) if (cad.AttributeType.FullName == "sun.reflect.CallerSensitiveAttribute") - { return true; - } - } + return false; -#else - return mb.IsDefined(typeof(global::sun.reflect.CallerSensitiveAttribute), false); -#endif } - private void GetNameSigFromMethodBase(MethodBase method, out string name, out string sig, out RuntimeJavaType retType, out RuntimeJavaType[] paramTypes, ref MemberFlags flags) + void GetNameSigFromMethodBase(IMethodBaseSymbol method, out string name, out string sig, out RuntimeJavaType retType, out RuntimeJavaType[] paramTypes, ref MemberFlags flags) { - retType = method is ConstructorInfo ? Context.PrimitiveJavaTypeFactory.VOID : GetParameterTypeWrapper(Context, ((MethodInfo)method).ReturnParameter); + retType = method is IConstructorSymbol ? Context.PrimitiveJavaTypeFactory.VOID : GetParameterTypeWrapper(Context, ((IMethodSymbol)method).ReturnParameter); + var parameters = method.GetParameters(); int len = parameters.Length; if (len > 0 && IsCallerID(Context, parameters[len - 1].ParameterType) && ClassLoader == Context.ClassLoaderFactory.GetBootstrapClassLoader() && IsCallerSensitive(method)) @@ -613,6 +611,7 @@ private void GetNameSigFromMethodBase(MethodBase method, out string name, out st len--; flags |= MemberFlags.CallerID; } + paramTypes = new RuntimeJavaType[len]; for (int i = 0; i < len; i++) paramTypes[i] = GetParameterTypeWrapper(Context, parameters[i]); @@ -626,6 +625,7 @@ private void GetNameSigFromMethodBase(MethodBase method, out string name, out st // HACK newhelper methods have a return type, but it should be void if (name == "") retType = Context.PrimitiveJavaTypeFactory.VOID; + SigTypePatchUp(sigret, ref retType); // if we have a remapped method, the paramTypes array contains an additional entry for "this" so we have // to remove that @@ -638,7 +638,7 @@ private void GetNameSigFromMethodBase(MethodBase method, out string name, out st } else { - if (method is ConstructorInfo) + if (method.IsConstructor) { name = method.IsStatic ? "" : ""; } @@ -652,9 +652,7 @@ private void GetNameSigFromMethodBase(MethodBase method, out string name, out st } if (method.IsSpecialName && method.Name.StartsWith(NamePrefix.DefaultMethod, StringComparison.Ordinal)) - { paramTypes = ArrayUtil.DropFirst(paramTypes); - } var sb = new System.Text.StringBuilder("("); foreach (RuntimeJavaType tw in paramTypes) @@ -667,7 +665,7 @@ private void GetNameSigFromMethodBase(MethodBase method, out string name, out st protected override void LazyPublishMethods() { - const BindingFlags flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance; + const System.Reflection.BindingFlags flags = System.Reflection.BindingFlags.DeclaredOnly | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Instance; var isDelegate = type.BaseType == Context.Types.MulticastDelegate; var methods = new List(); @@ -685,7 +683,7 @@ protected override void LazyPublishMethods() if (type.IsInterface && (type.IsPublic || type.IsNestedPublic)) { - var privateInterfaceMethods = type.GetNestedType(NestedTypeName.PrivateInterfaceMethods, BindingFlags.NonPublic); + var privateInterfaceMethods = type.GetNestedType(NestedTypeName.PrivateInterfaceMethods, System.Reflection.BindingFlags.NonPublic); if (privateInterfaceMethods != null) AddMethods(privateInterfaceMethods.GetMethods(flags), methods); } @@ -693,20 +691,18 @@ protected override void LazyPublishMethods() SetMethods(methods.ToArray()); } - private void AddMethods(MethodInfo[] add, List methods) + private void AddMethods(IMethodSymbol[] add, List methods) { foreach (var method in add) AddMethodOrConstructor(method, Context.AttributeHelper.GetHideFromJavaFlags(method), methods); } - private void AddMethodOrConstructor(MethodBase method, HideFromJavaFlags hideFromJavaFlags, List methods) + private void AddMethodOrConstructor(IMethodBaseSymbol method, HideFromJavaFlags hideFromJavaFlags, List methods) { if ((hideFromJavaFlags & HideFromJavaFlags.Code) != 0) { if (method.Name.StartsWith(NamePrefix.Incomplete, StringComparison.Ordinal)) - { SetHasIncompleteInterfaceImplementation(); - } } else { @@ -716,35 +712,36 @@ private void AddMethodOrConstructor(MethodBase method, HideFromJavaFlags hideFro } else { - var mi = method as MethodInfo; + var mi = method as IMethodSymbol; var hideFromReflection = mi != null && (hideFromJavaFlags & HideFromJavaFlags.Reflection) != 0; var flags = hideFromReflection ? MemberFlags.HideFromReflection : MemberFlags.None; GetNameSigFromMethodBase(method, out var name, out var sig, out var retType, out var paramTypes, ref flags); + var mods = Context.AttributeHelper.GetModifiers(method, false); if (mods.IsInternal) - { flags |= MemberFlags.InternalAccess; - } + if (hideFromReflection && name.StartsWith(NamePrefix.AccessStub, StringComparison.Ordinal)) { - int id = Int32.Parse(name.Substring(NamePrefix.AccessStub.Length, name.IndexOf('|', NamePrefix.AccessStub.Length) - NamePrefix.AccessStub.Length)); + var id = int.Parse(name.Substring(NamePrefix.AccessStub.Length, name.IndexOf('|', NamePrefix.AccessStub.Length) - NamePrefix.AccessStub.Length)); name = name.Substring(name.IndexOf('|', NamePrefix.AccessStub.Length) + 1); flags |= MemberFlags.AccessStub; - MethodInfo nonvirt = type.GetMethod(NamePrefix.NonVirtual + id, BindingFlags.NonPublic | BindingFlags.DeclaredOnly | BindingFlags.Instance); + + var nonvirt = type.GetMethod(NamePrefix.NonVirtual + id, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.DeclaredOnly | System.Reflection.BindingFlags.Instance); methods.Add(new RuntimeAccessStubJavaMethod(this, name, sig, mi, mi, nonvirt ?? mi, retType, paramTypes, mods.Modifiers & ~Modifiers.Final, flags)); return; } - MethodInfo impl; + IMethodSymbol impl; RuntimeJavaMethod mw; if (IsGhost && (mods.Modifiers & (Modifiers.Static | Modifiers.Private)) == 0) { - var types = new Type[paramTypes.Length]; + var types = new ITypeSymbol[paramTypes.Length]; for (int i = 0; i < types.Length; i++) types[i] = paramTypes[i].TypeAsSignatureType; var ifmethod = TypeAsBaseType.GetMethod(method.Name, types); - mw = new RuntimeGhostJavaMethod(this, name, sig, ifmethod, (MethodInfo)method, retType, paramTypes, mods.Modifiers, flags); + mw = new RuntimeGhostJavaMethod(this, name, sig, ifmethod, (IMethodSymbol)method, retType, paramTypes, mods.Modifiers, flags); if (!mw.IsAbstract) ((RuntimeGhostJavaMethod)mw).SetDefaultImpl(TypeAsSignatureType.GetMethod(NamePrefix.DefaultMethod + method.Name, types)); } @@ -760,58 +757,57 @@ private void AddMethodOrConstructor(MethodBase method, HideFromJavaFlags hideFro { mw = new RuntimeTypicalJavaMethod(this, name, sig, method, retType, paramTypes, mods.Modifiers, flags); } + if (mw.HasNonPublicTypeInSignature) { if (mi != null) { - MethodInfo stubVirt; - MethodInfo stubNonVirt; - if (GetType2AccessStubs(name, sig, out stubVirt, out stubNonVirt)) + if (GetType2AccessStubs(name, sig, out var stubVirt, out var stubNonVirt)) { mw = new RuntimeAccessStubJavaMethod(this, name, sig, mi, stubVirt, stubNonVirt ?? stubVirt, retType, paramTypes, mw.Modifiers, flags); } } else { - ConstructorInfo stub; - if (GetType2AccessStub(sig, out stub)) + if (GetType2AccessStub(sig, out var stub)) { - mw = new RuntimeConstructorAccessStubJavaMethod(this, sig, (ConstructorInfo)method, stub, paramTypes, mw.Modifiers, flags); + mw = new RuntimeConstructorAccessStubJavaMethod(this, sig, (IConstructorSymbol)method, stub, paramTypes, mw.Modifiers, flags); } } } + methods.Add(mw); } } } - MethodInfo GetDefaultInterfaceMethodImpl(MethodInfo method, string expectedSig) + IMethodSymbol GetDefaultInterfaceMethodImpl(IMethodSymbol method, string expectedSig) { - foreach (MethodInfo candidate in method.DeclaringType.GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly)) + foreach (var candidate in method.DeclaringType.GetMethods(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.DeclaredOnly)) { - if (candidate.IsSpecialName - && candidate.Name.StartsWith(NamePrefix.DefaultMethod, StringComparison.Ordinal) - && candidate.Name.Length == method.Name.Length + NamePrefix.DefaultMethod.Length - && candidate.Name.EndsWith(method.Name, StringComparison.Ordinal)) + if (candidate.IsSpecialName && + candidate.Name.StartsWith(NamePrefix.DefaultMethod, StringComparison.Ordinal) && + candidate.Name.Length == method.Name.Length + NamePrefix.DefaultMethod.Length && + candidate.Name.EndsWith(method.Name, StringComparison.Ordinal)) { - string name; - string sig; - RuntimeJavaType retType; - RuntimeJavaType[] paramTypes; - MemberFlags flags = MemberFlags.None; - GetNameSigFromMethodBase(candidate, out name, out sig, out retType, out paramTypes, ref flags); + var flags = MemberFlags.None; + GetNameSigFromMethodBase(candidate, out _, out var sig, out _, out _, ref flags); if (sig == expectedSig) - { return candidate; - } } } + return null; } - bool GetType2AccessStubs(string name, string sig, out MethodInfo stubVirt, out MethodInfo stubNonVirt) + bool GetType2AccessStubs(string name, string sig, out IMethodSymbol stubVirt, out IMethodSymbol stubNonVirt) { - const BindingFlags flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance; + const System.Reflection.BindingFlags flags = + System.Reflection.BindingFlags.DeclaredOnly | + System.Reflection.BindingFlags.Public | + System.Reflection.BindingFlags.NonPublic | + System.Reflection.BindingFlags.Static | + System.Reflection.BindingFlags.Instance; stubVirt = null; stubNonVirt = null; @@ -823,13 +819,9 @@ bool GetType2AccessStubs(string name, string sig, out MethodInfo stubVirt, out M if (attr != null && attr.Name == name && attr.Sig == sig) { if (method.Name.StartsWith(NamePrefix.NonVirtual, StringComparison.Ordinal)) - { stubNonVirt = method; - } else - { stubVirt = method; - } } } } @@ -837,9 +829,13 @@ bool GetType2AccessStubs(string name, string sig, out MethodInfo stubVirt, out M return stubVirt != null; } - bool GetType2AccessStub(string sig, out ConstructorInfo stub) + bool GetType2AccessStub(string sig, out IConstructorSymbol stub) { - const BindingFlags flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance; + const System.Reflection.BindingFlags flags = + System.Reflection.BindingFlags.DeclaredOnly | + System.Reflection.BindingFlags.Public | + System.Reflection.BindingFlags.NonPublic | + System.Reflection.BindingFlags.Instance; stub = null; foreach (var ctor in type.GetConstructors(flags)) @@ -848,23 +844,26 @@ bool GetType2AccessStub(string sig, out ConstructorInfo stub) { var attr = Context.AttributeHelper.GetNameSig(ctor); if (attr != null && attr.Sig == sig) - { stub = ctor; - } } } return stub != null; } - static int SortFieldByToken(FieldInfo field1, FieldInfo field2) + static int SortFieldByToken(IFieldSymbol field1, IFieldSymbol field2) { return field1.MetadataToken.CompareTo(field2.MetadataToken); } protected override void LazyPublishFields() { - const BindingFlags flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance; + const System.Reflection.BindingFlags flags = + System.Reflection.BindingFlags.DeclaredOnly | + System.Reflection.BindingFlags.Public | + System.Reflection.BindingFlags.NonPublic | + System.Reflection.BindingFlags.Static | + System.Reflection.BindingFlags.Instance; var fields = new List(); var rawfields = type.GetFields(flags); @@ -918,7 +917,7 @@ static bool MatchTypes(RuntimeJavaType tw1, RuntimeJavaType tw2) return tw1 == tw2 || (tw1.IsUnloadable && tw2.IsUnloadable && tw1.Name == tw2.Name); } - void AddPropertyFieldWrapper(List fields, PropertyInfo property, FieldInfo field) + void AddPropertyFieldWrapper(List fields, IPropertySymbol property, IFieldSymbol field) { // NOTE explictly defined properties (in map.xml) are decorated with HideFromJava, // so we don't need to worry about them here @@ -940,13 +939,13 @@ void AddPropertyFieldWrapper(List fields, PropertyInfo propert } } - static RuntimeJavaType TypeWrapperFromModOpt(RuntimeContext context, Type[] modopt) + static RuntimeJavaType TypeWrapperFromModOpt(RuntimeContext context, ITypeSymbol[] modopt) { int rank = 0; RuntimeJavaType tw = null; foreach (var type in modopt) { - if (type == context.Resolver.ResolveRuntimeType(typeof(IKVM.Attributes.AccessStub).FullName).AsReflection()) + if (type == context.Resolver.ResolveRuntimeType(typeof(IKVM.Attributes.AccessStub).FullName)) { // ignore } @@ -974,17 +973,17 @@ static RuntimeJavaType TypeWrapperFromModOpt(RuntimeContext context, Type[] modo return tw; } - RuntimeJavaType GetPropertyTypeWrapper(PropertyInfo property) + RuntimeJavaType GetPropertyTypeWrapper(IPropertySymbol property) { return TypeWrapperFromModOpt(Context, property.GetOptionalCustomModifiers()) ?? Context.ClassLoaderFactory.GetJavaTypeFromType(property.PropertyType); } - internal static RuntimeJavaType GetFieldTypeWrapper(RuntimeContext context, FieldInfo field) + internal static RuntimeJavaType GetFieldTypeWrapper(RuntimeContext context, IFieldSymbol field) { return TypeWrapperFromModOpt(context, field.GetOptionalCustomModifiers()) ?? context.ClassLoaderFactory.GetJavaTypeFromType(field.FieldType); } - internal static RuntimeJavaType GetParameterTypeWrapper(RuntimeContext context, ParameterInfo param) + internal static RuntimeJavaType GetParameterTypeWrapper(RuntimeContext context, IParameterSymbol param) { var tw = TypeWrapperFromModOpt(context, param.GetOptionalCustomModifiers()); if (tw != null) @@ -1000,7 +999,7 @@ internal static RuntimeJavaType GetParameterTypeWrapper(RuntimeContext context, return context.ClassLoaderFactory.GetJavaTypeFromType(parameterType); } - RuntimeJavaField CreateFieldWrapper(FieldInfo field, HideFromJavaFlags hideFromJavaFlags) + RuntimeJavaField CreateFieldWrapper(IFieldSymbol field, HideFromJavaFlags hideFromJavaFlags) { var modifiers = Context.AttributeHelper.GetModifiers(field, false); var type = GetFieldTypeWrapper(Context, field); @@ -1012,14 +1011,13 @@ RuntimeJavaField CreateFieldWrapper(FieldInfo field, HideFromJavaFlags hideFromJ if (field.IsLiteral) { var flags = MemberFlags.None; + if ((hideFromJavaFlags & HideFromJavaFlags.Reflection) != 0) - { flags |= MemberFlags.HideFromReflection; - } + if (modifiers.IsInternal) - { flags |= MemberFlags.InternalAccess; - } + return new RuntimeConstantJavaField(this, type, name, type.SigName, modifiers.Modifiers, field, null, flags); } else @@ -1028,7 +1026,7 @@ RuntimeJavaField CreateFieldWrapper(FieldInfo field, HideFromJavaFlags hideFromJ } } - internal override Type TypeAsTBD => type; + internal override ITypeSymbol TypeAsTBD => type; internal override bool IsMapUnsafeException => Context.AttributeHelper.IsExceptionIsUnsafeForMapping(type); @@ -1121,9 +1119,18 @@ internal override string[] GetEnclosingMethod() return null; } + object[] CastArray(CustomAttribute[] l) + { + var a = new object[l.Length]; + for (int i = 0; i < l.Length; i++) + a[i] = l[i]; + + return a; + } + internal override object[] GetDeclaredAnnotations() { - return type.GetCustomAttributes(false); + return CastArray(type.GetCustomAttribute(false)); } internal override object[] GetMethodAnnotations(RuntimeJavaMethod mw) @@ -1135,7 +1142,7 @@ internal override object[] GetMethodAnnotations(RuntimeJavaMethod mw) return null; } - return mb.GetCustomAttributes(false); + return CastArray(mb.GetCustomAttributes(false)); } internal override object[][] GetParameterAnnotations(RuntimeJavaMethod mw) @@ -1158,7 +1165,7 @@ internal override object[][] GetParameterAnnotations(RuntimeJavaMethod mw) var attribs = new object[parameters.Length - skip - skipEnd][]; for (int i = skip; i < parameters.Length - skipEnd; i++) - attribs[i - skip] = parameters[i].GetCustomAttributes(false); + attribs[i - skip] = CastArray(parameters[i].GetCustomAttributes(false)); return attribs; } @@ -1167,10 +1174,10 @@ internal override object[] GetFieldAnnotations(RuntimeJavaField fw) { var field = fw.GetField(); if (field != null) - return field.GetCustomAttributes(false); + return CastArray(field.GetCustomAttributes(false)); if (fw is RuntimeManagedByteCodePropertyJavaField prop) - return prop.GetProperty().GetCustomAttributes(false); + return CastArray(prop.GetProperty().GetCustomAttributes(false)); return Array.Empty(); } @@ -1181,17 +1188,17 @@ internal sealed class CompiledAnnotation : Annotation { readonly RuntimeContext context; - readonly ConstructorInfo constructor; + readonly IConstructorSymbol constructor; /// /// Initializes a new instance. /// /// /// - internal CompiledAnnotation(RuntimeContext context, Type type) + internal CompiledAnnotation(RuntimeContext context, ITypeSymbol type) { this.context = context ?? throw new ArgumentNullException(nameof(context)); - constructor = type.GetConstructor(new Type[] { context.Resolver.ResolveCoreType(typeof(object).FullName).MakeArrayType().AsReflection() }); + constructor = type.GetConstructor(new ITypeSymbol[] { context.Resolver.ResolveCoreType(typeof(object).FullName).MakeArrayType() }); } private CustomAttributeBuilder MakeCustomAttributeBuilder(RuntimeClassLoader loader, object annotation) @@ -1247,11 +1254,11 @@ internal override Annotation Annotation } } - internal override Type EnumType + internal override ITypeSymbol EnumType { get { - if ((this.Modifiers & Modifiers.Enum) != 0) + if ((Modifiers & Modifiers.Enum) != 0) return type.GetNestedType("__Enum"); return null; @@ -1262,9 +1269,9 @@ internal override Type EnumType internal override string GetSourceFileName() { - var attr = type.GetCustomAttributes(typeof(SourceFileAttribute), false); - if (attr.Length == 1) - return ((SourceFileAttribute)attr[0]).SourceFile; + var attr = type.GetCustomAttribute(Context.Resolver.ResolveType(typeof(SourceFileAttribute))); + if (attr != null && attr.Value.ConstructorArguments.Length > 0) + return (string)attr.Value.ConstructorArguments[0].Value; if (DeclaringTypeWrapper != null) return DeclaringTypeWrapper.GetSourceFileName(); @@ -1272,7 +1279,7 @@ internal override string GetSourceFileName() if (IsNestedTypeAnonymousOrLocalClass(type)) return Context.ClassLoaderFactory.GetJavaTypeFromType(type.DeclaringType).GetSourceFileName(); - if (type.Module.IsDefined(typeof(SourceFileAttribute), false)) + if (type.Module.IsDefined(Context.Resolver.ResolveType(typeof(SourceFileAttribute)), false)) return type.Name + ".java"; return null; @@ -1280,9 +1287,9 @@ internal override string GetSourceFileName() internal override int GetSourceLineNumber(MethodBase mb, int ilOffset) { - var attr = mb.GetCustomAttributes(typeof(LineNumberTableAttribute), false); - if (attr.Length == 1) - return ((LineNumberTableAttribute)attr[0]).GetLineNumber(ilOffset); + var attr = type.GetCustomAttribute(Context.Resolver.ResolveType(typeof(LineNumberTableAttribute))); + if (attr != null && attr.Value.Constructor != null) + return ((LineNumberTableAttribute)attr.Value.Constructor.AsReflection().Invoke(attr.Value.ConstructorArguments.Cast().ToArray())).GetLineNumber(ilOffset); return -1; } @@ -1305,13 +1312,13 @@ internal override byte[] GetRawTypeAnnotations() internal override byte[] GetMethodRawTypeAnnotations(RuntimeJavaMethod mw) { - MethodBase mb = mw.GetMethod(); + var mb = mw.GetMethod(); return mb == null ? null : Context.AttributeHelper.GetRuntimeVisibleTypeAnnotations(mb); } internal override byte[] GetFieldRawTypeAnnotations(RuntimeJavaField fw) { - FieldInfo fi = fw.GetField(); + var fi = fw.GetField(); return fi == null ? null : Context.AttributeHelper.GetRuntimeVisibleTypeAnnotations(fi); } diff --git a/src/IKVM.Runtime/RuntimeManagedByteCodePropertyJavaField.cs b/src/IKVM.Runtime/RuntimeManagedByteCodePropertyJavaField.cs index 80611d28c..87f276f30 100644 --- a/src/IKVM.Runtime/RuntimeManagedByteCodePropertyJavaField.cs +++ b/src/IKVM.Runtime/RuntimeManagedByteCodePropertyJavaField.cs @@ -21,6 +21,7 @@ Jeroen Frijters jeroen@frijters.net */ +using IKVM.CoreLib.Symbols; #if IMPORTER || EXPORTER using IKVM.Reflection; @@ -41,7 +42,7 @@ namespace IKVM.Runtime sealed class RuntimeManagedByteCodePropertyJavaField : RuntimeJavaField { - readonly PropertyInfo property; + readonly IPropertySymbol property; /// /// Initializes a new instance. @@ -49,13 +50,13 @@ sealed class RuntimeManagedByteCodePropertyJavaField : RuntimeJavaField /// /// /// - internal RuntimeManagedByteCodePropertyJavaField(RuntimeJavaType declaringType, PropertyInfo property, ExModifiers modifiers) : + internal RuntimeManagedByteCodePropertyJavaField(RuntimeJavaType declaringType, IPropertySymbol property, ExModifiers modifiers) : base(declaringType, declaringType.Context.ClassLoaderFactory.GetJavaTypeFromType(property.PropertyType), property.Name, declaringType.Context.ClassLoaderFactory.GetJavaTypeFromType(property.PropertyType).SigName, modifiers, null) { this.property = property; } - internal PropertyInfo GetProperty() + internal IPropertySymbol GetProperty() { return property; } @@ -111,7 +112,7 @@ internal override object GetValue(object obj) if (getter == null) throw new java.lang.NoSuchMethodError(); - return getter.Invoke(obj, new object[0]); + return getter.AsReflection().Invoke(obj, []); } internal override void SetValue(object obj, object value) @@ -120,7 +121,7 @@ internal override void SetValue(object obj, object value) if (setter == null) throw new java.lang.NoSuchMethodError(); - setter.Invoke(obj, new object[] { value }); + setter.AsReflection().Invoke(obj, new object[] { value }); } #endif diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.MultipleAnnotationJavaType.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.MultipleAnnotationJavaType.cs index 347bde315..b96ed3f2d 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.MultipleAnnotationJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.MultipleAnnotationJavaType.cs @@ -104,7 +104,7 @@ static object[] UnwrapArray(object annotation) } } - return new object[0]; + return []; } internal override void Apply(RuntimeClassLoader loader, MethodBuilder mb, object annotation) diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.cs index 9bd4613d3..a4867ea4d 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.cs @@ -25,6 +25,8 @@ Jeroen Frijters using System.Collections.Generic; using IKVM.CoreLib.Diagnostics; +using IKVM.CoreLib.Symbols; + #if IMPORTER || EXPORTER using IKVM.Reflection; @@ -54,8 +56,8 @@ sealed partial class RuntimeManagedJavaType sealed partial class AttributeAnnotationJavaType : AttributeAnnotationJavaTypeBase { - readonly Type fakeType; - readonly Type attributeType; + readonly ITypeSymbol fakeType; + readonly ITypeSymbol attributeType; volatile RuntimeJavaType[] innerClasses; /// @@ -63,21 +65,21 @@ sealed partial class AttributeAnnotationJavaType : AttributeAnnotationJavaTypeBa /// /// /// - internal AttributeAnnotationJavaType(RuntimeContext context, string name, Type attributeType) : + internal AttributeAnnotationJavaType(RuntimeContext context, string name, ITypeSymbol attributeType) : base(context, name) { #if IMPORTER || EXPORTER this.fakeType = context.FakeTypes.GetAttributeType(attributeType); #elif !FIRST_PASS - this.fakeType = typeof(ikvm.@internal.AttributeAnnotation<>).MakeGenericType(attributeType); + this.fakeType = context.Resolver.ResolveType(typeof(ikvm.@internal.AttributeAnnotation<>)).MakeGenericType(attributeType); #endif this.attributeType = attributeType; } - static bool IsSupportedType(RuntimeContext context, Type type) + static bool IsSupportedType(RuntimeContext context, ITypeSymbol type) { // Java annotations only support one-dimensional arrays - if (ReflectUtil.IsVector(type)) + if (type.IsSZArray) type = type.GetElementType(); return type == context.Types.String @@ -93,27 +95,27 @@ static bool IsSupportedType(RuntimeContext context, Type type) || type.IsEnum; } - internal static void GetConstructors(RuntimeContext context, Type type, out ConstructorInfo defCtor, out ConstructorInfo singleOneArgCtor) + internal static void GetConstructors(RuntimeContext context, ITypeSymbol type, out IConstructorSymbol defCtor, out IConstructorSymbol singleOneArgCtor) { defCtor = null; int oneArgCtorCount = 0; - ConstructorInfo oneArgCtor = null; - ConstructorInfo[] constructors = type.GetConstructors(BindingFlags.Public | BindingFlags.Instance); + IConstructorSymbol oneArgCtor = null; + var constructors = type.GetConstructors(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance); // HACK we have a special rule to make some additional custom attributes from mscorlib usable: // Attributes that have two constructors, one an enum and another one taking a byte, short or int, // we only expose the enum constructor. if (constructors.Length == 2 && type.Assembly == context.Types.Object.Assembly) { - ParameterInfo[] p0 = constructors[0].GetParameters(); - ParameterInfo[] p1 = constructors[1].GetParameters(); + var p0 = constructors[0].GetParameters(); + var p1 = constructors[1].GetParameters(); if (p0.Length == 1 && p1.Length == 1) { - Type t0 = p0[0].ParameterType; - Type t1 = p1[0].ParameterType; + var t0 = p0[0].ParameterType; + var t1 = p1[0].ParameterType; bool swapped = false; if (t1.IsEnum) { - Type tmp = t0; + var tmp = t0; t0 = t1; t1 = tmp; swapped = true; @@ -137,9 +139,9 @@ internal static void GetConstructors(RuntimeContext context, Type type, out Cons { if (type.FullName == "System.Runtime.CompilerServices.MethodImplAttribute") { - foreach (ConstructorInfo ci in constructors) + foreach (var ci in constructors) { - ParameterInfo[] p = ci.GetParameters(); + var p = ci.GetParameters(); if (p.Length == 1 && p[0].ParameterType.IsEnum) { singleOneArgCtor = ci; @@ -149,9 +151,9 @@ internal static void GetConstructors(RuntimeContext context, Type type, out Cons } } - foreach (ConstructorInfo ci in constructors) + foreach (var ci in constructors) { - ParameterInfo[] args = ci.GetParameters(); + var args = ci.GetParameters(); if (args.Length == 0) { defCtor = ci; @@ -185,13 +187,13 @@ sealed class AttributeAnnotationJavaMethod : DynamicOnlyJavaMethod /// /// /// - internal AttributeAnnotationJavaMethod(AttributeAnnotationJavaType tw, string name, Type type, bool optional) : + internal AttributeAnnotationJavaMethod(AttributeAnnotationJavaType tw, string name, ITypeSymbol type, bool optional) : this(tw, name, MapType(tw.Context, type, false), optional) { } - static RuntimeJavaType MapType(RuntimeContext context, Type type, bool isArray) + static RuntimeJavaType MapType(RuntimeContext context, ITypeSymbol type, bool isArray) { if (type == context.Types.String) { @@ -235,20 +237,20 @@ static RuntimeJavaType MapType(RuntimeContext context, Type type, bool isArray) } else if (type.IsEnum) { - foreach (RuntimeJavaType tw in context.ClassLoaderFactory.GetJavaTypeFromType(type).InnerClasses) + foreach (var tw in context.ClassLoaderFactory.GetJavaTypeFromType(type).InnerClasses) { if (tw is EnumEnumJavaType) { - if (!isArray && type.IsDefined(context.Resolver.ResolveCoreType(typeof(FlagsAttribute).FullName).AsReflection(), false)) - { + if (!isArray && type.IsDefined(context.Resolver.ResolveCoreType(typeof(FlagsAttribute).FullName), false)) return tw.MakeArrayType(1); - } + return tw; } } + throw new InvalidOperationException(); } - else if (!isArray && ReflectUtil.IsVector(type)) + else if (isArray == false && type.IsSZArray) { return MapType(context, type.GetElementType(), true).MakeArrayType(1); } @@ -285,7 +287,7 @@ protected override void LazyPublishMembers() if (singleOneArgCtor != null) methods.Add(new AttributeAnnotationJavaMethod(this, "value", singleOneArgCtor.GetParameters()[0].ParameterType, defCtor != null)); - foreach (var pi in attributeType.GetProperties(BindingFlags.Instance | BindingFlags.Public)) + foreach (var pi in attributeType.GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public)) { // the getter and setter methods both need to be public // the getter signature must be: Getter() @@ -293,12 +295,12 @@ protected override void LazyPublishMembers() // the property type needs to be a supported type var getter = pi.GetGetMethod(); var setter = pi.GetSetMethod(); - ParameterInfo[] parameters; + IParameterSymbol[] parameters; if (getter != null && getter.GetParameters().Length == 0 && getter.ReturnType == pi.PropertyType && setter != null && (parameters = setter.GetParameters()).Length == 1 && parameters[0].ParameterType == pi.PropertyType && setter.ReturnType == Context.Types.Void && IsSupportedType(Context, pi.PropertyType)) AddMethodIfUnique(methods, new AttributeAnnotationJavaMethod(this, pi.Name, pi.PropertyType, true)); } - foreach (var fi in attributeType.GetFields(BindingFlags.Public | BindingFlags.Instance)) + foreach (var fi in attributeType.GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)) if (!fi.IsInitOnly && IsSupportedType(Context, fi.FieldType)) AddMethodIfUnique(methods, new AttributeAnnotationJavaMethod(this, fi.Name, fi.FieldType, true)); @@ -374,7 +376,7 @@ internal override object GetAnnotationDefault(RuntimeJavaMethod mw) } else if (mw.ReturnType.IsArray) { - return Array.CreateInstance(mw.ReturnType.TypeAsArrayType, 0); + return Array.CreateInstance(mw.ReturnType.TypeAsArrayType.AsReflection(), 0); } } @@ -385,7 +387,7 @@ internal override object GetAnnotationDefault(RuntimeJavaMethod mw) internal override RuntimeJavaType DeclaringTypeWrapper => Context.ClassLoaderFactory.GetJavaTypeFromType(attributeType); - internal override Type TypeAsTBD => fakeType; + internal override ITypeSymbol TypeAsTBD => fakeType; internal override RuntimeJavaType[] InnerClasses => innerClasses ??= GetInnerClasses(); @@ -411,39 +413,39 @@ AttributeUsageAttribute GetAttributeUsage() AttributeTargets validOn = AttributeTargets.All; bool allowMultiple = false; bool inherited = true; - foreach (CustomAttributeData cad in CustomAttributeData.GetCustomAttributes(attributeType)) + foreach (var cad in attributeType.GetCustomAttributes()) { - if (cad.Constructor.DeclaringType == Context.Resolver.ResolveCoreType(typeof(AttributeUsageAttribute).FullName).AsReflection()) + if (cad.Constructor.DeclaringType == Context.Resolver.ResolveCoreType(typeof(AttributeUsageAttribute).FullName)) { - if (cad.ConstructorArguments.Count == 1 && cad.ConstructorArguments[0].ArgumentType == Context.Resolver.ResolveCoreType(typeof(AttributeTargets).FullName).AsReflection()) + if (cad.ConstructorArguments.Length == 1 && cad.ConstructorArguments[0].ArgumentType == Context.Resolver.ResolveCoreType(typeof(AttributeTargets).FullName)) { validOn = (AttributeTargets)cad.ConstructorArguments[0].Value; } - foreach (CustomAttributeNamedArgument cana in cad.NamedArguments) + + foreach (var cana in cad.NamedArguments) { if (cana.MemberInfo.Name == "AllowMultiple") - { allowMultiple = (bool)cana.TypedValue.Value; - } else if (cana.MemberInfo.Name == "Inherited") - { inherited = (bool)cana.TypedValue.Value; - } } } } - AttributeUsageAttribute attr = new AttributeUsageAttribute(validOn); + + var attr = new AttributeUsageAttribute(validOn); attr.AllowMultiple = allowMultiple; attr.Inherited = inherited; return attr; } #if !IMPORTER && !FIRST_PASS && !EXPORTER + internal override object[] GetDeclaredAnnotations() { // note that AttributeUsageAttribute.Inherited does not map to java.lang.annotation.Inherited - AttributeTargets validOn = GetAttributeUsage().ValidOn; - List targets = new List(); + var validOn = GetAttributeUsage().ValidOn; + var targets = new List(); + if ((validOn & (AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Delegate | AttributeTargets.Assembly)) != 0) { targets.Add(java.lang.annotation.ElementType.TYPE); @@ -468,23 +470,23 @@ internal override object[] GetDeclaredAnnotations() targetMap.put("value", targets.ToArray()); java.util.HashMap retentionMap = new java.util.HashMap(); retentionMap.put("value", java.lang.annotation.RetentionPolicy.RUNTIME); - return new object[] { - java.lang.reflect.Proxy.newProxyInstance(null, new java.lang.Class[] { typeof(java.lang.annotation.Target) }, new sun.reflect.annotation.AnnotationInvocationHandler(typeof(java.lang.annotation.Target), targetMap)), - java.lang.reflect.Proxy.newProxyInstance(null, new java.lang.Class[] { typeof(java.lang.annotation.Retention) }, new sun.reflect.annotation.AnnotationInvocationHandler(typeof(java.lang.annotation.Retention), retentionMap)) - }; + return [ + java.lang.reflect.Proxy.newProxyInstance(null, [typeof(java.lang.annotation.Target)], new sun.reflect.annotation.AnnotationInvocationHandler(typeof(java.lang.annotation.Target), targetMap)), + java.lang.reflect.Proxy.newProxyInstance(null, [typeof(java.lang.annotation.Retention)], new sun.reflect.annotation.AnnotationInvocationHandler(typeof(java.lang.annotation.Retention), retentionMap)) + ]; } #endif sealed class AttributeAnnotation : Annotation { - readonly Type type; + readonly ITypeSymbol type; /// /// Initializes a new instance. /// /// - internal AttributeAnnotation(Type type) + internal AttributeAnnotation(ITypeSymbol type) { this.type = type; } @@ -492,14 +494,14 @@ internal AttributeAnnotation(Type type) CustomAttributeBuilder MakeCustomAttributeBuilder(RuntimeClassLoader loader, object annotation) { object[] arr = (object[])annotation; - ConstructorInfo defCtor; - ConstructorInfo singleOneArgCtor; object ctorArg = null; - GetConstructors(loader.Context, type, out defCtor, out singleOneArgCtor); - List properties = new List(); - List propertyValues = new List(); - List fields = new List(); - List fieldValues = new List(); + + GetConstructors(loader.Context, type, out var defCtor, out var singleOneArgCtor); + var properties = new List(); + var propertyValues = new List(); + var fields = new List(); + var fieldValues = new List(); + for (int i = 2; i < arr.Length; i += 2) { string name = (string)arr[i]; @@ -509,7 +511,7 @@ CustomAttributeBuilder MakeCustomAttributeBuilder(RuntimeClassLoader loader, obj } else { - PropertyInfo pi = type.GetProperty(name, BindingFlags.Public | BindingFlags.Instance); + var pi = type.GetProperty(name, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance); if (pi != null) { properties.Add(pi); @@ -517,7 +519,7 @@ CustomAttributeBuilder MakeCustomAttributeBuilder(RuntimeClassLoader loader, obj } else { - FieldInfo fi = type.GetField(name, BindingFlags.Public | BindingFlags.Instance); + var fi = type.GetField(name, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance); if (fi != null) { fields.Add(fi); @@ -526,21 +528,24 @@ CustomAttributeBuilder MakeCustomAttributeBuilder(RuntimeClassLoader loader, obj } } } + if (ctorArg == null && defCtor == null) { // TODO required argument is missing } - return new CustomAttributeBuilder(ctorArg == null ? defCtor : singleOneArgCtor, - ctorArg == null ? new object[0] : new object[] { ctorArg }, - properties.ToArray(), + + return new CustomAttributeBuilder( + ctorArg == null ? defCtor.AsReflection() : singleOneArgCtor.AsReflection(), + ctorArg == null ? [] : new object[] { ctorArg }, + properties.ToArray().AsReflection(), propertyValues.ToArray(), - fields.ToArray(), + fields.ToArray().AsReflection(), fieldValues.ToArray()); } internal override void Apply(RuntimeClassLoader loader, TypeBuilder tb, object annotation) { - if (type == loader.Context.Resolver.ResolveCoreType(typeof(System.Runtime.InteropServices.StructLayoutAttribute).FullName).AsReflection() && tb.BaseType != loader.Context.Types.Object) + if (type == loader.Context.Resolver.ResolveCoreType(typeof(System.Runtime.InteropServices.StructLayoutAttribute).FullName) && loader.Context.Resolver.ResolveType(tb.BaseType) != loader.Context.Types.Object) { // we have to handle this explicitly, because if we apply an illegal StructLayoutAttribute, // TypeBuilder.CreateType() will later on throw an exception. @@ -569,7 +574,7 @@ internal override void Apply(RuntimeClassLoader loader, ParameterBuilder pb, obj { // TODO with the current custom attribute annotation restrictions it is impossible to use this CA, // but if we make it possible, we should also implement it here - if (type == loader.Context.Resolver.ResolveCoreType(typeof(System.Runtime.InteropServices.DefaultParameterValueAttribute).FullName).AsReflection()) + if (type == loader.Context.Resolver.ResolveCoreType(typeof(System.Runtime.InteropServices.DefaultParameterValueAttribute).FullName)) throw new NotImplementedException(); else pb.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); @@ -578,11 +583,11 @@ internal override void Apply(RuntimeClassLoader loader, ParameterBuilder pb, obj internal override void Apply(RuntimeClassLoader loader, AssemblyBuilder ab, object annotation) { #if IMPORTER - if (type == loader.Context.Resolver.ResolveCoreType(typeof(System.Runtime.CompilerServices.TypeForwardedToAttribute).FullName).AsReflection()) + if (type == loader.Context.Resolver.ResolveCoreType(typeof(System.Runtime.CompilerServices.TypeForwardedToAttribute).FullName)) { ab.__AddTypeForwarder((Type)ConvertValue(loader, loader.Context.Types.Type, ((object[])annotation)[3])); } - else if (type == loader.Context.Resolver.ResolveCoreType(typeof(System.Reflection.AssemblyVersionAttribute).FullName).AsReflection()) + else if (type == loader.Context.Resolver.ResolveCoreType(typeof(System.Reflection.AssemblyVersionAttribute).FullName)) { string str = (string)ConvertValue(loader, loader.Context.Types.String, ((object[])annotation)[3]); Version version; @@ -595,7 +600,7 @@ internal override void Apply(RuntimeClassLoader loader, AssemblyBuilder ab, obje loader.Diagnostics.InvalidCustomAttribute(type.FullName, "The version '" + str + "' is invalid."); } } - else if (type == loader.Context.Resolver.ResolveCoreType(typeof(System.Reflection.AssemblyCultureAttribute).FullName).AsReflection()) + else if (type == loader.Context.Resolver.ResolveCoreType(typeof(System.Reflection.AssemblyCultureAttribute).FullName)) { string str = (string)ConvertValue(loader, loader.Context.Types.String, ((object[])annotation)[3]); if (str != "") @@ -603,18 +608,19 @@ internal override void Apply(RuntimeClassLoader loader, AssemblyBuilder ab, obje ab.__SetAssemblyCulture(str); } } - else if (type == loader.Context.Resolver.ResolveCoreType(typeof(System.Reflection.AssemblyDelaySignAttribute).FullName).AsReflection() - || type == loader.Context.Resolver.ResolveCoreType(typeof(System.Reflection.AssemblyKeyFileAttribute).FullName).AsReflection() - || type == loader.Context.Resolver.ResolveCoreType(typeof(System.Reflection.AssemblyKeyNameAttribute).FullName).AsReflection()) + else if ( + type == loader.Context.Resolver.ResolveCoreType(typeof(System.Reflection.AssemblyDelaySignAttribute).FullName) || + type == loader.Context.Resolver.ResolveCoreType(typeof(System.Reflection.AssemblyKeyFileAttribute).FullName) || + type == loader.Context.Resolver.ResolveCoreType(typeof(System.Reflection.AssemblyKeyNameAttribute).FullName)) { loader.Diagnostics.IgnoredCustomAttribute(type.FullName, "Please use the corresponding compiler switch."); } - else if (type == loader.Context.Resolver.ResolveCoreType(typeof(System.Reflection.AssemblyAlgorithmIdAttribute).FullName).AsReflection()) + else if (type == loader.Context.Resolver.ResolveCoreType(typeof(System.Reflection.AssemblyAlgorithmIdAttribute).FullName)) { // this attribute is currently not exposed as an annotation and isn't very interesting throw new NotImplementedException(); } - else if (type == loader.Context.Resolver.ResolveCoreType(typeof(System.Reflection.AssemblyFlagsAttribute).FullName).AsReflection()) + else if (type == loader.Context.Resolver.ResolveCoreType(typeof(System.Reflection.AssemblyFlagsAttribute).FullName)) { // this attribute is currently not exposed as an annotation and isn't very interesting throw new NotImplementedException(); @@ -624,7 +630,7 @@ internal override void Apply(RuntimeClassLoader loader, AssemblyBuilder ab, obje ab.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); } #else - ab.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); + ab.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); #endif } diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.ByRefJavaMethod.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.ByRefJavaMethod.cs index bc808390f..ee8ee78f2 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.ByRefJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.ByRefJavaMethod.cs @@ -21,9 +21,8 @@ Jeroen Frijters jeroen@frijters.net */ -using System; - using IKVM.Attributes; +using IKVM.CoreLib.Symbols; #if IMPORTER || EXPORTER using IKVM.Reflection; @@ -31,7 +30,6 @@ Jeroen Frijters using Type = IKVM.Reflection.Type; #else -using System.Reflection; using System.Reflection.Emit; #endif @@ -47,7 +45,7 @@ sealed class ByRefJavaMethod : RuntimeSmartJavaMethod #if !IMPORTER readonly bool[] byrefs; #endif - readonly Type[] args; + readonly ITypeSymbol[] args; /// /// Initializes a new instance. @@ -62,7 +60,7 @@ sealed class ByRefJavaMethod : RuntimeSmartJavaMethod /// /// /// - internal ByRefJavaMethod(Type[] args, bool[] byrefs, RuntimeJavaType declaringType, string name, string sig, MethodBase method, RuntimeJavaType returnType, RuntimeJavaType[] parameterTypes, Modifiers modifiers, bool hideFromReflection) : + internal ByRefJavaMethod(ITypeSymbol[] args, bool[] byrefs, RuntimeJavaType declaringType, string name, string sig, IMethodBaseSymbol method, RuntimeJavaType returnType, RuntimeJavaType[] parameterTypes, Modifiers modifiers, bool hideFromReflection) : base(declaringType, name, sig, method, returnType, parameterTypes, modifiers, hideFromReflection ? MemberFlags.HideFromReflection : MemberFlags.None) { this.args = args; @@ -72,6 +70,7 @@ internal ByRefJavaMethod(Type[] args, bool[] byrefs, RuntimeJavaType declaringTy } #if EMITTERS + protected override void CallImpl(CodeEmitter ilgen) { ConvertByRefArgs(ilgen); diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.CloneJavaMethod.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.CloneJavaMethod.cs index b9a0b9f6e..669a19174 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.CloneJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.CloneJavaMethod.cs @@ -71,7 +71,7 @@ internal override void EmitCall(CodeEmitter ilgen) ilgen.MarkLabel(label2); ilgen.EmitThrow("java.lang.NullPointerException"); ilgen.MarkLabel(label1); - ilgen.Emit(OpCodes.Call, DeclaringType.Context.Types.Object.GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic, null, Type.EmptyTypes, null)); + ilgen.Emit(OpCodes.Call, DeclaringType.Context.Types.Object.GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic, null, [], null)); } internal override void EmitCallvirt(CodeEmitter ilgen) diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.DelegateInnerClassJavaType.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.DelegateInnerClassJavaType.cs index 87e804711..6d00693b2 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.DelegateInnerClassJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.DelegateInnerClassJavaType.cs @@ -24,19 +24,12 @@ Jeroen Frijters using System; using IKVM.Attributes; - -#if IMPORTER || EXPORTER -using Type = IKVM.Reflection.Type; -#endif +using IKVM.CoreLib.Symbols; #if IMPORTER using IKVM.Tools.Importer; #endif -#if EXPORTER -using IKVM.Tools.Exporter; -#endif - namespace IKVM.Runtime { @@ -46,7 +39,7 @@ sealed partial class RuntimeManagedJavaType sealed class DelegateInnerClassJavaType : FakeJavaType { - readonly Type fakeType; + readonly ITypeSymbol fakeType; /// /// Initializes a new instance. @@ -54,13 +47,13 @@ sealed class DelegateInnerClassJavaType : FakeJavaType /// /// /// - internal DelegateInnerClassJavaType(RuntimeContext context, string name, Type delegateType) : + internal DelegateInnerClassJavaType(RuntimeContext context, string name, ITypeSymbol delegateType) : base(context, Modifiers.Public | Modifiers.Interface | Modifiers.Abstract, name, null) { #if IMPORTER || EXPORTER this.fakeType = context.FakeTypes.GetDelegateType(delegateType); #elif !FIRST_PASS - this.fakeType = typeof(ikvm.@internal.DelegateInterface<>).MakeGenericType(delegateType); + this.fakeType = context.Resolver.ResolveType(typeof(ikvm.@internal.DelegateInterface<>)).MakeGenericType(delegateType); #endif var invoke = delegateType.GetMethod("Invoke"); var parameters = invoke.GetParameters(); @@ -76,22 +69,24 @@ internal DelegateInnerClassJavaType(RuntimeContext context, string name, Type de flags |= MemberFlags.DelegateInvokeWithByRefParameter; parameterType = RuntimeArrayJavaType.MakeArrayType(parameterType.GetElementType(), 1); } + argTypeWrappers[i] = Context.ClassLoaderFactory.GetJavaTypeFromType(parameterType); sb.Append(argTypeWrappers[i].SigName); } var returnType = Context.ClassLoaderFactory.GetJavaTypeFromType(invoke.ReturnType); sb.Append(")").Append(returnType.SigName); + var invokeMethod = new DynamicOnlyJavaMethod(this, "Invoke", sb.ToString(), returnType, argTypeWrappers, flags); - SetMethods(new RuntimeJavaMethod[] { invokeMethod }); - SetFields(Array.Empty()); + SetMethods([invokeMethod]); + SetFields([]); } internal override RuntimeJavaType DeclaringTypeWrapper => Context.ClassLoaderFactory.GetJavaTypeFromType(fakeType.GetGenericArguments()[0]); internal override RuntimeClassLoader ClassLoader => DeclaringTypeWrapper.ClassLoader; - internal override Type TypeAsTBD => fakeType; + internal override ITypeSymbol TypeAsTBD => fakeType; internal override bool IsFastClassLiteralSafe => true; diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.EnumEnumJavaType.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.EnumEnumJavaType.cs index f709eb7aa..9d5dc4e1a 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.EnumEnumJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.EnumEnumJavaType.cs @@ -25,6 +25,8 @@ Jeroen Frijters using System.Collections.Generic; using IKVM.Attributes; +using IKVM.CoreLib.Symbols; + #if IMPORTER || EXPORTER using IKVM.Reflection; @@ -49,7 +51,7 @@ sealed partial class RuntimeManagedJavaType sealed partial class EnumEnumJavaType : FakeJavaType { - readonly Type fakeType; + readonly ITypeSymbol fakeType; /// /// Initializes a new instance. @@ -57,13 +59,13 @@ sealed partial class EnumEnumJavaType : FakeJavaType /// /// /// - internal EnumEnumJavaType(RuntimeContext context, string name, Type enumType) : + internal EnumEnumJavaType(RuntimeContext context, string name, ITypeSymbol enumType) : base(context, Modifiers.Public | Modifiers.Enum | Modifiers.Final, name, context.ClassLoaderFactory.LoadClassCritical("java.lang.Enum")) { #if IMPORTER || EXPORTER this.fakeType = context.FakeTypes.GetEnumType(enumType); #elif !FIRST_PASS - this.fakeType = typeof(ikvm.@internal.EnumEnum<>).MakeGenericType(enumType); + this.fakeType = context.Resolver.ResolveType(typeof(ikvm.@internal.EnumEnum<>)).MakeGenericType(enumType); #endif } @@ -105,7 +107,7 @@ internal EnumJavaField(RuntimeJavaType tw, string name, int ordinal) : internal override object GetValue(object obj) { if (val == null) - System.Threading.Interlocked.CompareExchange(ref val, Activator.CreateInstance(this.DeclaringType.TypeAsTBD, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, new object[] { this.Name, ordinal }, null), null); + System.Threading.Interlocked.CompareExchange(ref val, Activator.CreateInstance(this.DeclaringType.TypeAsTBD.AsReflection(), BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, new object[] { this.Name, ordinal }, null), null); return val; } @@ -120,7 +122,7 @@ internal override void SetValue(object obj, object value) #if EMITTERS protected override void EmitGetImpl(CodeEmitter ilgen) { - var typeofByteCodeHelper = DeclaringType.Context.Resolver.ResolveRuntimeType("IKVM.Runtime.ByteCodeHelper").AsReflection(); + var typeofByteCodeHelper = DeclaringType.Context.Resolver.ResolveRuntimeType("IKVM.Runtime.ByteCodeHelper"); ilgen.Emit(OpCodes.Ldstr, Name); ilgen.Emit(OpCodes.Call, typeofByteCodeHelper.GetMethod("GetDotNetEnumField").MakeGenericMethod(DeclaringType.TypeAsBaseType)); } @@ -142,7 +144,7 @@ sealed class EnumValuesJavaMethod : RuntimeJavaMethod /// /// internal EnumValuesJavaMethod(RuntimeJavaType declaringType) : - base(declaringType, "values", "()[" + declaringType.SigName, null, declaringType.MakeArrayType(1), Array.Empty(), Modifiers.Public | Modifiers.Static, MemberFlags.None) + base(declaringType, "values", "()[" + declaringType.SigName, null, declaringType.MakeArrayType(1), [], Modifiers.Public | Modifiers.Static, MemberFlags.None) { } @@ -153,12 +155,11 @@ internal EnumValuesJavaMethod(RuntimeJavaType declaringType) : internal override object Invoke(object obj, object[] args) { - RuntimeJavaField[] values = this.DeclaringType.GetFields(); - object[] array = (object[])Array.CreateInstance(this.DeclaringType.TypeAsArrayType, values.Length); + var values = DeclaringType.GetFields(); + var array = (object[])Array.CreateInstance(DeclaringType.TypeAsArrayType.AsReflection(), values.Length); for (int i = 0; i < values.Length; i++) - { array[i] = values[i].GetValue(null); - } + return array; } @@ -170,14 +171,14 @@ protected override void LazyPublishMembers() { var fields = new List(); int ordinal = 0; - foreach (var field in DeclaringTypeWrapper.TypeAsTBD.GetFields(BindingFlags.Static | BindingFlags.Public)) + foreach (var field in DeclaringTypeWrapper.TypeAsTBD.GetFields(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public)) if (field.IsLiteral) fields.Add(new EnumJavaField(this, field.Name, ordinal++)); // TODO if the enum already has an __unspecified value, rename this one fields.Add(new EnumJavaField(this, "__unspecified", ordinal++)); SetFields(fields.ToArray()); - SetMethods(new RuntimeJavaMethod[] { new EnumValuesJavaMethod(this), new EnumValueOfJavaMethod(this) }); + SetMethods([new EnumValuesJavaMethod(this), new EnumValueOfJavaMethod(this)]); base.LazyPublishMembers(); } @@ -185,7 +186,7 @@ protected override void LazyPublishMembers() internal override RuntimeClassLoader ClassLoader => DeclaringTypeWrapper.ClassLoader; - internal override Type TypeAsTBD => fakeType; + internal override ITypeSymbol TypeAsTBD => fakeType; internal override bool IsFastClassLiteralSafe => true; diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.OpenGenericJavaType.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.OpenGenericJavaType.cs index bde190045..1a21b4801 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.OpenGenericJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.OpenGenericJavaType.cs @@ -24,6 +24,7 @@ Jeroen Frijters using System; using IKVM.Attributes; +using IKVM.CoreLib.Symbols; #if IMPORTER || EXPORTER using Type = IKVM.Reflection.Type; @@ -48,9 +49,9 @@ sealed partial class RuntimeManagedJavaType sealed class OpenGenericJavaType : RuntimeJavaType { - readonly Type type; + readonly ITypeSymbol type; - static Modifiers GetModifiers(Type type) + static Modifiers GetModifiers(ITypeSymbol type) { var modifiers = Modifiers.Abstract | Modifiers.Final; if (type.IsInterface) @@ -65,7 +66,7 @@ static Modifiers GetModifiers(Type type) /// /// /// - internal OpenGenericJavaType(RuntimeContext context, Type type, string name) : + internal OpenGenericJavaType(RuntimeContext context, ITypeSymbol type, string name) : base(context, TypeFlags.None, GetModifiers(type), name) { this.type = type; @@ -73,7 +74,7 @@ internal OpenGenericJavaType(RuntimeContext context, Type type, string name) : internal override RuntimeJavaType BaseTypeWrapper => type.IsInterface ? null : Context.JavaBase.TypeOfJavaLangObject; - internal override Type TypeAsTBD => type; + internal override ITypeSymbol TypeAsTBD => type; internal override RuntimeClassLoader ClassLoader => Context.AssemblyClassLoaderFactory.FromAssembly(type.Assembly); diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.cs index c864042da..523b20f72 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.cs @@ -26,6 +26,7 @@ Jeroen Frijters using System.Diagnostics; using IKVM.Attributes; +using IKVM.CoreLib.Symbols; #if IMPORTER || EXPORTER using IKVM.Reflection; @@ -59,13 +60,13 @@ sealed partial class RuntimeManagedJavaType : RuntimeJavaType internal const string GenericAttributeAnnotationReturnValueTypeName = "ikvm.internal.AttributeAnnotationReturnValue`1"; internal const string GenericAttributeAnnotationMultipleTypeName = "ikvm.internal.AttributeAnnotationMultiple`1"; - readonly Type type; + readonly ITypeSymbol type; RuntimeJavaType baseTypeWrapper; RuntimeJavaType[] innerClasses; RuntimeJavaType outerClass; RuntimeJavaType[] interfaces; - static Modifiers GetModifiers(Type type) + static Modifiers GetModifiers(ITypeSymbol type) { Modifiers modifiers = 0; if (type.IsPublic) @@ -111,7 +112,7 @@ static Modifiers GetModifiers(Type type) // NOTE when this is called on a remapped type, the "warped" underlying type name is returned. // E.g. GetName(typeof(object)) returns "cli.System.Object". - internal static string GetName(RuntimeContext context, Type type) + internal static string GetName(RuntimeContext context, ITypeSymbol type) { Debug.Assert(!type.Name.EndsWith("[]") && !context.AttributeHelper.IsJavaModule(type.Module)); @@ -127,8 +128,9 @@ internal static string GetName(RuntimeContext context, Type type) var sb = new System.Text.StringBuilder(); sb.Append(MangleTypeName(type.GetGenericTypeDefinition().FullName)); sb.Append("_$$$_"); - string sep = ""; - foreach (Type t1 in type.GetGenericArguments()) + + var sep = ""; + foreach (var t1 in type.GetGenericArguments()) { var t = t1; sb.Append(sep); @@ -141,7 +143,7 @@ internal static string GetName(RuntimeContext context, Type type) // class Base { } // class Derived : Base { } // - while (ReflectUtil.IsVector(t)) + while (t.IsSZArray) { t = t.GetElementType(); sb.Append('A'); @@ -269,20 +271,20 @@ internal static string DemangleTypeName(string name) // TODO from a perf pov it may be better to allow creation of TypeWrappers, // but to simply make sure they don't have ClassObject - internal static bool IsAllowedOutside(Type type) + internal static bool IsAllowedOutside(ITypeSymbol type) { // SECURITY we never expose types from IKVM.Runtime, because doing so would lead to a security hole, // since the reflection implementation lives inside this assembly, all internal members would // be accessible through Java reflection. #if !FIRST_PASS && !IMPORTER && !EXPORTER - if (type.Assembly == typeof(RuntimeManagedJavaType).Assembly) + if (type.Assembly.AsReflection() == typeof(RuntimeManagedJavaType).Assembly) return false; #endif return true; } - internal static RuntimeJavaType Create(RuntimeContext context, Type type, string name) + internal static RuntimeJavaType Create(RuntimeContext context, ITypeSymbol type, string name) { if (type.ContainsGenericParameters) { @@ -300,13 +302,13 @@ internal static RuntimeJavaType Create(RuntimeContext context, Type type, string /// /// /// - RuntimeManagedJavaType(RuntimeContext context, Type type, string name) : + RuntimeManagedJavaType(RuntimeContext context, ITypeSymbol type, string name) : base(context, TypeFlags.None, GetModifiers(type), name) { Debug.Assert(!type.IsByRef, type.FullName); Debug.Assert(!type.IsPointer, type.FullName); Debug.Assert(!type.Name.EndsWith("[]"), type.FullName); - Debug.Assert(type is not TypeBuilder, type.FullName); + Debug.Assert(type.AsReflection() is not TypeBuilder, type.FullName); Debug.Assert(!Context.AttributeHelper.IsJavaModule(type.Module)); this.type = type; @@ -316,7 +318,7 @@ internal static RuntimeJavaType Create(RuntimeContext context, Type type, string internal override RuntimeClassLoader ClassLoader => type.IsGenericType ? Context.ClassLoaderFactory.GetGenericClassLoader(this) : Context.AssemblyClassLoaderFactory.FromAssembly(type.Assembly); - internal static string GetDelegateInvokeStubName(Type delegateType) + internal static string GetDelegateInvokeStubName(ITypeSymbol delegateType) { var delegateInvoke = delegateType.GetMethod("Invoke"); var parameters = delegateInvoke.GetParameters(); @@ -334,8 +336,9 @@ protected override void LazyPublishMembers() // special support for enums if (type.IsEnum) { - Type underlyingType = EnumHelper.GetUnderlyingType(type); - Type javaUnderlyingType; + var underlyingType = type.GetEnumUnderlyingType(); + + ITypeSymbol javaUnderlyingType; if (underlyingType == Context.Types.SByte) { javaUnderlyingType = Context.Types.Byte; @@ -358,7 +361,7 @@ protected override void LazyPublishMembers() } var fieldType = Context.ClassLoaderFactory.GetJavaTypeFromType(javaUnderlyingType); - var fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Static); + var fields = type.GetFields(System.Reflection.BindingFlags.DeclaredOnly | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static); var fieldsList = new List(); for (int i = 0; i < fields.Length; i++) { @@ -381,7 +384,7 @@ protected override void LazyPublishMembers() else { var fieldsList = new List(); - var fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance); + var fields = type.GetFields(System.Reflection.BindingFlags.DeclaredOnly | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Instance); for (int i = 0; i < fields.Length; i++) { // TODO for remapped types, instance fields need to be converted to static getter/setter methods @@ -411,7 +414,7 @@ protected override void LazyPublishMembers() if (type == Context.Types.MulticastDelegate) methodsList.Add("()V", new MulticastDelegateCtorJavaMethod(this)); - var constructors = type.GetConstructors(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance); + var constructors = type.GetConstructors(System.Reflection.BindingFlags.DeclaredOnly | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Instance); for (int i = 0; i < constructors.Length; i++) { if (MakeMethodDescriptor(constructors[i], out var name, out var sig, out var args, out var ret)) @@ -429,7 +432,7 @@ protected override void LazyPublishMembers() methodsList.Add("()V", new ValueTypeDefaultCtorJavaMethod(this)); } - var methods = type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance); + var methods = type.GetMethods(System.Reflection.BindingFlags.DeclaredOnly | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Instance); for (int i = 0; i < methods.Length; i++) { if (methods[i].IsStatic && type.IsInterface) @@ -545,10 +548,8 @@ protected override void LazyPublishMembers() #if !IMPORTER && !EXPORTER && !FIRST_PASS // support serializing .NET exceptions (by replacing them with a placeholder exception) - if (typeof(Exception).IsAssignableFrom(type) && !typeof(java.io.Serializable.__Interface).IsAssignableFrom(type) && !methodsList.ContainsKey("writeReplace()Ljava.lang.Object;")) - { + if (Context.Types.Exception.IsAssignableFrom(type) && Context.Resolver.ResolveType(typeof(java.io.Serializable.__Interface)).IsAssignableFrom(type) == false && methodsList.ContainsKey("writeReplace()Ljava.lang.Object;") == false) methodsList.Add("writeReplace()Ljava.lang.Object;", new ExceptionWriteReplaceJavaMethod(this)); - } #endif @@ -558,7 +559,7 @@ protected override void LazyPublishMembers() } } - void InterfaceMethodStubHelper(Dictionary methodsList, MethodBase method, string name, string sig, RuntimeJavaType[] args, RuntimeJavaType ret) + void InterfaceMethodStubHelper(Dictionary methodsList, IMethodBaseSymbol method, string name, string sig, RuntimeJavaType[] args, RuntimeJavaType ret) { var key = name + sig; methodsList.TryGetValue(key, out var existing); @@ -578,11 +579,11 @@ void InterfaceMethodStubHelper(Dictionary methodsList } } - internal static bool IsUnsupportedAbstractMethod(MethodBase mb) + internal static bool IsUnsupportedAbstractMethod(IMethodBaseSymbol mb) { if (mb.IsAbstract) { - var mi = (MethodInfo)mb; + var mi = (IMethodSymbol)mb; if (mi.ReturnType.IsByRef || IsPointerType(mi.ReturnType) || mb.IsGenericMethodDefinition) return true; @@ -594,7 +595,7 @@ internal static bool IsUnsupportedAbstractMethod(MethodBase mb) return false; } - static bool IsPointerType(Type type) + static bool IsPointerType(ITypeSymbol type) { while (type.HasElementType) { @@ -604,14 +605,10 @@ static bool IsPointerType(Type type) type = type.GetElementType(); } -#if IMPORTER || EXPORTER - return type.__IsFunctionPointer; -#else - return false; -#endif + return type.IsUnmanagedFunctionPointer; } - bool MakeMethodDescriptor(MethodBase mb, out string name, out string sig, out RuntimeJavaType[] args, out RuntimeJavaType ret) + bool MakeMethodDescriptor(IMethodBaseSymbol mb, out string name, out string sig, out RuntimeJavaType[] args, out RuntimeJavaType ret) { if (mb.IsGenericMethodDefinition) { @@ -668,7 +665,7 @@ bool MakeMethodDescriptor(MethodBase mb, out string name, out string sig, out Ru } else { - var type = ((MethodInfo)mb).ReturnType; + var type = ((IMethodSymbol)mb).ReturnType; if (IsPointerType(type) || type.IsByRef) { name = null; @@ -686,7 +683,7 @@ bool MakeMethodDescriptor(MethodBase mb, out string name, out string sig, out Ru internal override RuntimeJavaType[] Interfaces => interfaces ??= GetImplementedInterfacesAsTypeWrappers(Context, type); - static bool IsAttribute(RuntimeContext context, Type type) + static bool IsAttribute(RuntimeContext context, ITypeSymbol type) { if (!type.IsAbstract && type.IsSubclassOf(context.Types.Attribute) && type.IsVisible) { @@ -710,7 +707,7 @@ static bool IsAttribute(RuntimeContext context, Type type) return false; } - static bool IsDelegate(RuntimeContext context, Type type) + static bool IsDelegate(RuntimeContext context, ITypeSymbol type) { // HACK non-public delegates do not get the special treatment (because they are likely to refer to // non-public types in the arg list and they're not really useful anyway) @@ -739,7 +736,7 @@ static bool IsDelegate(RuntimeContext context, Type type) RuntimeJavaType[] GetInnerClasses() { - var nestedTypes = type.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic); + var nestedTypes = type.GetNestedTypes(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic); var list = new List(nestedTypes.Length); for (int i = 0; i < nestedTypes.Length; i++) if (!nestedTypes[i].IsGenericTypeDefinition) @@ -776,7 +773,7 @@ internal override RuntimeJavaType DeclaringTypeWrapper internal override Modifiers ReflectiveModifiers => DeclaringTypeWrapper != null ? Modifiers | Modifiers.Static : Modifiers; - RuntimeJavaField CreateFieldWrapperDotNet(Modifiers modifiers, string name, Type fieldType, FieldInfo field) + RuntimeJavaField CreateFieldWrapperDotNet(Modifiers modifiers, string name, ITypeSymbol fieldType, IFieldSymbol field) { var type = Context.ClassLoaderFactory.GetJavaTypeFromType(fieldType); if (field.IsLiteral) @@ -790,7 +787,7 @@ RuntimeJavaField CreateFieldWrapperDotNet(Modifiers modifiers, string name, Type /// /// /// - static bool IsRemappedImplDerived(RuntimeContext context, Type type) + static bool IsRemappedImplDerived(RuntimeContext context, ITypeSymbol type) { for (; type != null; type = type.BaseType) if (!context.ClassLoaderFactory.IsRemappedType(type) && context.ClassLoaderFactory.GetJavaTypeFromType(type).IsRemapped) @@ -799,7 +796,7 @@ static bool IsRemappedImplDerived(RuntimeContext context, Type type) return false; } - RuntimeJavaMethod CreateMethodWrapper(string name, string sig, RuntimeJavaType[] argTypeWrappers, RuntimeJavaType retTypeWrapper, MethodBase mb, bool privateInterfaceImplHack) + RuntimeJavaMethod CreateMethodWrapper(string name, string sig, RuntimeJavaType[] argTypeWrappers, RuntimeJavaType retTypeWrapper, IMethodBaseSymbol mb, bool privateInterfaceImplHack) { var exmods = Context.AttributeHelper.GetModifiers(mb, true); var mods = exmods.Modifiers; @@ -813,7 +810,7 @@ RuntimeJavaMethod CreateMethodWrapper(string name, string sig, RuntimeJavaType[] } var parameters = mb.GetParameters(); - var args = new Type[parameters.Length]; + var args = new ITypeSymbol[parameters.Length]; var hasByRefArgs = false; bool[] byrefs = null; @@ -836,7 +833,7 @@ RuntimeJavaMethod CreateMethodWrapper(string name, string sig, RuntimeJavaType[] if (hasByRefArgs) { - if (mb is not ConstructorInfo && !mb.IsStatic) + if (mb.IsConstructor == false && !mb.IsStatic) mods |= Modifiers.Final; return new ByRefJavaMethod(args, byrefs, this, name, sig, mb, retTypeWrapper, argTypeWrappers, mods, false); @@ -847,7 +844,7 @@ RuntimeJavaMethod CreateMethodWrapper(string name, string sig, RuntimeJavaType[] } } - internal override Type TypeAsTBD => type; + internal override ITypeSymbol TypeAsTBD => type; internal override bool IsRemapped => Context.ClassLoaderFactory.IsRemappedType(type); @@ -918,7 +915,12 @@ internal override MethodParametersEntry[] GetMethodParameters(RuntimeJavaMethod internal override object[] GetDeclaredAnnotations() { - return type.GetCustomAttributes(false); + var l = type.GetCustomAttributes(); + var a = new object[l.Length]; + for (int i = 0; i < l.Length; i++) + a[i] = l[i]; + + return a; } internal override object[] GetFieldAnnotations(RuntimeJavaField fw) @@ -927,7 +929,12 @@ internal override object[] GetFieldAnnotations(RuntimeJavaField fw) if (fi == null) return null; - return fi.GetCustomAttributes(false); + var l = fi.GetCustomAttributes(); + var a = new object[l.Length]; + for (int i = 0; i < l.Length; i++) + a[i] = l[i]; + + return a; } internal override object[] GetMethodAnnotations(RuntimeJavaMethod mw) @@ -936,7 +943,12 @@ internal override object[] GetMethodAnnotations(RuntimeJavaMethod mw) if (mb == null) return null; - return mb.GetCustomAttributes(false); + var l = mb.GetCustomAttributes(); + var a = new object[l.Length]; + for (int i = 0; i < l.Length; i++) + a[i] = l[i]; + + return a; } internal override object[][] GetParameterAnnotations(RuntimeJavaMethod mw) @@ -948,10 +960,18 @@ internal override object[][] GetParameterAnnotations(RuntimeJavaMethod mw) var parameters = mb.GetParameters(); var attribs = new object[parameters.Length][]; for (int i = 0; i < parameters.Length; i++) - attribs[i] = parameters[i].GetCustomAttributes(false); + { + var l = parameters[i].GetCustomAttributes(); + var a = new object[l.Length]; + for (int j = 0; j < l.Length; j++) + a[j] = l[j]; + + attribs[i] = a; + } return attribs; } + #endif internal override bool IsFastClassLiteralSafe => type != Context.Types.Void && !type.IsPrimitive && !IsRemapped; @@ -970,13 +990,11 @@ internal override bool IsPackageAccessibleFrom(RuntimeJavaType wrapper) return false; // check accessibility for nested types - for (Type type = TypeAsTBD; type.IsNested; type = type.DeclaringType) + for (var type = TypeAsTBD; type.IsNested; type = type.DeclaringType) { // we don't support family (protected) access if (!type.IsNestedAssembly && !type.IsNestedFamORAssem && !type.IsNestedPublic) - { return false; - } } return true; diff --git a/src/IKVM.Runtime/RuntimeManagedJavaTypeFactory.cs b/src/IKVM.Runtime/RuntimeManagedJavaTypeFactory.cs index 1893aa103..d6c1aace8 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaTypeFactory.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaTypeFactory.cs @@ -24,6 +24,8 @@ Jeroen Frijters using System; using System.Runtime.CompilerServices; +using IKVM.CoreLib.Symbols; + #if IMPORTER || EXPORTER using IKVM.Reflection; using IKVM.Reflection.Emit; @@ -42,7 +44,7 @@ class RuntimeManagedJavaTypeFactory { readonly RuntimeContext context; - readonly ConditionalWeakTable cache = new ConditionalWeakTable(); + readonly ConditionalWeakTable cache = new ConditionalWeakTable(); /// /// Initializes a new instance. @@ -59,9 +61,9 @@ public RuntimeManagedJavaTypeFactory(RuntimeContext context) /// /// /// - public RuntimeJavaType GetJavaTypeFromManagedType(Type type) + public RuntimeJavaType GetJavaTypeFromManagedType(ITypeSymbol type) { - return cache.GetValue(type, _ => context.AssemblyClassLoaderFactory.FromAssembly(_.Assembly).GetJavaTypeFromAssemblyType(_)); + return cache.GetValue(type, _ => context.AssemblyClassLoaderFactory.FromAssembly(_.Assembly.AsReflection()).GetJavaTypeFromAssemblyType(_.AsReflection())); } /// @@ -69,7 +71,7 @@ public RuntimeJavaType GetJavaTypeFromManagedType(Type type) /// /// /// - public RuntimeJavaType GetBaseJavaType(Type type) + public RuntimeJavaType GetBaseJavaType(ITypeSymbol type) { // interfaces have no base type if (type.IsInterface) diff --git a/src/IKVM.Runtime/RuntimePrimitiveJavaType.cs b/src/IKVM.Runtime/RuntimePrimitiveJavaType.cs index 1603b1975..d0e2256a5 100644 --- a/src/IKVM.Runtime/RuntimePrimitiveJavaType.cs +++ b/src/IKVM.Runtime/RuntimePrimitiveJavaType.cs @@ -24,6 +24,8 @@ Jeroen Frijters using System; using IKVM.Attributes; +using IKVM.CoreLib.Symbols; + #if IMPORTER || EXPORTER using IKVM.Reflection; @@ -76,7 +78,7 @@ public RuntimePrimitiveJavaTypeFactory(RuntimeContext context) sealed class RuntimePrimitiveJavaType : RuntimeJavaType { - readonly Type type; + readonly ITypeSymbol type; readonly string sigName; /// @@ -84,7 +86,7 @@ sealed class RuntimePrimitiveJavaType : RuntimeJavaType /// /// /// - public RuntimePrimitiveJavaType(RuntimeContext context, Type type, string sigName) : + public RuntimePrimitiveJavaType(RuntimeContext context, ITypeSymbol type, string sigName) : base(context, TypeFlags.None, Modifiers.Public | Modifiers.Abstract | Modifiers.Final, null) { this.type = type; @@ -93,7 +95,7 @@ public RuntimePrimitiveJavaType(RuntimeContext context, Type type, string sigNam internal override RuntimeJavaType BaseTypeWrapper => null; - internal static bool IsPrimitiveType(RuntimeContext context, Type type) + internal static bool IsPrimitiveType(RuntimeContext context, ITypeSymbol type) { return type == context.PrimitiveJavaTypeFactory.BYTE.type || type == context.PrimitiveJavaTypeFactory.CHAR.type @@ -110,7 +112,7 @@ internal static bool IsPrimitiveType(RuntimeContext context, Type type) internal override RuntimeClassLoader ClassLoader => Context.ClassLoaderFactory.GetBootstrapClassLoader(); - internal override Type TypeAsTBD => type; + internal override ITypeSymbol TypeAsTBD => type; public override string ToString() => "RuntimePrimitiveJavaType[" + sigName + "]"; diff --git a/src/IKVM.Runtime/RuntimePrivateInterfaceJavaMethod.cs b/src/IKVM.Runtime/RuntimePrivateInterfaceJavaMethod.cs index 730c8447b..e7535f9f7 100644 --- a/src/IKVM.Runtime/RuntimePrivateInterfaceJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimePrivateInterfaceJavaMethod.cs @@ -22,14 +22,11 @@ Jeroen Frijters */ using IKVM.Attributes; +using IKVM.CoreLib.Symbols; #if IMPORTER || EXPORTER -using IKVM.Reflection; using IKVM.Reflection.Emit; - -using Type = IKVM.Reflection.Type; #else -using System.Reflection; using System.Reflection.Emit; #endif @@ -50,7 +47,7 @@ sealed class RuntimePrivateInterfaceJavaMethod : RuntimeSmartJavaMethod /// /// /// - internal RuntimePrivateInterfaceJavaMethod(RuntimeJavaType declaringType, string name, string sig, MethodBase method, RuntimeJavaType returnType, RuntimeJavaType[] parameterTypes, Modifiers modifiers, MemberFlags flags) : + internal RuntimePrivateInterfaceJavaMethod(RuntimeJavaType declaringType, string name, string sig, IMethodBaseSymbol method, RuntimeJavaType returnType, RuntimeJavaType[] parameterTypes, Modifiers modifiers, MemberFlags flags) : base(declaringType, name, sig, method, returnType, parameterTypes, modifiers, flags) { diff --git a/src/IKVM.Runtime/RuntimeSimpleJavaField.cs b/src/IKVM.Runtime/RuntimeSimpleJavaField.cs index b2f055afc..bba30138f 100644 --- a/src/IKVM.Runtime/RuntimeSimpleJavaField.cs +++ b/src/IKVM.Runtime/RuntimeSimpleJavaField.cs @@ -23,6 +23,8 @@ Jeroen Frijters */ using System.Diagnostics; using System.Runtime.CompilerServices; +using IKVM.CoreLib.Symbols; + #if IMPORTER || EXPORTER using IKVM.Reflection; @@ -55,7 +57,7 @@ sealed class RuntimeSimpleJavaField : RuntimeJavaField /// /// /// - internal RuntimeSimpleJavaField(RuntimeJavaType declaringType, RuntimeJavaType fieldType, FieldInfo fi, string name, string sig, ExModifiers modifiers) : + internal RuntimeSimpleJavaField(RuntimeJavaType declaringType, RuntimeJavaType fieldType, IFieldSymbol fi, string name, string sig, ExModifiers modifiers) : base(declaringType, fieldType, name, sig, modifiers, fi) { Debug.Assert(!(fieldType == declaringType.Context.PrimitiveJavaTypeFactory.DOUBLE || fieldType == declaringType.Context.PrimitiveJavaTypeFactory.LONG) || !IsVolatile); @@ -65,12 +67,12 @@ internal RuntimeSimpleJavaField(RuntimeJavaType declaringType, RuntimeJavaType f internal override object GetValue(object obj) { - return GetField().GetValue(obj); + return GetField().AsReflection().GetValue(obj); } internal override void SetValue(object obj, object value) { - GetField().SetValue(obj, value); + GetField().AsReflection().SetValue(obj, value); } #endif @@ -134,7 +136,7 @@ protected override void EmitUnsafeGetImpl(CodeEmitter il) if (IsFinal) { il.Emit(OpCodes.Ldsflda, fi); - il.Emit(OpCodes.Call, DeclaringType.Context.Resolver.ResolveRuntimeType(typeof(RuntimeSimpleJavaField).FullName).AsReflection().GetMethod(nameof(UnsafeGetImplByRefNoInline), BindingFlags.Static | BindingFlags.NonPublic).MakeGenericMethod(fi.FieldType)); + il.Emit(OpCodes.Call, DeclaringType.Context.Resolver.ResolveRuntimeType(typeof(RuntimeSimpleJavaField).FullName).GetMethod(nameof(UnsafeGetImplByRefNoInline), System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).MakeGenericMethod(fi.FieldType)); } else { diff --git a/src/IKVM.Runtime/RuntimeSmartJavaMethod.cs b/src/IKVM.Runtime/RuntimeSmartJavaMethod.cs index 38de8ed72..0ea23f718 100644 --- a/src/IKVM.Runtime/RuntimeSmartJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimeSmartJavaMethod.cs @@ -24,6 +24,7 @@ Jeroen Frijters using System; using IKVM.Attributes; +using IKVM.CoreLib.Symbols; #if IMPORTER || EXPORTER using IKVM.Reflection; @@ -48,7 +49,7 @@ abstract class RuntimeSmartJavaMethod : RuntimeJavaMethod /// /// /// - internal RuntimeSmartJavaMethod(RuntimeJavaType declaringType, string name, string sig, MethodBase method, RuntimeJavaType returnType, RuntimeJavaType[] parameterTypes, Modifiers modifiers, MemberFlags flags) : + internal RuntimeSmartJavaMethod(RuntimeJavaType declaringType, string name, string sig, IMethodBaseSymbol method, RuntimeJavaType returnType, RuntimeJavaType[] parameterTypes, Modifiers modifiers, MemberFlags flags) : base(declaringType, name, sig, method, returnType, parameterTypes, modifiers, flags) { diff --git a/src/IKVM.Runtime/RuntimeTypicalJavaMethod.cs b/src/IKVM.Runtime/RuntimeTypicalJavaMethod.cs index c58ff7626..e2a384afa 100644 --- a/src/IKVM.Runtime/RuntimeTypicalJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimeTypicalJavaMethod.cs @@ -22,6 +22,8 @@ Jeroen Frijters */ using IKVM.Attributes; +using IKVM.CoreLib.Symbols; + #if IMPORTER || EXPORTER using IKVM.Reflection; @@ -50,7 +52,7 @@ sealed class RuntimeTypicalJavaMethod : RuntimeSmartJavaMethod /// /// /// - internal RuntimeTypicalJavaMethod(RuntimeJavaType declaringType, string name, string sig, MethodBase method, RuntimeJavaType returnType, RuntimeJavaType[] parameterTypes, Modifiers modifiers, MemberFlags flags) : + internal RuntimeTypicalJavaMethod(RuntimeJavaType declaringType, string name, string sig, IMethodBaseSymbol method, RuntimeJavaType returnType, RuntimeJavaType[] parameterTypes, Modifiers modifiers, MemberFlags flags) : base(declaringType, name, sig, method, returnType, parameterTypes, modifiers, flags) { diff --git a/src/IKVM.Runtime/RuntimeUnloadableJavaType.cs b/src/IKVM.Runtime/RuntimeUnloadableJavaType.cs index 05961e1ed..a0265537b 100644 --- a/src/IKVM.Runtime/RuntimeUnloadableJavaType.cs +++ b/src/IKVM.Runtime/RuntimeUnloadableJavaType.cs @@ -23,6 +23,8 @@ Jeroen Frijters */ using System; +using IKVM.CoreLib.Symbols; + #if IMPORTER || EXPORTER using IKVM.Reflection; using IKVM.Reflection.Emit; @@ -43,8 +45,8 @@ sealed class RuntimeUnloadableJavaType : RuntimeJavaType internal const string ContainerTypeName = "__"; - readonly Type missingType; - Type customModifier; + readonly ITypeSymbol missingType; + ITypeSymbol customModifier; /// /// Initializes a new instance. @@ -62,7 +64,7 @@ internal RuntimeUnloadableJavaType(RuntimeContext context, string name) : /// /// /// - internal RuntimeUnloadableJavaType(RuntimeContext context, Type missingType) : + internal RuntimeUnloadableJavaType(RuntimeContext context, ITypeSymbol missingType) : this(context, missingType.FullName) // TODO demangle and re-mangle appropriately { this.missingType = missingType; @@ -74,7 +76,7 @@ internal RuntimeUnloadableJavaType(RuntimeContext context, Type missingType) : /// /// /// - internal RuntimeUnloadableJavaType(RuntimeContext context, string name, Type customModifier) : + internal RuntimeUnloadableJavaType(RuntimeContext context, string name, ITypeSymbol customModifier) : this(context, name) { this.customModifier = customModifier; @@ -86,9 +88,9 @@ internal RuntimeUnloadableJavaType(RuntimeContext context, string name, Type cus internal override RuntimeJavaType EnsureLoadable(RuntimeClassLoader loader) { - var tw = loader.TryLoadClassByName(this.Name); + var tw = loader.TryLoadClassByName(Name); if (tw == null) - throw new NoClassDefFoundError(this.Name); + throw new NoClassDefFoundError(Name); return tw; } @@ -110,7 +112,7 @@ protected override void LazyPublishMembers() throw new InvalidOperationException("LazyPublishMembers called on UnloadableTypeWrapper: " + Name); } - internal override Type TypeAsTBD => throw new InvalidOperationException("get_Type called on UnloadableTypeWrapper: " + Name); + internal override ITypeSymbol TypeAsTBD => throw new InvalidOperationException("get_Type called on UnloadableTypeWrapper: " + Name); internal override RuntimeJavaType[] Interfaces { @@ -137,9 +139,9 @@ internal override void Finish() throw new InvalidOperationException("Finish called on UnloadableTypeWrapper: " + Name); } - internal Type MissingType => missingType; + internal ITypeSymbol MissingType => missingType; - internal Type CustomModifier => customModifier; + internal ITypeSymbol CustomModifier => customModifier; internal void SetCustomModifier(Type type) { diff --git a/src/IKVM.Runtime/RuntimeVolatileLongDoubleJavaField.cs b/src/IKVM.Runtime/RuntimeVolatileLongDoubleJavaField.cs index 9c5f66c0a..e2c161e13 100644 --- a/src/IKVM.Runtime/RuntimeVolatileLongDoubleJavaField.cs +++ b/src/IKVM.Runtime/RuntimeVolatileLongDoubleJavaField.cs @@ -23,6 +23,8 @@ Jeroen Frijters */ using System; +using IKVM.CoreLib.Symbols; + #if IMPORTER || EXPORTER using IKVM.Reflection; using IKVM.Reflection.Emit; @@ -49,7 +51,7 @@ sealed class RuntimeVolatileLongDoubleJavaField : RuntimeJavaField /// /// /// - internal RuntimeVolatileLongDoubleJavaField(RuntimeJavaType declaringType, RuntimeJavaType fieldType, FieldInfo fi, string name, string sig, ExModifiers modifiers) : + internal RuntimeVolatileLongDoubleJavaField(RuntimeJavaType declaringType, RuntimeJavaType fieldType, IFieldSymbol fi, string name, string sig, ExModifiers modifiers) : base(declaringType, fieldType, name, sig, modifiers, fi) { if (sig != "J" && sig != "D") diff --git a/src/IKVM.Runtime/SymbolExtensions.cs b/src/IKVM.Runtime/SymbolExtensions.cs index d49d1486e..65a6c08df 100644 --- a/src/IKVM.Runtime/SymbolExtensions.cs +++ b/src/IKVM.Runtime/SymbolExtensions.cs @@ -30,6 +30,18 @@ public static Assembly AsReflection(this IAssemblySymbol symbol) #endif } + public static Module AsReflection(this IModuleSymbol symbol) + { + if (symbol == null) + return null; + +#if IMPORTER || EXPORTER + return ((IkvmReflectionModuleSymbol)symbol).ReflectionObject; +#else + return ((ReflectionModuleSymbol)symbol).ReflectionObject; +#endif + } + public static Type AsReflection(this ITypeSymbol symbol) { if (symbol == null) @@ -42,6 +54,30 @@ public static Type AsReflection(this ITypeSymbol symbol) #endif } + public static Type[] AsReflection(this ITypeSymbol[] symbols) + { + if (symbols == null) + return null; + + var a = new Type[symbols.Length]; + for (int i = 0; i < symbols.Length; i++) + a[i] = AsReflection(symbols[i]); + + return a; + } + + public static MethodBase AsReflection(this IMethodBaseSymbol symbol) + { + if (symbol == null) + return null; + +#if IMPORTER || EXPORTER + return ((IkvmReflectionMethodBaseSymbol)symbol).ReflectionObject; +#else + return ((ReflectionMethodBaseSymbol)symbol).ReflectionObject; +#endif + } + public static ConstructorInfo AsReflection(this IConstructorSymbol symbol) { if (symbol == null) @@ -78,6 +114,18 @@ public static FieldInfo AsReflection(this IFieldSymbol symbol) #endif } + public static FieldInfo[] AsReflection(this IFieldSymbol[] symbols) + { + if (symbols == null) + return null; + + var a = new FieldInfo[symbols.Length]; + for (int i = 0; i < symbols.Length; i++) + a[i] = AsReflection(symbols[i]); + + return a; + } + public static PropertyInfo AsReflection(this IPropertySymbol symbol) { if (symbol == null) @@ -90,6 +138,18 @@ public static PropertyInfo AsReflection(this IPropertySymbol symbol) #endif } + public static PropertyInfo[] AsReflection(this IPropertySymbol[] symbols) + { + if (symbols == null) + return null; + + var a = new PropertyInfo[symbols.Length]; + for (int i = 0; i < symbols.Length; i++) + a[i] = AsReflection(symbols[i]); + + return a; + } + } } diff --git a/src/IKVM.Runtime/Types.cs b/src/IKVM.Runtime/Types.cs index e08593213..f790f8172 100644 --- a/src/IKVM.Runtime/Types.cs +++ b/src/IKVM.Runtime/Types.cs @@ -22,7 +22,8 @@ Jeroen Frijters */ using System; -using System.Threading; + +using IKVM.CoreLib.Symbols; #if IMPORTER || EXPORTER using Type = IKVM.Reflection.Type; @@ -39,34 +40,34 @@ class Types readonly RuntimeContext context; - Type typeOfObject; - Type typeOfValueType; - Type typeOfEnum; - Type typeOfType; - Type typeOfString; - Type typeOfException; - Type typeOfArray; - Type typeOfAttribute; - Type typeOfDelegate; - Type typeOfMulticastDelegate; - Type typeOfRuntimeTypeHandle; - - Type typeOfIntPtr; - Type typeOfVoid; - Type typeOfBoolean; - Type typeOfByte; - Type typeOfSByte; - Type typeOfChar; - Type typeOfInt16; - Type typeOfUInt16; - Type typeOfInt32; - Type typeOfUInt32; - Type typeOfInt64; - Type typeOfUInt64; - Type typeOfSingle; - Type typeOfDouble; - - Type typeOfIsVolatile; + ITypeSymbol typeOfObject; + ITypeSymbol typeOfValueType; + ITypeSymbol typeOfEnum; + ITypeSymbol typeOfType; + ITypeSymbol typeOfString; + ITypeSymbol typeOfException; + ITypeSymbol typeOfArray; + ITypeSymbol typeOfAttribute; + ITypeSymbol typeOfDelegate; + ITypeSymbol typeOfMulticastDelegate; + ITypeSymbol typeOfRuntimeTypeHandle; + + ITypeSymbol typeOfIntPtr; + ITypeSymbol typeOfVoid; + ITypeSymbol typeOfBoolean; + ITypeSymbol typeOfByte; + ITypeSymbol typeOfSByte; + ITypeSymbol typeOfChar; + ITypeSymbol typeOfInt16; + ITypeSymbol typeOfUInt16; + ITypeSymbol typeOfInt32; + ITypeSymbol typeOfUInt32; + ITypeSymbol typeOfInt64; + ITypeSymbol typeOfUInt64; + ITypeSymbol typeOfSingle; + ITypeSymbol typeOfDouble; + + ITypeSymbol typeOfIsVolatile; /// /// Initializes a new instance. @@ -83,62 +84,62 @@ public Types(RuntimeContext context) /// /// /// - Type Import(System.Type type) + ITypeSymbol Import(System.Type type) { - return context.Resolver.ResolveCoreType(type.FullName).AsReflection(); + return context.Resolver.ResolveCoreType(type.FullName); } - public Type Object => typeOfObject ??= Import(typeof(System.Object)); + public ITypeSymbol Object => typeOfObject ??= Import(typeof(System.Object)); - public Type ValueType => typeOfValueType ??= Import(typeof(System.ValueType)); + public ITypeSymbol ValueType => typeOfValueType ??= Import(typeof(System.ValueType)); - public Type Enum => typeOfEnum ??= Import(typeof(System.Enum)); + public ITypeSymbol Enum => typeOfEnum ??= Import(typeof(System.Enum)); - public Type Type => typeOfType ??= Import(typeof(System.Type)); + public ITypeSymbol Type => typeOfType ??= Import(typeof(System.Type)); - public Type String => typeOfString ??= Import(typeof(System.String)); + public ITypeSymbol String => typeOfString ??= Import(typeof(System.String)); - public Type Exception => typeOfException ??= Import(typeof(System.Exception)); + public ITypeSymbol Exception => typeOfException ??= Import(typeof(System.Exception)); - public Type Array => typeOfArray ??= Import(typeof(System.Array)); + public ITypeSymbol Array => typeOfArray ??= Import(typeof(System.Array)); - public Type Attribute => typeOfAttribute ??= Import(typeof(System.Attribute)); + public ITypeSymbol Attribute => typeOfAttribute ??= Import(typeof(System.Attribute)); - public Type Delegate => typeOfDelegate ??= Import(typeof(System.Delegate)); + public ITypeSymbol Delegate => typeOfDelegate ??= Import(typeof(System.Delegate)); - public Type MulticastDelegate => typeOfMulticastDelegate ??= Import(typeof(System.MulticastDelegate)); + public ITypeSymbol MulticastDelegate => typeOfMulticastDelegate ??= Import(typeof(System.MulticastDelegate)); - public Type RuntimeTypeHandle => typeOfRuntimeTypeHandle ??= Import(typeof(System.RuntimeTypeHandle)); + public ITypeSymbol RuntimeTypeHandle => typeOfRuntimeTypeHandle ??= Import(typeof(System.RuntimeTypeHandle)); - public Type IntPtr => typeOfIntPtr ??= Import(typeof(IntPtr)); + public ITypeSymbol IntPtr => typeOfIntPtr ??= Import(typeof(IntPtr)); - public Type Void => typeOfVoid ??= Import(typeof(void)); + public ITypeSymbol Void => typeOfVoid ??= Import(typeof(void)); - public Type Boolean => typeOfBoolean ??= Import(typeof(bool)); + public ITypeSymbol Boolean => typeOfBoolean ??= Import(typeof(bool)); - public Type Byte => typeOfByte ??= Import(typeof(byte)); + public ITypeSymbol Byte => typeOfByte ??= Import(typeof(byte)); - public Type SByte => typeOfSByte ??= Import(typeof(sbyte)); + public ITypeSymbol SByte => typeOfSByte ??= Import(typeof(sbyte)); - public Type Char => typeOfChar ??= Import(typeof(char)); + public ITypeSymbol Char => typeOfChar ??= Import(typeof(char)); - public Type Int16 => typeOfInt16 ??= Import(typeof(short)); + public ITypeSymbol Int16 => typeOfInt16 ??= Import(typeof(short)); - public Type UInt16 => typeOfUInt16 ??= Import(typeof(ushort)); + public ITypeSymbol UInt16 => typeOfUInt16 ??= Import(typeof(ushort)); - public Type Int32 => typeOfInt32 ??= Import(typeof(int)); + public ITypeSymbol Int32 => typeOfInt32 ??= Import(typeof(int)); - public Type UInt32 => typeOfUInt32 ??= Import(typeof(uint)); + public ITypeSymbol UInt32 => typeOfUInt32 ??= Import(typeof(uint)); - public Type Int64 => typeOfInt64 ??= Import(typeof(long)); + public ITypeSymbol Int64 => typeOfInt64 ??= Import(typeof(long)); - public Type UInt64 => typeOfUInt64 ??= Import(typeof(ulong)); + public ITypeSymbol UInt64 => typeOfUInt64 ??= Import(typeof(ulong)); - public Type Single => typeOfSingle ??= Import(typeof(float)); + public ITypeSymbol Single => typeOfSingle ??= Import(typeof(float)); - public Type Double => typeOfDouble ??= Import(typeof(double)); + public ITypeSymbol Double => typeOfDouble ??= Import(typeof(double)); - public Type IsVolatile => typeOfIsVolatile ??= Import(typeof(System.Runtime.CompilerServices.IsVolatile)); + public ITypeSymbol IsVolatile => typeOfIsVolatile ??= Import(typeof(System.Runtime.CompilerServices.IsVolatile)); } diff --git a/src/IKVM.Runtime/Vfs/VfsAssemblyClassDirectory.cs b/src/IKVM.Runtime/Vfs/VfsAssemblyClassDirectory.cs index 6ac29415a..5e8cb20fc 100644 --- a/src/IKVM.Runtime/Vfs/VfsAssemblyClassDirectory.cs +++ b/src/IKVM.Runtime/Vfs/VfsAssemblyClassDirectory.cs @@ -109,7 +109,7 @@ IEnumerable GetAssemblyTypes() } catch { - return Type.EmptyTypes; + return []; } } diff --git a/src/IKVM.Runtime/compiler.cs b/src/IKVM.Runtime/compiler.cs index 9efe8b734..72f7e81b4 100644 --- a/src/IKVM.Runtime/compiler.cs +++ b/src/IKVM.Runtime/compiler.cs @@ -118,11 +118,11 @@ public CompilerFactory(RuntimeContext context, bool bootstrap) public MethodInfo FixateExceptionMethod => fixateExceptionMethod ??= bootstrap ? (MethodInfo)Throwable.GetMethodWrapper("__", "(Ljava.lang.Throwable;)Ljava.lang.Throwable;", false).GetMethod() : Throwable.TypeAsBaseType.GetMethod("__", new Type[] { context.Types.Exception }); - public MethodInfo SuppressFillInStackTraceMethod => suppressFillInStackTraceMethod ??= bootstrap ? (MethodInfo)Throwable.GetMethodWrapper("__", "()V", false).GetMethod() : Throwable.TypeAsBaseType.GetMethod("__", Type.EmptyTypes); + public MethodInfo SuppressFillInStackTraceMethod => suppressFillInStackTraceMethod ??= bootstrap ? (MethodInfo)Throwable.GetMethodWrapper("__", "()V", false).GetMethod() : Throwable.TypeAsBaseType.GetMethod("__", []); public MethodInfo GetTypeFromHandleMethod => getTypeFromHandleMethod ??= context.Types.Type.GetMethod("GetTypeFromHandle", BindingFlags.Static | BindingFlags.Public, null, [context.Types.RuntimeTypeHandle], null); - public MethodInfo GetTypeMethod => getTypeMethod ??= context.Types.Object.GetMethod("GetType", BindingFlags.Public | BindingFlags.Instance, null, Type.EmptyTypes, null); + public MethodInfo GetTypeMethod => getTypeMethod ??= context.Types.Object.GetMethod("GetType", BindingFlags.Public | BindingFlags.Instance, null, [], null); public MethodInfo KeepAliveMethod => keepAliveMethod ??= context.Resolver.ResolveCoreType(typeof(GC).FullName).AsReflection().GetMethod("KeepAlive", BindingFlags.Static | BindingFlags.Public, null, [context.Types.Object], null); @@ -2761,7 +2761,7 @@ internal static void Emit(Compiler compiler, ClassFile.ConstantPoolItemInvokeDyn static MethodBuilder CreateBootstrapStub(Compiler compiler, ClassFile.ConstantPoolItemInvokeDynamic cpi, Type delegateType, TypeBuilder tb, FieldBuilder fb, MethodInfo methodGetTarget) { var typeofCallSite = compiler.finish.Context.ClassLoaderFactory.LoadClassCritical("java.lang.invoke.CallSite").TypeAsSignatureType; - var args = Type.EmptyTypes; + var args = []; if (delegateType.IsGenericType) { diff --git a/src/IKVM.Tools.Exporter/IKVM.Tools.Exporter.csproj b/src/IKVM.Tools.Exporter/IKVM.Tools.Exporter.csproj index 00fd909a0..d3db518a9 100644 --- a/src/IKVM.Tools.Exporter/IKVM.Tools.Exporter.csproj +++ b/src/IKVM.Tools.Exporter/IKVM.Tools.Exporter.csproj @@ -93,6 +93,7 @@ + diff --git a/src/IKVM.Tools.Importer/FakeTypes.cs b/src/IKVM.Tools.Importer/FakeTypes.cs index dce91bf0f..61bf501de 100644 --- a/src/IKVM.Tools.Importer/FakeTypes.cs +++ b/src/IKVM.Tools.Importer/FakeTypes.cs @@ -23,12 +23,11 @@ Jeroen Frijters */ using System; +using IKVM.CoreLib.Symbols; using IKVM.Reflection; using IKVM.Reflection.Emit; using IKVM.Runtime; -using Type = IKVM.Reflection.Type; - namespace IKVM.Tools.Importer { @@ -37,11 +36,11 @@ class FakeTypes readonly RuntimeContext context; - Type genericEnumEnumType; - Type genericDelegateInterfaceType; - Type genericAttributeAnnotationType; - Type genericAttributeAnnotationMultipleType; - Type genericAttributeAnnotationReturnValueType; + ITypeSymbol genericEnumEnumType; + ITypeSymbol genericDelegateInterfaceType; + ITypeSymbol genericAttributeAnnotationType; + ITypeSymbol genericAttributeAnnotationMultipleType; + ITypeSymbol genericAttributeAnnotationReturnValueType; /// /// Initializes a new instance. @@ -52,27 +51,27 @@ public FakeTypes(RuntimeContext context) this.context = context ?? throw new ArgumentNullException(nameof(context)); } - internal Type GetEnumType(Type enumType) + internal ITypeSymbol GetEnumType(ITypeSymbol enumType) { return genericEnumEnumType.MakeGenericType(enumType); } - internal Type GetDelegateType(Type delegateType) + internal ITypeSymbol GetDelegateType(ITypeSymbol delegateType) { return genericDelegateInterfaceType.MakeGenericType(delegateType); } - internal Type GetAttributeType(Type attributeType) + internal ITypeSymbol GetAttributeType(ITypeSymbol attributeType) { return genericAttributeAnnotationType.MakeGenericType(attributeType); } - internal Type GetAttributeMultipleType(Type attributeType) + internal ITypeSymbol GetAttributeMultipleType(ITypeSymbol attributeType) { return genericAttributeAnnotationMultipleType.MakeGenericType(attributeType); } - internal Type GetAttributeReturnValueType(Type attributeType) + internal ITypeSymbol GetAttributeReturnValueType(ITypeSymbol attributeType) { return genericAttributeAnnotationReturnValueType.MakeGenericType(attributeType); } @@ -80,8 +79,8 @@ internal Type GetAttributeReturnValueType(Type attributeType) internal void Create(ModuleBuilder modb, RuntimeClassLoader loader) { var tb = modb.DefineType(RuntimeManagedJavaType.GenericDelegateInterfaceTypeName, TypeAttributes.Interface | TypeAttributes.Abstract | TypeAttributes.Public); - tb.DefineGenericParameters("T")[0].SetBaseTypeConstraint(context.Types.MulticastDelegate); - genericDelegateInterfaceType = tb.CreateType(); + tb.DefineGenericParameters("T")[0].SetBaseTypeConstraint(context.Types.MulticastDelegate.AsReflection()); + genericDelegateInterfaceType = context.Resolver.ResolveType(tb.CreateType()); genericAttributeAnnotationType = CreateAnnotationType(modb, RuntimeManagedJavaType.GenericAttributeAnnotationTypeName); genericAttributeAnnotationMultipleType = CreateAnnotationType(modb, RuntimeManagedJavaType.GenericAttributeAnnotationMultipleTypeName); @@ -91,36 +90,36 @@ internal void Create(ModuleBuilder modb, RuntimeClassLoader loader) internal void Finish(RuntimeClassLoader loader) { - var tb = (TypeBuilder)genericEnumEnumType; + var tb = (TypeBuilder)genericEnumEnumType.AsReflection(); var enumTypeWrapper = loader.LoadClassByName("java.lang.Enum"); enumTypeWrapper.Finish(); - tb.SetParent(enumTypeWrapper.TypeAsBaseType); - var ilgen = context.CodeEmitterFactory.Create(ReflectUtil.DefineConstructor(tb, MethodAttributes.Private, new Type[] { context.Types.String, context.Types.Int32 })); + tb.SetParent(enumTypeWrapper.TypeAsBaseType.AsReflection()); + var ilgen = context.CodeEmitterFactory.Create(ReflectUtil.DefineConstructor(tb, MethodAttributes.Private, [context.Types.String.AsReflection(), context.Types.Int32.AsReflection()])); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Ldarg_1); ilgen.Emit(OpCodes.Ldarg_2); enumTypeWrapper.GetMethodWrapper("", "(Ljava.lang.String;I)V", false).EmitCall(ilgen); ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); - genericEnumEnumType = tb.CreateType(); + genericEnumEnumType = context.Resolver.ResolveType(tb.CreateType()); } - private void CreateEnumEnum(ModuleBuilder modb, RuntimeClassLoader loader) + void CreateEnumEnum(ModuleBuilder modb, RuntimeClassLoader loader) { var tb = modb.DefineType(RuntimeManagedJavaType.GenericEnumEnumTypeName, TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.Public); var gtpb = tb.DefineGenericParameters("T")[0]; - gtpb.SetBaseTypeConstraint(context.Types.Enum); - genericEnumEnumType = tb; + gtpb.SetBaseTypeConstraint(context.Types.Enum.AsReflection()); + genericEnumEnumType = context.Resolver.ResolveType(tb); } - private Type CreateAnnotationType(ModuleBuilder modb, string name) + ITypeSymbol CreateAnnotationType(ModuleBuilder modb, string name) { var tb = modb.DefineType(name, TypeAttributes.Interface | TypeAttributes.Abstract | TypeAttributes.Public); - tb.DefineGenericParameters("T")[0].SetBaseTypeConstraint(context.Types.Attribute); - return tb.CreateType(); + tb.DefineGenericParameters("T")[0].SetBaseTypeConstraint(context.Types.Attribute.AsReflection()); + return context.Resolver.ResolveType(tb.CreateType()); } - internal void Load(Assembly assembly) + internal void Load(IAssemblySymbol assembly) { genericEnumEnumType = assembly.GetType(RuntimeManagedJavaType.GenericEnumEnumTypeName); genericDelegateInterfaceType = assembly.GetType(RuntimeManagedJavaType.GenericDelegateInterfaceTypeName); diff --git a/src/IKVM.Tools.Importer/ImportClassLoader.cs b/src/IKVM.Tools.Importer/ImportClassLoader.cs index d3251bd5f..8bbc52ed5 100644 --- a/src/IKVM.Tools.Importer/ImportClassLoader.cs +++ b/src/IKVM.Tools.Importer/ImportClassLoader.cs @@ -134,9 +134,18 @@ internal void AddReference(ImportClassLoader ccl) peerReferences.Add(ccl); } - internal AssemblyName GetAssemblyName() + internal System.Reflection.AssemblyName GetAssemblyName() { - return assemblyBuilder.GetName(); + var src = assemblyBuilder.GetName(); + return new System.Reflection.AssemblyName + { + Name = src.Name, + Version = src.Version, + CultureName = src.CultureName, + HashAlgorithm = (System.Configuration.Assemblies.AssemblyHashAlgorithm)src.HashAlgorithm, + Flags = (System.Reflection.AssemblyNameFlags)src.Flags, + ContentType = (System.Reflection.AssemblyContentType)src.ContentType, + }; } private static PermissionSet Combine(PermissionSet p1, PermissionSet p2) diff --git a/src/IKVM.Tools.Importer/StaticCompiler.cs b/src/IKVM.Tools.Importer/StaticCompiler.cs index 0f45623fc..f5e3f7cb7 100644 --- a/src/IKVM.Tools.Importer/StaticCompiler.cs +++ b/src/IKVM.Tools.Importer/StaticCompiler.cs @@ -30,6 +30,7 @@ Jeroen Frijters using System.Reflection.PortableExecutable; using IKVM.CoreLib.Diagnostics; +using IKVM.CoreLib.Symbols; using IKVM.Reflection; using IKVM.Reflection.Diagnostics; using IKVM.Runtime; @@ -204,15 +205,14 @@ internal Type GetType(RuntimeClassLoader loader, string name) internal static void LinkageError(string msg, RuntimeJavaType actualType, RuntimeJavaType expectedType, params object[] values) { - object[] args = new object[values.Length + 2]; + var args = new object[values.Length + 2]; values.CopyTo(args, 2); args[0] = AssemblyQualifiedName(actualType); args[1] = AssemblyQualifiedName(expectedType); - string str = string.Format(msg, args); + + var str = string.Format(msg, args); if (actualType is RuntimeUnloadableJavaType && (expectedType is RuntimeManagedByteCodeJavaType || expectedType is RuntimeManagedJavaType)) - { - str += string.Format("\n\t(Please add a reference to {0})", expectedType.TypeAsBaseType.Assembly.Location); - } + str += string.Format("\n\t(Please add a reference to {0})", expectedType.TypeAsBaseType.Assembly.AsReflection().Location); throw new FatalCompilerErrorException(DiagnosticEvent.LinkageError(str)); } @@ -231,10 +231,10 @@ static string AssemblyQualifiedName(RuntimeJavaType javaType) return javaType.Name + " (unknown assembly)"; } - internal void IssueMissingTypeMessage(Type type) + internal void IssueMissingTypeMessage(ITypeSymbol type) { type = ReflectUtil.GetMissingType(type); - if (type.Assembly.__IsMissing) + if (type.Assembly.IsMissing) diagnostics.MissingReference(type.FullName, type.Assembly.FullName); else diagnostics.MissingType(type.FullName, type.Assembly.FullName); From 947bb0e2d1e18f026be98fb14b8bff72d7b04a52 Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Sun, 15 Sep 2024 17:44:55 -0500 Subject: [PATCH 03/51] Replace underlying stuff when completing a type. --- .../Reflection/ReflectionSymbolTests.cs | 22 +++ .../AssemblyNameEqualityComparer.cs | 130 ++++++++++++++++++ .../Symbols/Emit/IAssemblySymbolBuilder.cs | 5 + .../Symbols/Emit/IModuleSymbolBuilder.cs | 5 + .../Symbols/Emit/ITypeSymbolBuilder.cs | 2 +- .../Emit/ReflectionAssemblySymbolBuilder.cs | 18 +++ .../Emit/ReflectionModuleSymbolBuilder.cs | 12 ++ .../Emit/ReflectionParameterBuilderInfo.cs | 43 ++++++ .../Emit/ReflectionTypeSymbolBuilder.cs | 16 ++- .../Reflection/ReflectionAssemblySymbol.cs | 48 ++++--- .../Reflection/ReflectionConstructorSymbol.cs | 21 ++- .../Reflection/ReflectionEventSymbol.cs | 12 +- .../Reflection/ReflectionFieldSymbol.cs | 12 +- .../Reflection/ReflectionMemberSymbol.cs | 13 +- .../Reflection/ReflectionMethodBaseSymbol.cs | 16 ++- .../Reflection/ReflectionModuleSymbol.cs | 24 +++- .../Reflection/ReflectionParameterSymbol.cs | 80 +++-------- .../Reflection/ReflectionPropertySymbol.cs | 15 +- .../Reflection/ReflectionSymbolContext.cs | 31 ++++- .../Reflection/ReflectionTypeSymbol.cs | 23 +++- src/IKVM.CoreLib/System/TypeExtensions.cs | 33 +++-- 21 files changed, 475 insertions(+), 106 deletions(-) create mode 100644 src/IKVM.CoreLib/Reflection/AssemblyNameEqualityComparer.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionParameterBuilderInfo.cs diff --git a/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs b/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs index efbd5e284..f01a0bf35 100644 --- a/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs +++ b/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs @@ -382,6 +382,28 @@ public void CanResolveMultipleEventBuilders() event2Symbol.Should().BeSameAs(c.GetOrCreateEventSymbol(event2)); } + [TestMethod] + public void CanCompleteTypeBuilder() + { + var c = new ReflectionSymbolContext(); + var a = new ReflectionAssemblySymbolBuilder(c, AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.RunAndCollect)); + + var moduleBuilder = a.DefineModule("DynamicModule"); + var moduleSymbol = moduleBuilder.Symbol; + + var type1Builder = moduleBuilder.DefineType("DynamicType1"); + var type1Symbol = type1Builder.Symbol; + type1Symbol.Should().BeOfType(); + + type1Builder.Complete(); + var type1SymbolAgain = type1Builder.Symbol; + type1SymbolAgain.Should().BeSameAs(type1Symbol); + type1SymbolAgain.Name.Should().Be("DynamicType1"); + + // check that we can relookup type + moduleSymbol.GetType("DynamicType1").Should().BeSameAs(type1SymbolAgain); + } + [TestMethod] public void CanCreateAndResolveDynamicMethodOnModule() { diff --git a/src/IKVM.CoreLib/Reflection/AssemblyNameEqualityComparer.cs b/src/IKVM.CoreLib/Reflection/AssemblyNameEqualityComparer.cs new file mode 100644 index 000000000..fe1a16f44 --- /dev/null +++ b/src/IKVM.CoreLib/Reflection/AssemblyNameEqualityComparer.cs @@ -0,0 +1,130 @@ +using System; +using System.Collections.Generic; +using System.Reflection; + +namespace IKVM.CoreLib.Reflection +{ + + class AssemblyNameEqualityComparer : IEqualityComparer + { + + /// + /// Gets the default instance of this comparer. + /// + public static readonly AssemblyNameEqualityComparer Instance = new(); + + /// + /// Initializes a new instance. + /// + public AssemblyNameEqualityComparer() + { + + } + + + /// + public bool Equals(AssemblyName? x, AssemblyName? y) + { + // this expects non-null AssemblyName + if (x == null || y == null) + return false; + + if (ReferenceEquals(x, y)) + return true; + + if (x.Name != null && y.Name != null) + { + if (string.Compare(x.Name, y.Name, StringComparison.OrdinalIgnoreCase) != 0) + return false; + } + else if (!(x.Name == null && y.Name == null)) + { + return false; + } + + if (x.Version != null && y.Version != null) + { + if (x.Version != y.Version) + return false; + } + else if (!(x.Version == null && y.Version == null)) + { + return false; + } + + if (x.CultureInfo != null && y.CultureInfo != null) + { + if (!x.CultureInfo.Equals(y.CultureInfo)) + return false; + } + else if (!(x.CultureInfo == null && y.CultureInfo == null)) + { + return false; + } + + var xArray = x.GetPublicKeyToken(); + var yArray = y.GetPublicKeyToken(); + if (!IsSameKeyToken(xArray, yArray)) + return false; + + return true; + } + + /// + public int GetHashCode(AssemblyName obj) + { + int hashcode = 0; + + if (obj.Name != null) + hashcode ^= obj.Name.GetHashCode(); + + if (obj.Version != null) + hashcode ^= obj.Version.GetHashCode(); + + if (obj.CultureInfo != null) + hashcode ^= obj.CultureInfo.GetHashCode(); + + var objArray = obj.GetPublicKeyToken(); + if (objArray != null) + { + // distinguishing no PKToken from "PKToken = null" which is an array of length=0 + hashcode ^= objArray.Length.GetHashCode() + 1; + if (objArray.Length > 0) + hashcode ^= BitConverter.ToUInt64(objArray, 0).GetHashCode(); + } + + return hashcode; + } + + static bool IsSameKeyToken(byte[]? reqKeyToken, byte[]? curKeyToken) + { + bool isSame = false; + + if (reqKeyToken == null && curKeyToken == null) + { + // Both Key Tokens are not set, treat them as same. + isSame = true; + } + else if (reqKeyToken != null && curKeyToken != null) + { + // Both KeyTokens are set. + if (reqKeyToken.Length == curKeyToken.Length) + { + isSame = true; + for (int i = 0; i < reqKeyToken.Length; i++) + { + if (reqKeyToken[i] != curKeyToken[i]) + { + isSame = false; + break; + } + } + } + } + + return isSame; + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Emit/IAssemblySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IAssemblySymbolBuilder.cs index c89940b3a..e4d72dc17 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/IAssemblySymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/IAssemblySymbolBuilder.cs @@ -24,6 +24,11 @@ interface IAssemblySymbolBuilder : ISymbolBuilder /// void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute); + /// + /// Finishes all modules of the assembly, updating the associated symbols. + /// + void Complete(); + } } diff --git a/src/IKVM.CoreLib/Symbols/Emit/IModuleSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IModuleSymbolBuilder.cs index 5d059cc09..4ffa0fdb1 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/IModuleSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/IModuleSymbolBuilder.cs @@ -85,6 +85,11 @@ interface IModuleSymbolBuilder : ISymbolBuilder /// void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute); + /// + /// Finishes all types of the module, updating the associated symbols. + /// + void Complete(); + } } diff --git a/src/IKVM.CoreLib/Symbols/Emit/ITypeSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/ITypeSymbolBuilder.cs index ebe0c5915..7bed9beb7 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/ITypeSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/ITypeSymbolBuilder.cs @@ -319,7 +319,7 @@ interface ITypeSymbolBuilder : ISymbolBuilder /// /// Finishes the type, updating the associated symbol. /// - void Finish(); + void Complete(); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs index ee8c1f687..25f8018f3 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs @@ -44,6 +44,24 @@ public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) _builder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).ReflectionBuilder); } + /// + public void Complete() + { + foreach (var module in _builder.GetModules()) + { + if (module is ModuleBuilder moduleBuilder) + { + moduleBuilder.CreateGlobalFunctions(); + + foreach (var type in moduleBuilder.GetTypes()) + if (type is TypeBuilder typeBuilder) + if (typeBuilder.IsCreated() == false) + if (typeBuilder.CreateType() is { } t) + ReflectionSymbol.ResolveTypeSymbol(t).Complete(t); + } + } + } + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionModuleSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionModuleSymbolBuilder.cs index 83f3a6ea1..0861c2c9e 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionModuleSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionModuleSymbolBuilder.cs @@ -81,6 +81,18 @@ public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) _builder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).ReflectionBuilder); } + /// + public void Complete() + { + _builder.CreateGlobalFunctions(); + + foreach (var type in _builder.GetTypes()) + if (type is TypeBuilder typeBuilder) + if (typeBuilder.IsCreated() == false) + if (typeBuilder.CreateType() is { } t) + ReflectionSymbol.ResolveTypeSymbol(t).Complete(t); + } + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionParameterBuilderInfo.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionParameterBuilderInfo.cs new file mode 100644 index 000000000..bb28d0082 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionParameterBuilderInfo.cs @@ -0,0 +1,43 @@ +using System; +using System.Reflection; +using System.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.Reflection.Emit +{ + + /// + /// Fake implementation that wraps a , which does not extend . + /// + class ReflectionParameterBuilderInfo : ParameterInfo + { + + readonly ParameterBuilder _builder; + + /// + /// Initialies a new instance. + /// + /// + /// + public ReflectionParameterBuilderInfo(ParameterBuilder builder) + { + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + } + + /// + public override ParameterAttributes Attributes => (ParameterAttributes)_builder.Attributes; + + /// + public override MemberInfo Member => _builder.GetMethodBuilder(); + + /// + public override string? Name => _builder.Name; + + /// + public override int Position => _builder.Position; + + /// + public override int MetadataToken => _builder.GetMetadataToken(); + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs index 197211f65..586138398 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs @@ -227,10 +227,20 @@ public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) } /// - public void Finish() + void Complete(Type type) { - var sym = ReflectionSymbol; - sym.FinishType(_builder.CreateType()); + ReflectionSymbol.Complete(type); + } + + /// + public void Complete() + { + if (_builder.IsCreated() == false) + { + var type = _builder.CreateType(); + if (type != null) + Complete(type); + } } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs index 8f5120253..ef66d94d1 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs @@ -3,9 +3,11 @@ using System.Diagnostics; using System.Linq; using System.Reflection; -using System.Runtime.CompilerServices; +using System.Threading; -using IKVM.CoreLib.Symbols.Reflection.Emit; +using IKVM.CoreLib.Collections; +using IKVM.CoreLib.Reflection; +using IKVM.CoreLib.Threading; namespace IKVM.CoreLib.Symbols.Reflection { @@ -13,8 +15,10 @@ namespace IKVM.CoreLib.Symbols.Reflection class ReflectionAssemblySymbol : ReflectionSymbol, IAssemblySymbol { - readonly Assembly _assembly; - readonly ConditionalWeakTable _modules = new(); + Assembly _assembly; + + IndexRangeDictionary _moduleSymbols = new(initialCapacity: 1, maxCapacity: 32); + ReaderWriterLockSlim? _moduleLock; /// /// Initializes a new instance. @@ -40,21 +44,22 @@ internal ReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) if (module is null) throw new ArgumentNullException(nameof(module)); - Debug.Assert(module.Assembly == _assembly); - return _modules.GetValue(module, _ => new ReflectionModuleSymbol(Context, _)); - } + Debug.Assert(AssemblyNameEqualityComparer.Instance.Equals(module.Assembly.GetName(), _assembly.GetName())); - /// - /// Gets or creates the cached for the module. - /// - /// - /// - internal ReflectionModuleSymbol GetOrCreateModuleSymbol(ReflectionModuleSymbolBuilder module) - { - if (module is null) - throw new ArgumentNullException(nameof(module)); + // create lock on demand + if (_moduleLock == null) + lock (this) + _moduleLock ??= new ReaderWriterLockSlim(); - throw new NotImplementedException(); + using (_moduleLock.CreateUpgradeableReadLock()) + { + var row = module.GetMetadataTokenRowNumberSafe(); + if (_moduleSymbols[row] == null) + using (_moduleLock.CreateWriteLock()) + return _moduleSymbols[row] ??= new ReflectionModuleSymbol(Context, this, module); + else + return _moduleSymbols[row] ?? throw new InvalidOperationException(); + } } /// @@ -168,6 +173,15 @@ public bool IsDefined(ITypeSymbol attributeType, bool inherit = false) return _assembly.IsDefined(((ReflectionTypeSymbol)attributeType).ReflectionObject, false); } + /// + /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. + /// + /// + internal void Complete(Assembly assembly) + { + Context.GetOrCreateAssemblySymbol(_assembly = assembly); + } + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionConstructorSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionConstructorSymbol.cs index aba5e173f..b4d8759e7 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionConstructorSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionConstructorSymbol.cs @@ -1,4 +1,5 @@ -using System.Reflection; +using System; +using System.Reflection; namespace IKVM.CoreLib.Symbols.Reflection { @@ -10,17 +11,29 @@ class ReflectionConstructorSymbol : ReflectionMethodBaseSymbol, IConstructorSymb /// Initializes a new instance. /// /// - /// /// /// - public ReflectionConstructorSymbol(ReflectionSymbolContext context, ReflectionModuleSymbol module, ReflectionTypeSymbol type, ConstructorInfo ctor) : - base(context, module, type, ctor) + public ReflectionConstructorSymbol(ReflectionSymbolContext context, ReflectionTypeSymbol type, ConstructorInfo ctor) : + base(context, type, ctor) { } + /// + /// Gets the underlying wrapped by this symbol. + /// internal new ConstructorInfo ReflectionObject => (ConstructorInfo)base.ReflectionObject; + + /// + /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. + /// + /// + internal void Complete(ConstructorInfo type) + { + base.Complete(type); + } + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionEventSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionEventSymbol.cs index 080785635..81bcd813c 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionEventSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionEventSymbol.cs @@ -7,7 +7,7 @@ namespace IKVM.CoreLib.Symbols.Reflection class ReflectionEventSymbol : ReflectionMemberSymbol, IEventSymbol { - readonly EventInfo _event; + EventInfo _event; /// /// Initializes a new instance. @@ -92,6 +92,16 @@ public IMethodSymbol[] GetOtherMethods(bool nonPublic) return ResolveMethodSymbols(_event.GetOtherMethods(nonPublic)); } + /// + /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. + /// + /// + internal void Complete(EventInfo @event) + { + ResolveEventSymbol(_event = @event); + base.Complete(_event); + } + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionFieldSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionFieldSymbol.cs index 61bfb5476..ca18fda1a 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionFieldSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionFieldSymbol.cs @@ -7,7 +7,7 @@ namespace IKVM.CoreLib.Symbols.Reflection class ReflectionFieldSymbol : ReflectionMemberSymbol, IFieldSymbol { - readonly FieldInfo _field; + FieldInfo _field; /// /// Initializes a new instance. @@ -100,6 +100,16 @@ public ITypeSymbol[] GetRequiredCustomModifiers() return _field.GetRawConstantValue(); } + /// + /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. + /// + /// + internal void Complete(FieldInfo field) + { + ResolveFieldSymbol(_field = field); + base.Complete(_field); + } + } } \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs index f4bbd6c78..52b19f985 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs @@ -42,7 +42,7 @@ static T[] Concat(List? list) readonly ReflectionModuleSymbol _containingModule; readonly ReflectionTypeSymbol? _containingType; - readonly MemberInfo _member; + MemberInfo _member; CustomAttribute[]? _customAttributes; CustomAttribute[]? _inheritedCustomAttributes; @@ -252,6 +252,17 @@ public virtual bool IsDefined(ITypeSymbol attributeType, bool inherit = false) return _member.IsDefined(((ReflectionTypeSymbol)attributeType).ReflectionObject, inherit); } + /// + /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. + /// + /// + protected void Complete(MemberInfo member) + { + ResolveMemberSymbol(_member = member); + _customAttributes = null; + _inheritedCustomAttributes = null; + } + } } \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodBaseSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodBaseSymbol.cs index 8bd357f1d..911580f57 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodBaseSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodBaseSymbol.cs @@ -7,7 +7,7 @@ namespace IKVM.CoreLib.Symbols.Reflection abstract class ReflectionMethodBaseSymbol : ReflectionMemberSymbol, IMethodBaseSymbol { - readonly MethodBase _method; + MethodBase _method; /// /// Initializes a new instance. @@ -114,6 +114,20 @@ public IParameterSymbol[] GetParameters() return ResolveParameterSymbols(_method.GetParameters()); } + /// + /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. + /// + /// + internal void Complete(MethodBase method) + { + ResolveMethodBaseSymbol(_method = method); + base.Complete(_method); + + foreach (var i in _method.GetParameters()) + ResolveParameterSymbol(i).Complete(i); + + } + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs index 2f7a1cff7..40e757344 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs @@ -34,7 +34,8 @@ static bool IsTypeDefinition(Type type) const BindingFlags DefaultBindingFlags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance; - readonly Module _module; + readonly ReflectionAssemblySymbol _containingAssembly; + Module _module; IndexRangeDictionary _typeTable = new(maxCapacity: MAX_CAPACITY); IndexRangeDictionary _typeSymbols = new(maxCapacity: MAX_CAPACITY); @@ -64,14 +65,21 @@ static bool IsTypeDefinition(Type type) /// Initializes a new instance. /// /// + /// /// /// - public ReflectionModuleSymbol(ReflectionSymbolContext context, Module module) : + public ReflectionModuleSymbol(ReflectionSymbolContext context, ReflectionAssemblySymbol containingAssembly, Module module) : base(context) { + _containingAssembly = containingAssembly ?? throw new ArgumentNullException(nameof(containingAssembly)); _module = module ?? throw new ArgumentNullException(nameof(module)); } + /// + /// Gets the which contains the metadata of this member. + /// + internal ReflectionAssemblySymbol ContainingAssembly => _containingAssembly; + /// /// Gets the wrapped . /// @@ -178,7 +186,7 @@ internal ReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase metho if (method is null) throw new ArgumentNullException(nameof(method)); - Debug.Assert(method.Module == _module); + Debug.Assert(method.Module.GetMetadataTokenSafe() == _module.GetMetadataTokenSafe()); // create lock on demand if (_methodLock == null) @@ -548,6 +556,16 @@ public bool IsDefined(ITypeSymbol attributeType, bool inherit = false) return _module.IsDefined(((ReflectionTypeSymbol)attributeType).ReflectionObject, false); } + /// + /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. + /// + /// + internal void Complete(Module module) + { + ResolveModuleSymbol(_module = module); + ContainingAssembly.Complete(_module.Assembly); + } + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterSymbol.cs index d891bd548..931bb03ce 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterSymbol.cs @@ -11,8 +11,7 @@ class ReflectionParameterSymbol : ReflectionSymbol, IParameterSymbol { readonly ReflectionMethodBaseSymbol _containingMethod; - ParameterInfo? _parameter; - ReflectionParameterSymbolBuilder? _builder; + ParameterInfo _parameter; CustomAttribute[]? _customAttributes; @@ -29,76 +28,51 @@ public ReflectionParameterSymbol(ReflectionSymbolContext context, ReflectionMeth _parameter = parameter ?? throw new ArgumentNullException(nameof(parameter)); } - /// - /// Initializes a new instance. - /// - /// - /// - /// - public ReflectionParameterSymbol(ReflectionSymbolContext context, ReflectionMethodBaseSymbol containingMethod, ReflectionParameterSymbolBuilder builder) : - base(context) - { - _containingMethod = containingMethod ?? throw new ArgumentNullException(nameof(containingMethod)); - _builder = builder ?? throw new ArgumentNullException(nameof(builder)); - } - internal ReflectionMethodBaseSymbol ContainingMethod => _containingMethod; /// - public ParameterAttributes Attributes => _parameter is { } p ? p.Attributes : _builder is { } b ? (ParameterAttributes)b.ReflectionBuilder.Attributes : throw new InvalidOperationException(); + public ParameterAttributes Attributes => _parameter.Attributes; /// - public object? DefaultValue => _parameter is { } p ? p.DefaultValue : _builder is { } b ? b.GetConstant() : throw new InvalidOperationException(); + public object? DefaultValue => _parameter.DefaultValue; /// - public bool HasDefaultValue => (Attributes & ParameterAttributes.HasDefault) != 0; + public bool HasDefaultValue => _parameter.HasDefaultValue; /// - public bool IsIn => (Attributes & ParameterAttributes.In) != 0; + public bool IsIn => _parameter.IsIn; /// - public bool IsLcid => (Attributes & ParameterAttributes.Lcid) != 0; + public bool IsLcid => _parameter.IsLcid; /// - public bool IsOptional => (Attributes & ParameterAttributes.Optional) != 0; + public bool IsOptional => _parameter.IsOptional; /// - public bool IsOut => (Attributes & ParameterAttributes.Out) != 0; + public bool IsOut => _parameter.IsOut; /// - public bool IsRetval => (Attributes & ParameterAttributes.Retval) != 0; + public bool IsRetval => _parameter.IsRetval; /// - public IMemberSymbol Member => _parameter is { } p ? ResolveMemberSymbol(p.Member) : _containingMethod; - -#if NETFRAMEWORK + public IMemberSymbol Member => ResolveMemberSymbol(_parameter.Member); /// - public int MetadataToken => _parameter is { } p ? p.MetadataToken : _builder is { } b ? b.ReflectionBuilder.GetToken().Token : throw new InvalidOperationException(); - -#else - - /// - public int MetadataToken => _parameter is { } p ? p.MetadataToken : _builder is { } b ? throw new NotSupportedException() : throw new InvalidOperationException(); - -#endif + public int MetadataToken => _parameter.MetadataToken; /// - public string? Name => _parameter is { } p ? p.Name : _builder is { } b ? b.ReflectionBuilder.Name : throw new InvalidOperationException(); + public string? Name => _parameter.Name; /// - public ITypeSymbol ParameterType => _parameter is { } p ? ResolveTypeSymbol(p.ParameterType) : _builder is { } b ? throw new NotSupportedException() : throw new InvalidOperationException(); + public ITypeSymbol ParameterType => ResolveTypeSymbol(_parameter.ParameterType); /// - public int Position => _parameter is { } p ? p.Position : _builder is { } b ? b.ReflectionBuilder.Position : throw new InvalidOperationException(); + public int Position => _parameter.Position; /// public CustomAttribute[] GetCustomAttributes(bool inherit = false) { - if (_parameter is not null) - return _customAttributes ??= ResolveCustomAttributes(_parameter.GetCustomAttributesData()); - - throw new NotSupportedException(); + return _customAttributes ??= ResolveCustomAttributes(_parameter.GetCustomAttributesData()); } /// @@ -116,39 +90,29 @@ public virtual CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, /// public virtual bool IsDefined(ITypeSymbol attributeType, bool inherit = false) { - if (_parameter is not null) - return _parameter.IsDefined(((ReflectionTypeSymbol)attributeType).ReflectionObject, inherit); - - throw new NotSupportedException(); + return _parameter.IsDefined(((ReflectionTypeSymbol)attributeType).ReflectionObject, inherit); } /// public ITypeSymbol[] GetOptionalCustomModifiers() { - if (_parameter is not null) - return ResolveTypeSymbols(_parameter.GetOptionalCustomModifiers()); - - throw new NotSupportedException(); + return ResolveTypeSymbols(_parameter.GetOptionalCustomModifiers()); } /// public ITypeSymbol[] GetRequiredCustomModifiers() { - if (_parameter is not null) - return ResolveTypeSymbols(_parameter.GetRequiredCustomModifiers()); - - throw new NotSupportedException(); + return ResolveTypeSymbols(_parameter.GetRequiredCustomModifiers()); } /// - /// Finishes the symbol by replacing the builder. + /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. /// /// - /// - internal void Finish(ParameterInfo parameter) + internal void Complete(ParameterInfo parameter) { - _parameter = parameter ?? throw new ArgumentNullException(nameof(parameter)); - _builder = null; + ResolveParameterSymbol(_parameter = parameter); + _customAttributes = null; } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionPropertySymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionPropertySymbol.cs index 8e82493be..8e39abaeb 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionPropertySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionPropertySymbol.cs @@ -7,7 +7,7 @@ namespace IKVM.CoreLib.Symbols.Reflection class ReflectionPropertySymbol : ReflectionMemberSymbol, IPropertySymbol { - readonly PropertyInfo _property; + PropertyInfo _property; /// /// Initializes a new instance. @@ -16,7 +16,7 @@ class ReflectionPropertySymbol : ReflectionMemberSymbol, IPropertySymbol /// /// public ReflectionPropertySymbol(ReflectionSymbolContext context, ReflectionTypeSymbol type, PropertyInfo property) : - base(context, type.ContainingModule, type, property) + base(context, type, property) { _property = property ?? throw new ArgumentNullException(nameof(property)); } @@ -112,6 +112,17 @@ public ITypeSymbol[] GetRequiredCustomModifiers() { return ResolveTypeSymbols(_property.GetRequiredCustomModifiers()); } + + /// + /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. + /// + /// + internal void Complete(PropertyInfo property) + { + ResolvePropertySymbol(_property = property); + base.Complete(_property); + } + } } \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs index 6a65e9547..f4e809e2f 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs @@ -1,8 +1,10 @@ using System; +using System.Collections.Concurrent; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; +using IKVM.CoreLib.Reflection; using IKVM.CoreLib.Symbols.Reflection.Emit; namespace IKVM.CoreLib.Symbols.Reflection @@ -14,7 +16,8 @@ namespace IKVM.CoreLib.Symbols.Reflection class ReflectionSymbolContext { - readonly ConditionalWeakTable _assemblies = new(); + readonly ConcurrentDictionary> _symbolByName = new(AssemblyNameEqualityComparer.Instance); + readonly ConditionalWeakTable _symbolByAssembly = new(); /// /// Initializes a new instance. @@ -24,6 +27,30 @@ public ReflectionSymbolContext() } + /// + /// Gets or creates a indexed based on the assembly's name. + /// + /// + /// + ReflectionAssemblySymbol GetOrCreateAssemblySymbolByName(Assembly assembly) + { + var r = _symbolByName.GetOrAdd(assembly.GetName(), _ => new WeakReference(new ReflectionAssemblySymbol(this, assembly))); + + // reference has valid symbol + if (r.TryGetTarget(out var s)) + return s; + + // no valid symbol, must have been released, lock to restore + lock (r) + { + // still gone, recreate + if (r.TryGetTarget(out s) == false) + r.SetTarget(s = new ReflectionAssemblySymbol(this, assembly)); + + return s; + } + } + /// /// Gets or creates a for the specified . /// @@ -31,7 +58,7 @@ public ReflectionSymbolContext() /// public ReflectionAssemblySymbol GetOrCreateAssemblySymbol(Assembly assembly) { - return _assemblies.GetValue(assembly, _ => new ReflectionAssemblySymbol(this, _)); + return _symbolByAssembly.GetValue(assembly, GetOrCreateAssemblySymbolByName); } /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbol.cs index b49dbe028..652a3c8fc 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbol.cs @@ -692,10 +692,27 @@ public ITypeSymbol MakePointerType() /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. /// /// - /// - internal void FinishType(Type type) + internal void Complete(Type type) { - _type = type; + ResolveTypeSymbol(_type = type); + base.Complete(_type); + + ContainingModule.Complete(_type.Module); + + foreach (var i in _type.GetConstructors(DefaultBindingFlags)) + ResolveConstructorSymbol(i).Complete(i); + + foreach (var i in _type.GetMethods(DefaultBindingFlags)) + ResolveMethodSymbol(i).Complete(i); + + foreach (var i in _type.GetFields(DefaultBindingFlags)) + ResolveFieldSymbol(i).Complete(i); + + foreach (var i in _type.GetProperties(DefaultBindingFlags)) + ResolvePropertySymbol(i).Complete(i); + + foreach (var i in _type.GetEvents(DefaultBindingFlags)) + ResolveEventSymbol(i).Complete(i); } } diff --git a/src/IKVM.CoreLib/System/TypeExtensions.cs b/src/IKVM.CoreLib/System/TypeExtensions.cs index 1abd007c2..ea2a69932 100644 --- a/src/IKVM.CoreLib/System/TypeExtensions.cs +++ b/src/IKVM.CoreLib/System/TypeExtensions.cs @@ -3,8 +3,6 @@ using System.Reflection.Emit; using System.Reflection.Metadata.Ecma335; -using IKVM.CoreLib.Symbols.Reflection.Emit; - namespace System { @@ -94,6 +92,30 @@ static class TypeExtensions _eventBuilderParameter) .Compile(); + /// + /// Gets the metadata token for the specified . + /// + /// + /// + public static int GetMetadataTokenSafe(this Module module) + { + var t = module.MetadataToken; + if (t == 0) + throw new InvalidOperationException(); + + return t; + } + + /// + /// Gets the metadata row number for the specified . + /// + /// + /// + public static int GetMetadataTokenRowNumberSafe(this Module module) + { + return MetadataTokens.GetRowNumber(MetadataTokens.EntityHandle(module.GetMetadataTokenSafe())); + } + /// /// Gets the metadata token for the specified . /// @@ -292,13 +314,6 @@ public static int GetMetadataTokenRowNumberSafe(this PropertyInfo property) /// public static int GetMetadataTokenSafe(this EventInfo @event) { - if (@event is ReflectionEventBuilderInfo b) - { - var t = b.GetMetadataToken(); - if (t == 0) - throw new InvalidOperationException(); - } - return @event.GetMetadataToken(); } From 635ca5fc8c5d674dd18fd965a1fcb13d7f82dbf2 Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Sun, 15 Sep 2024 22:59:54 -0500 Subject: [PATCH 04/51] Fixes. --- .../Reflection/ReflectionSymbolTests.cs | 16 + .../Symbols/Emit/IAssemblySymbolBuilder.cs | 21 +- .../Symbols/Emit/IConstructorSymbolBuilder.cs | 12 +- src/IKVM.CoreLib/Symbols/ITypeSymbol.cs | 54 ++ .../IkvmReflectionAssemblySymbolBuilder.cs | 79 +++ .../IkvmReflectionConstructorSymbolBuilder.cs | 74 +++ .../IkvmReflectionCustomAttributeBuilder.cs | 29 + .../Emit/IkvmReflectionEventSymbolBuilder.cs | 70 +++ .../Emit/IkvmReflectionFieldSymbolBuilder.cs | 88 +++ .../IkvmReflectionMethodBaseSymbolBuilder.cs | 49 ++ .../Emit/IkvmReflectionMethodSymbolBuilder.cs | 107 ++++ .../Emit/IkvmReflectionModuleSymbolBuilder.cs | 98 +++ .../IkvmReflectionParameterBuilderInfo.cs | 68 +++ .../IkvmReflectionParameterSymbolBuilder.cs | 106 ++++ .../IkvmReflectionAssemblySymbol.cs | 81 +-- .../IkvmReflectionConstructorSymbol.cs | 17 +- .../IkvmReflectionEventSymbol.cs | 53 +- .../IkvmReflectionFieldSymbol.cs | 58 +- .../IkvmReflectionMemberSymbol.cs | 102 ++-- .../IkvmReflectionMethodBaseSymbol.cs | 78 +-- .../IkvmReflectionMethodSymbol.cs | 94 +-- .../IkvmReflectionModuleSymbol.cs | 383 +++++++++--- .../IkvmReflectionParameterSymbol.cs | 22 +- .../IkvmReflectionPropertySymbol.cs | 50 +- .../IkvmReflection/IkvmReflectionSymbol.cs | 118 ++-- .../IkvmReflectionSymbolContext.cs | 97 +-- .../IkvmReflectionTypeSymbol.cs | 558 ++++-------------- .../IkvmReflection/IkvmReflectionUtil.cs | 195 ++++++ .../Emit/ReflectionAssemblySymbolBuilder.cs | 20 + .../ReflectionConstructorSymbolBuilder.cs | 4 +- .../Reflection/ReflectionMethodSymbol.cs | 89 +-- .../Reflection/ReflectionModuleSymbol.cs | 73 ++- .../Symbols/Reflection/ReflectionSymbol.cs | 14 + .../Reflection/ReflectionTypeSymbol.cs | 138 ++--- .../Symbols/TypeSymbolListEqualityComparer.cs | 49 ++ src/IKVM.Reflection/BuiltinArrayMethod.cs | 2 +- src/IKVM.Reflection/Emit/MethodBuilder.cs | 2 +- src/IKVM.Reflection/Emit/ParameterBuilder.cs | 1 - .../GenericParameterInfoImpl.cs | 2 +- src/IKVM.Reflection/MissingMethod.cs | 2 +- src/IKVM.Reflection/ParameterInfo.cs | 6 +- src/IKVM.Reflection/PropertyInfo.cs | 2 +- .../Reader/ParameterInfoImpl.cs | 2 +- src/IKVM.Reflection/Type.cs | 15 + 44 files changed, 2098 insertions(+), 1100 deletions(-) create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionAssemblySymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionConstructorSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionCustomAttributeBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionEventSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionFieldSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodBaseSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionModuleSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterBuilderInfo.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionUtil.cs create mode 100644 src/IKVM.CoreLib/Symbols/TypeSymbolListEqualityComparer.cs diff --git a/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs b/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs index f01a0bf35..c27511937 100644 --- a/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs +++ b/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using System.Reflection; using System.Reflection.Emit; @@ -145,6 +146,21 @@ public void CanResolveMethod() m.IsPrivate.Should().BeFalse(); } + [TestMethod] + public void CanResolveGenericMethod() + { + var c = new ReflectionSymbolContext(); + var s = c.GetOrCreateTypeSymbol(typeof(ValueTuple)); + var m = s.GetMethods().FirstOrDefault(i => i.Name == "Create" && i.GetGenericArguments().Length == 1); + m.Name.Should().Be("Create"); + m.ReturnType.Should().BeSameAs(c.GetOrCreateTypeSymbol(typeof(ValueTuple<>)).MakeGenericType(m.GetGenericArguments()[0])); + m.ReturnParameter.ParameterType.Should().BeSameAs(c.GetOrCreateTypeSymbol(typeof(ValueTuple<>)).MakeGenericType(m.GetGenericArguments()[0])); + m.IsGenericMethod.Should().BeTrue(); + m.IsGenericMethodDefinition.Should().BeTrue(); + m.IsPublic.Should().BeTrue(); + m.IsPrivate.Should().BeFalse(); + } + [TestMethod] public void CanResolveParameters() { diff --git a/src/IKVM.CoreLib/Symbols/Emit/IAssemblySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IAssemblySymbolBuilder.cs index e4d72dc17..1bac977b7 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/IAssemblySymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/IAssemblySymbolBuilder.cs @@ -1,4 +1,6 @@ -namespace IKVM.CoreLib.Symbols.Emit +using System.Xml.Linq; + +namespace IKVM.CoreLib.Symbols.Emit { interface IAssemblySymbolBuilder : ISymbolBuilder @@ -11,6 +13,23 @@ interface IAssemblySymbolBuilder : ISymbolBuilder /// IModuleSymbolBuilder DefineModule(string name); + /// + /// Defines a named module in this assembly. + /// + /// + /// + /// + IModuleSymbolBuilder DefineModule(string name, string fileName); + + /// + /// Defines a named module in this assembly. + /// + /// + /// + /// + /// + IModuleSymbolBuilder DefineModule(string name, string fileName, bool emitSymbolInfo); + /// /// Set a custom attribute using a custom attribute builder. /// diff --git a/src/IKVM.CoreLib/Symbols/Emit/IConstructorSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IConstructorSymbolBuilder.cs index 72d628579..e98f8e770 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/IConstructorSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/IConstructorSymbolBuilder.cs @@ -1,4 +1,6 @@ -namespace IKVM.CoreLib.Symbols.Emit +using System.Reflection; + +namespace IKVM.CoreLib.Symbols.Emit { interface IConstructorSymbolBuilder : ISymbolBuilder @@ -8,7 +10,7 @@ interface IConstructorSymbolBuilder : ISymbolBuilder /// Sets the method implementation flags for this constructor. /// /// - void SetImplementationFlags(System.Reflection.MethodImplAttributes attributes); + void SetImplementationFlags(MethodImplAttributes attributes); /// /// Defines a parameter of this constructor. @@ -17,20 +19,20 @@ interface IConstructorSymbolBuilder : ISymbolBuilder /// /// /// - IParameterSymbolBuilder DefineParameter(int iSequence, System.Reflection.ParameterAttributes attributes, string? strParamName); + IParameterSymbolBuilder DefineParameter(int iSequence, ParameterAttributes attributes, string? strParamName); /// /// Gets an ILGenerator object, with the specified MSIL stream size, that can be used to build a method body for this constructor. /// /// /// - System.Reflection.Emit.ILGenerator GetILGenerator(int streamSize); + IILGenerator GetILGenerator(int streamSize); /// /// Gets an ILGenerator for this constructor. /// /// - System.Reflection.Emit.ILGenerator GetILGenerator(); + IILGenerator GetILGenerator(); /// /// Set a custom attribute using a custom attribute builder. diff --git a/src/IKVM.CoreLib/Symbols/ITypeSymbol.cs b/src/IKVM.CoreLib/Symbols/ITypeSymbol.cs index 0df2185f3..21926c44b 100644 --- a/src/IKVM.CoreLib/Symbols/ITypeSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/ITypeSymbol.cs @@ -453,6 +453,60 @@ interface ITypeSymbol : IMemberSymbol /// IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types); + /// + /// Searches for the specified method whose parameters match the specified argument types and modifiers, using the specified binding constraints and the specified calling convention. + /// + /// + /// + /// + /// + /// + /// + IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers); + + /// + /// Searches for the specified method whose parameters match the specified generic parameter count, argument types and modifiers, using the specified binding constraints and the specified calling convention. + /// + /// + /// + /// + /// + /// + /// + /// + IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers); + + /// + /// Searches for the specified method whose parameters match the specified generic parameter count, argument types and modifiers, using the specified binding constraints. + /// + /// + /// + /// + /// + /// + /// + IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, ITypeSymbol[] types, ParameterModifier[]? modifiers); + + /// + /// Searches for the specified method whose parameters match the specified argument types and modifiers, using the specified binding constraints. + /// + /// + /// + /// + /// + /// + IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types, ParameterModifier[]? modifiers); + + /// + /// Searches for the specified public method whose parameters match the specified generic parameter count, argument types and modifiers. + /// + /// + /// + /// + /// + /// + IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, ParameterModifier[]? modifiers); + /// /// Returns all the public methods of the current . /// diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionAssemblySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionAssemblySymbolBuilder.cs new file mode 100644 index 000000000..ccb5a77f4 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionAssemblySymbolBuilder.cs @@ -0,0 +1,79 @@ +using System; + +using IKVM.CoreLib.Symbols.Emit; +using IKVM.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + class IkvmReflectionAssemblySymbolBuilder : IkvmReflectionSymbolBuilder, IAssemblySymbolBuilder + { + + readonly AssemblyBuilder _builder; + IkvmReflectionAssemblySymbol? _symbol; + + /// + /// Initializes a new instance. + /// + /// + /// + public IkvmReflectionAssemblySymbolBuilder(IkvmReflectionSymbolContext context, AssemblyBuilder builder) : + base(context) + { + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + } + + /// + internal sealed override IkvmReflectionAssemblySymbol ReflectionSymbol => _symbol ??= Context.GetOrCreateAssemblySymbol(_builder); + + /// + public IModuleSymbolBuilder DefineModule(string name) + { + return new IkvmReflectionModuleSymbolBuilder(Context, _builder.DefineDynamicModule(name, name + ".dll")); + } + + /// + public IModuleSymbolBuilder DefineModule(string name, string fileName) + { + return new IkvmReflectionModuleSymbolBuilder(Context, _builder.DefineDynamicModule(name, fileName)); + } + + /// + public IModuleSymbolBuilder DefineModule(string name, string fileName, bool emitSymbolInfo) + { + return new IkvmReflectionModuleSymbolBuilder(Context, _builder.DefineDynamicModule(name, fileName, emitSymbolInfo)); + } + + /// + public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) + { + _builder.SetCustomAttribute(con.Unpack(), binaryAttribute); + } + + /// + public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) + { + _builder.SetCustomAttribute(((IkvmReflectionCustomAttributeBuilder)customBuilder).ReflectionBuilder); + } + + /// + public void Complete() + { + foreach (var module in _builder.GetModules()) + { + if (module is ModuleBuilder moduleBuilder) + { + moduleBuilder.CreateGlobalFunctions(); + + foreach (var type in moduleBuilder.GetTypes()) + if (type is TypeBuilder typeBuilder) + if (typeBuilder.IsCreated() == false) + if (typeBuilder.CreateType() is { } t) + ReflectionSymbol.ResolveTypeSymbol(t).Complete(t); + } + } + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionConstructorSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionConstructorSymbolBuilder.cs new file mode 100644 index 000000000..2d0fc2e7c --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionConstructorSymbolBuilder.cs @@ -0,0 +1,74 @@ +using System; + +using IKVM.CoreLib.Symbols.Emit; +using IKVM.Reflection; +using IKVM.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + class IkvmReflectionConstructorSymbolBuilder : IkvmReflectionMethodBaseSymbolBuilder, IConstructorSymbolBuilder + { + + readonly ConstructorBuilder _builder; + IkvmReflectionConstructorSymbol? _symbol; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + public IkvmReflectionConstructorSymbolBuilder(IkvmReflectionSymbolContext context, IkvmReflectionTypeSymbolBuilder containingTypeBuilder, ConstructorBuilder builder) : + base(context, containingTypeBuilder) + { + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + } + + /// + /// Gets the containing . + /// + protected internal new IkvmReflectionTypeSymbolBuilder ContainingTypeBuilder => base.ContainingTypeBuilder ?? throw new NullReferenceException(); + + /// + internal override IkvmReflectionConstructorSymbol ReflectionSymbol => _symbol ??= Context.GetOrCreateConstructorSymbol(_builder); + + /// + public void SetImplementationFlags(System.Reflection.MethodImplAttributes attributes) + { + _builder.SetImplementationFlags((MethodImplAttributes)attributes); + } + + /// + public IParameterSymbolBuilder DefineParameter(int iSequence, System.Reflection.ParameterAttributes attributes, string? strParamName) + { + return new IkvmReflectionParameterSymbolBuilder(Context, this, _builder, _builder.DefineParameter(iSequence, (ParameterAttributes)attributes, strParamName)); + } + + /// + public IILGenerator GetILGenerator() + { + throw new NotImplementedException(); + } + + /// + public IILGenerator GetILGenerator(int streamSize) + { + throw new NotImplementedException(); + } + + /// + public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) + { + _builder.SetCustomAttribute(((IkvmReflectionCustomAttributeBuilder)customBuilder).ReflectionBuilder); + } + + /// + public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) + { + _builder.SetCustomAttribute(con.Unpack(), binaryAttribute); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionCustomAttributeBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionCustomAttributeBuilder.cs new file mode 100644 index 000000000..39adf5040 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionCustomAttributeBuilder.cs @@ -0,0 +1,29 @@ +using System; + +using IKVM.CoreLib.Symbols.Emit; +using IKVM.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + class IkvmReflectionCustomAttributeBuilder : ICustomAttributeBuilder + { + + readonly CustomAttributeBuilder _builder; + + /// + /// Initializes a new instance. + /// + public IkvmReflectionCustomAttributeBuilder(CustomAttributeBuilder builder) + { + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + } + + /// + /// Gets the underlying reflection . + /// + internal CustomAttributeBuilder ReflectionBuilder => _builder; + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionEventSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionEventSymbolBuilder.cs new file mode 100644 index 000000000..c1b580055 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionEventSymbolBuilder.cs @@ -0,0 +1,70 @@ +using System; + +using IKVM.CoreLib.Symbols.Emit; +using IKVM.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + class IkvmReflectionEventSymbolBuilder : IkvmReflectionSymbolBuilder, IEventSymbolBuilder + { + + readonly IkvmReflectionTypeSymbolBuilder _containingTypeBuilder; + readonly EventBuilder _builder; + IkvmReflectionEventSymbol? _symbol; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + public IkvmReflectionEventSymbolBuilder(IkvmReflectionSymbolContext context, IkvmReflectionTypeSymbolBuilder containingTypeBuilder, EventBuilder builder) : + base(context) + { + _containingTypeBuilder = containingTypeBuilder ?? throw new ArgumentNullException(nameof(containingTypeBuilder)); + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + } + + /// + internal override IkvmReflectionEventSymbol ReflectionSymbol => _symbol ??= _containingTypeBuilder.ReflectionSymbol.ResolveEventSymbol(_builder); + + /// + public void SetAddOnMethod(IMethodSymbolBuilder mdBuilder) + { + _builder.SetAddOnMethod(((IkvmReflectionMethodSymbolBuilder)mdBuilder).ReflectionBuilder); + } + + /// + public void SetRemoveOnMethod(IMethodSymbolBuilder mdBuilder) + { + _builder.SetRemoveOnMethod(((IkvmReflectionMethodSymbolBuilder)mdBuilder).ReflectionBuilder); + } + + /// + public void SetRaiseMethod(IMethodSymbolBuilder mdBuilder) + { + _builder.SetRaiseMethod(((IkvmReflectionMethodSymbolBuilder)mdBuilder).ReflectionBuilder); + } + + /// + public void AddOtherMethod(IMethodSymbolBuilder mdBuilder) + { + _builder.AddOtherMethod(((IkvmReflectionMethodSymbolBuilder)mdBuilder).ReflectionBuilder); + } + + /// + public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) + { + _builder.SetCustomAttribute(con.Unpack(), binaryAttribute); + } + + /// + public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) + { + _builder.SetCustomAttribute(((IkvmReflectionCustomAttributeBuilder)customBuilder).ReflectionBuilder); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionFieldSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionFieldSymbolBuilder.cs new file mode 100644 index 000000000..75d2bc47c --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionFieldSymbolBuilder.cs @@ -0,0 +1,88 @@ +using System; + +using IKVM.CoreLib.Symbols.Emit; +using IKVM.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + class IkvmReflectionFieldSymbolBuilder : IkvmReflectionSymbolBuilder, IFieldSymbolBuilder + { + + readonly IkvmReflectionModuleSymbolBuilder _containingModuleBuilder; + readonly IkvmReflectionTypeSymbolBuilder? _containingTypeBuilder; + readonly FieldBuilder _builder; + IkvmReflectionFieldSymbol? _symbol; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + public IkvmReflectionFieldSymbolBuilder(IkvmReflectionSymbolContext context, IkvmReflectionModuleSymbolBuilder containingModuleBuilder, FieldBuilder builder) : + base(context) + { + _containingModuleBuilder = containingModuleBuilder ?? throw new ArgumentNullException(nameof(containingModuleBuilder)); + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + } + + /// + /// Initializes a new instance. + /// + /// + /// + /// + public IkvmReflectionFieldSymbolBuilder(IkvmReflectionSymbolContext context, IkvmReflectionTypeSymbolBuilder containingTypeBuilder, FieldBuilder builder) : + base(context) + { + _containingTypeBuilder = containingTypeBuilder ?? throw new ArgumentNullException(nameof(containingTypeBuilder)); + _containingModuleBuilder = containingTypeBuilder.ContainingModuleBuilder; + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + } + + /// + /// Gets the containing . + /// + internal IkvmReflectionModuleSymbolBuilder ContainingModuleBuilder => _containingModuleBuilder; + + /// + /// Gets the containing . + /// + internal IkvmReflectionTypeSymbolBuilder? ContainingTypeBuilder => _containingTypeBuilder; + + /// + /// Gets the underlying + /// + internal FieldBuilder ReflectionBuilder => _builder; + + /// + internal override IkvmReflectionFieldSymbol ReflectionSymbol => _symbol ??= Context.GetOrCreateFieldSymbol(_builder); + + /// + public void SetConstant(object? defaultValue) + { + _builder.SetConstant(defaultValue); + } + + /// + public void SetOffset(int iOffset) + { + _builder.SetOffset(iOffset); + } + + /// + public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) + { + _builder.SetCustomAttribute(con.Unpack(), binaryAttribute); + } + + /// + public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) + { + _builder.SetCustomAttribute(((IkvmReflectionCustomAttributeBuilder)customBuilder).ReflectionBuilder); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodBaseSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodBaseSymbolBuilder.cs new file mode 100644 index 000000000..1fe558174 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodBaseSymbolBuilder.cs @@ -0,0 +1,49 @@ +using System; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + abstract class IkvmReflectionMethodBaseSymbolBuilder : IkvmReflectionSymbolBuilder + where TSymbol : ISymbol + where TReflectionSymbol : IkvmReflectionSymbol, TSymbol + { + + readonly IkvmReflectionModuleSymbolBuilder _containingModuleBuilder; + readonly IkvmReflectionTypeSymbolBuilder? _containingTypeBuilder; + + /// + /// Initializes a new instance. + /// + /// + /// + protected IkvmReflectionMethodBaseSymbolBuilder(IkvmReflectionSymbolContext context, IkvmReflectionTypeSymbolBuilder containingTypeBuilder) : + base(context) + { + _containingTypeBuilder = containingTypeBuilder ?? throw new ArgumentNullException(nameof(containingTypeBuilder)); + _containingModuleBuilder = containingTypeBuilder.ContainingModuleBuilder; + } + + /// + /// Initializes a new instance. + /// + /// + /// + protected IkvmReflectionMethodBaseSymbolBuilder(IkvmReflectionSymbolContext context, IkvmReflectionModuleSymbolBuilder containingModuleBuilder) : + base(context) + { + _containingModuleBuilder = containingModuleBuilder ?? throw new ArgumentNullException(nameof(containingModuleBuilder)); + } + + /// + /// Gets the containing . + /// + protected internal IkvmReflectionModuleSymbolBuilder ContainingModuleBuilder => _containingModuleBuilder; + + /// + /// Gets the containing . + /// + protected internal IkvmReflectionTypeSymbolBuilder? ContainingTypeBuilder => _containingTypeBuilder; + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodSymbolBuilder.cs new file mode 100644 index 000000000..e01792a35 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodSymbolBuilder.cs @@ -0,0 +1,107 @@ +using System; + +using IKVM.CoreLib.Symbols.Emit; +using IKVM.Reflection; +using IKVM.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + class IkvmReflectionMethodSymbolBuilder : IkvmReflectionMethodBaseSymbolBuilder, IMethodSymbolBuilder + { + + readonly MethodBuilder _builder; + IkvmReflectionMethodSymbol? _symbol; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + public IkvmReflectionMethodSymbolBuilder(IkvmReflectionSymbolContext context, IkvmReflectionModuleSymbolBuilder containingModuleBuilder, MethodBuilder builder) : + base(context, containingModuleBuilder) + { + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + } + + /// + /// Initializes a new instance. + /// + /// + /// + /// + public IkvmReflectionMethodSymbolBuilder(IkvmReflectionSymbolContext context, IkvmReflectionTypeSymbolBuilder containingTypeBuilder, MethodBuilder builder) : + base(context, containingTypeBuilder) + { + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + } + + /// + /// Gets the that underlies this instance. + /// + internal MethodBuilder ReflectionBuilder => _builder; + + /// + internal override IkvmReflectionMethodSymbol ReflectionSymbol => _symbol ??= Context.GetOrCreateMethodSymbol(_builder); + + /// + public void SetImplementationFlags(System.Reflection.MethodImplAttributes attributes) + { + _builder.SetImplementationFlags((MethodImplAttributes)attributes); + } + + /// + public void SetParameters(params ITypeSymbol[] parameterTypes) + { + _builder.SetParameters(parameterTypes.Unpack()); + } + + /// + public void SetReturnType(ITypeSymbol? returnType) + { + _builder.SetReturnType(returnType?.Unpack()); + } + + /// + public void SetSignature(ITypeSymbol? returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers) + { + _builder.SetSignature(returnType?.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack()); + } + + public IGenericTypeParameterSymbolBuilder[] DefineGenericParameters(params string[] names) + { + throw new NotImplementedException(); + } + + /// + public IParameterSymbolBuilder DefineParameter(int position, System.Reflection.ParameterAttributes attributes, string? strParamName) + { + return new IkvmReflectionParameterSymbolBuilder(Context, this, _builder, _builder.DefineParameter(position, (ParameterAttributes)attributes, strParamName)); + } + + public IILGenerator GetILGenerator() + { + throw new NotImplementedException(); + } + + public IILGenerator GetILGenerator(int size) + { + throw new NotImplementedException(); + } + + /// + public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) + { + _builder.SetCustomAttribute(con.Unpack(), binaryAttribute); + } + + /// + public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) + { + _builder.SetCustomAttribute(((IkvmReflectionCustomAttributeBuilder)customBuilder).ReflectionBuilder); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionModuleSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionModuleSymbolBuilder.cs new file mode 100644 index 000000000..6064c7e88 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionModuleSymbolBuilder.cs @@ -0,0 +1,98 @@ +using System; + +using IKVM.CoreLib.Symbols.Emit; +using IKVM.Reflection; +using IKVM.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + class IkvmReflectionModuleSymbolBuilder : IkvmReflectionSymbolBuilder, IModuleSymbolBuilder + { + + readonly ModuleBuilder _builder; + IkvmReflectionModuleSymbol? _symbol; + + /// + /// Initializes a new instance. + /// + /// + /// + public IkvmReflectionModuleSymbolBuilder(IkvmReflectionSymbolContext context, ModuleBuilder builder) : + base(context) + { + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + } + + /// + internal override IkvmReflectionModuleSymbol ReflectionSymbol => _symbol ??= Context.GetOrCreateModuleSymbol(_builder); + + /// + public ITypeSymbolBuilder DefineType(string name) + { + return new IkvmReflectionTypeSymbolBuilder(Context, this, _builder.DefineType(name)); + } + + /// + public ITypeSymbolBuilder DefineType(string name, System.Reflection.TypeAttributes attr, ITypeSymbol? parent, int typesize) + { + return new IkvmReflectionTypeSymbolBuilder(Context, this, _builder.DefineType(name, (TypeAttributes)attr, parent?.Unpack(), typesize)); + } + + /// + public ITypeSymbolBuilder DefineType(string name, System.Reflection.TypeAttributes attr, ITypeSymbol? parent) + { + return new IkvmReflectionTypeSymbolBuilder(Context, this, _builder.DefineType(name, (TypeAttributes)attr, parent?.Unpack())); + } + + /// + public ITypeSymbolBuilder DefineType(string name, System.Reflection.TypeAttributes attr) + { + return new IkvmReflectionTypeSymbolBuilder(Context, this, _builder.DefineType(name, (TypeAttributes)attr)); + } + + /// + public ITypeSymbolBuilder DefineType(string name, System.Reflection.TypeAttributes attr, ITypeSymbol? parent, System.Reflection.Emit.PackingSize packsize) + { + return new IkvmReflectionTypeSymbolBuilder(Context, this, _builder.DefineType(name, (TypeAttributes)attr, parent?.Unpack(), (PackingSize)packsize)); + } + + /// + public ITypeSymbolBuilder DefineType(string name, System.Reflection.TypeAttributes attr, ITypeSymbol? parent, System.Reflection.Emit.PackingSize packingSize, int typesize) + { + return new IkvmReflectionTypeSymbolBuilder(Context, this, _builder.DefineType(name, (TypeAttributes)attr, parent?.Unpack(), (PackingSize)packingSize, typesize)); + } + + /// + public ITypeSymbolBuilder DefineType(string name, System.Reflection.TypeAttributes attr, ITypeSymbol? parent, ITypeSymbol[]? interfaces) + { + return new IkvmReflectionTypeSymbolBuilder(Context, this, _builder.DefineType(name, (TypeAttributes)attr, parent?.Unpack(), interfaces?.Unpack())); + } + + /// + public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) + { + _builder.SetCustomAttribute(con.Unpack(), binaryAttribute); + } + + /// + public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) + { + _builder.SetCustomAttribute(((IkvmReflectionCustomAttributeBuilder)customBuilder).ReflectionBuilder); + } + + /// + public void Complete() + { + _builder.CreateGlobalFunctions(); + + foreach (var type in _builder.GetTypes()) + if (type is TypeBuilder typeBuilder) + if (typeBuilder.IsCreated() == false) + if (typeBuilder.CreateType() is { } t) + ReflectionSymbol.ResolveTypeSymbol(t).Complete(t); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterBuilderInfo.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterBuilderInfo.cs new file mode 100644 index 000000000..66e07f7e0 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterBuilderInfo.cs @@ -0,0 +1,68 @@ +using System; + +using IKVM.Reflection; +using IKVM.Reflection.Emit; + +using Type = IKVM.Reflection.Type; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + /// + /// Fake implementation that wraps a , which does not extend . + /// + class IkvmReflectionParameterBuilderInfo : ParameterInfo + { + + readonly MemberInfo _member; + readonly ParameterBuilder _parameter; + + /// + /// Initialies a new instance. + /// + /// + /// + /// + public IkvmReflectionParameterBuilderInfo(MemberInfo member, ParameterBuilder parameter) + { + _member = member ?? throw new ArgumentNullException(nameof(member)); + _parameter = parameter ?? throw new ArgumentNullException(nameof(parameter)); + } + + /// + public override ParameterAttributes Attributes => (ParameterAttributes)_parameter.Attributes; + + /// + public override Module Module => _member.Module; + + /// + public override MemberInfo Member => _member; + + /// + public override string? Name => _parameter.Name; + + /// + public override int Position => _parameter.Position; + + /// + public override int MetadataToken => throw new NotImplementedException(); + + /// + public override Type ParameterType => throw new NotImplementedException(); + + /// + public override object RawDefaultValue => throw new NotImplementedException(); + + public override CustomModifiers __GetCustomModifiers() + { + throw new NotSupportedException(); + } + + public override bool __TryGetFieldMarshal(out FieldMarshal fieldMarshal) + { + throw new NotSupportedException(); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterSymbolBuilder.cs new file mode 100644 index 000000000..21ba94fa2 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterSymbolBuilder.cs @@ -0,0 +1,106 @@ +using System; + +using IKVM.CoreLib.Symbols.Emit; +using IKVM.Reflection; +using IKVM.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + abstract class IkvmReflectionParameterSymbolBuilder : IkvmReflectionSymbolBuilder, IParameterSymbolBuilder + { + + readonly MemberInfo _member; + readonly ParameterBuilder _builder; + readonly IkvmReflectionParameterBuilderInfo _info; + IkvmReflectionParameterSymbol? _symbol; + + object? _constant; + + /// + /// Initializes a new instance. + /// + /// + protected IkvmReflectionParameterSymbolBuilder(IkvmReflectionSymbolContext context, MemberInfo member, ParameterBuilder builder) : + base(context) + { + _member = member ?? throw new ArgumentNullException(nameof(member)); + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + _info = new IkvmReflectionParameterBuilderInfo(_member, _builder); + } + + /// + /// Gets the wrapped . + /// + internal ParameterBuilder ReflectionBuilder => _builder; + + /// + internal override IkvmReflectionParameterSymbol ReflectionSymbol => _symbol ??= GetOrCreateSymbol(_info); + + /// + /// Gets or creates the . + /// + /// + protected internal abstract IkvmReflectionParameterSymbol GetOrCreateSymbol(IkvmReflectionParameterBuilderInfo info); + + /// + public void SetConstant(object? defaultValue) + { + _builder.SetConstant(_constant = defaultValue); + } + + /// + /// Saves the constant value so it can be retrieved as a symbol. + /// + /// + internal object? GetConstant() + { + return _constant; + } + + /// + public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) + { + _builder.SetCustomAttribute(con.Unpack(), binaryAttribute); + } + + /// + public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) + { + _builder.SetCustomAttribute(((IkvmReflectionCustomAttributeBuilder)customBuilder).ReflectionBuilder); + } + + } + + class IkvmReflectionParameterSymbolBuilder : IkvmReflectionParameterSymbolBuilder + where TContainingSymbol : IMethodBaseSymbol + where TContainingReflectionSymbol : IkvmReflectionMethodBaseSymbol, TContainingSymbol + where TContainingBuilder : IkvmReflectionMethodBaseSymbolBuilder + { + + readonly TContainingBuilder _containingMethodBuilder; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + public IkvmReflectionParameterSymbolBuilder(IkvmReflectionSymbolContext context, TContainingBuilder containingMethodBuilder, MemberInfo member, ParameterBuilder builder) : + base(context, member, builder) + { + _containingMethodBuilder = containingMethodBuilder ?? throw new ArgumentNullException(nameof(containingMethodBuilder)); + } + + /// + /// Gets the containing . + /// + internal TContainingBuilder ContainingMethodBuilder => _containingMethodBuilder; + + /// + protected internal override IkvmReflectionParameterSymbol GetOrCreateSymbol(IkvmReflectionParameterBuilderInfo info) => ContainingMethodBuilder.ReflectionSymbol.ResolveParameterSymbol(info); + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs index 19b75b993..50bb64af9 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs @@ -2,10 +2,14 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; -using System.Runtime.CompilerServices; +using System.Reflection.Metadata.Ecma335; +using System.Threading; + +using IKVM.CoreLib.Collections; +using IKVM.CoreLib.Reflection; +using IKVM.CoreLib.Threading; using Assembly = IKVM.Reflection.Assembly; -using AssemblyName = IKVM.Reflection.AssemblyName; using Module = IKVM.Reflection.Module; using Type = IKVM.Reflection.Type; @@ -15,11 +19,12 @@ namespace IKVM.CoreLib.Symbols.IkvmReflection class IkvmReflectionAssemblySymbol : IkvmReflectionSymbol, IAssemblySymbol { - readonly Assembly _assembly; - readonly ConditionalWeakTable _modules = new(); - + Assembly _assembly; System.Reflection.AssemblyName? _assemblyName; + IndexRangeDictionary _moduleSymbols = new(initialCapacity: 1, maxCapacity: 32); + ReaderWriterLockSlim? _moduleLock; + /// /// Initializes a new instance. /// @@ -31,6 +36,8 @@ public IkvmReflectionAssemblySymbol(IkvmReflectionSymbolContext context, Assembl _assembly = assembly ?? throw new ArgumentNullException(nameof(assembly)); } + internal Assembly ReflectionObject => _assembly; + /// /// Gets or creates the cached for the module. /// @@ -39,14 +46,26 @@ public IkvmReflectionAssemblySymbol(IkvmReflectionSymbolContext context, Assembl /// internal IkvmReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) { - Debug.Assert(module.Assembly == _assembly); - return _modules.GetValue(module, _ => new IkvmReflectionModuleSymbol(Context, _)); - } + if (module is null) + throw new ArgumentNullException(nameof(module)); - /// - /// Gets the wrapped . - /// - internal Assembly ReflectionObject => _assembly; + Debug.Assert(AssemblyNameEqualityComparer.Instance.Equals(module.Assembly.GetName().ToAssemblyName(), _assembly.GetName().ToAssemblyName())); + + // create lock on demand + if (_moduleLock == null) + lock (this) + _moduleLock ??= new ReaderWriterLockSlim(); + + using (_moduleLock.CreateUpgradeableReadLock()) + { + var row = MetadataTokens.GetRowNumber(MetadataTokens.ModuleReferenceHandle(module.MetadataToken)); + if (_moduleSymbols[row] == null) + using (_moduleLock.CreateWriteLock()) + return _moduleSymbols[row] ??= new IkvmReflectionModuleSymbol(Context, this, module); + else + return _moduleSymbols[row] ?? throw new InvalidOperationException(); + } + } /// public IEnumerable DefinedTypes => ResolveTypeSymbols(_assembly.DefinedTypes); @@ -69,12 +88,6 @@ internal IkvmReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) /// public IEnumerable Modules => ResolveModuleSymbols(_assembly.Modules); - /// - public override bool IsMissing => _assembly.__IsMissing; - - /// - public override bool ContainsMissing => GetModules().Any(i => i.IsMissing || i.ContainsMissing); - /// public ITypeSymbol[] GetExportedTypes() { @@ -99,31 +112,16 @@ public IModuleSymbol[] GetModules(bool getResourceModules) return ResolveModuleSymbols(_assembly.GetModules(getResourceModules)); } - System.Reflection.AssemblyName ToName(AssemblyName src) - { -#pragma warning disable SYSLIB0037 // Type or member is obsolete - return new System.Reflection.AssemblyName() - { - Name = src.Name, - Version = src.Version, - CultureName = src.CultureName, - HashAlgorithm = (System.Configuration.Assemblies.AssemblyHashAlgorithm)src.HashAlgorithm, - Flags = (System.Reflection.AssemblyNameFlags)src.Flags, - ContentType = (System.Reflection.AssemblyContentType)src.ContentType, - }; -#pragma warning restore SYSLIB0037 // Type or member is obsolete - } - /// public System.Reflection.AssemblyName GetName() { - return _assemblyName ??= ToName(_assembly.GetName()); + return _assemblyName ??= _assembly.GetName().ToAssemblyName(); } /// public System.Reflection.AssemblyName GetName(bool copiedName) { - return ToName(_assembly.GetName()); + return _assembly.GetName().ToAssemblyName(); } /// @@ -132,7 +130,7 @@ public System.Reflection.AssemblyName[] GetReferencedAssemblies() var l = _assembly.GetReferencedAssemblies(); var a = new System.Reflection.AssemblyName[l.Length]; for (int i = 0; i < l.Length; i++) - a[i] = ToName(l[i]); + a[i] = l[i].ToAssemblyName(); return a; } @@ -170,7 +168,7 @@ public CustomAttribute[] GetCustomAttributes(bool inherit = false) /// public CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) { - return ResolveCustomAttributes(_assembly.__GetCustomAttributes(((IkvmReflectionTypeSymbol)attributeType).ReflectionObject, false)); + return ResolveCustomAttributes(_assembly.GetCustomAttributesData().Where(i => i.AttributeType == ((IkvmReflectionTypeSymbol)attributeType).ReflectionObject)); } /// @@ -185,6 +183,15 @@ public bool IsDefined(ITypeSymbol attributeType, bool inherit = false) return _assembly.IsDefined(((IkvmReflectionTypeSymbol)attributeType).ReflectionObject, false); } + /// + /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. + /// + /// + internal void Complete(Assembly assembly) + { + Context.GetOrCreateAssemblySymbol(_assembly = assembly); + } + } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionConstructorSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionConstructorSymbol.cs index 4a312beb3..a991bdfa5 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionConstructorSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionConstructorSymbol.cs @@ -10,17 +10,28 @@ class IkvmReflectionConstructorSymbol : IkvmReflectionMethodBaseSymbol, IConstru /// Initializes a new instance. /// /// - /// /// /// - public IkvmReflectionConstructorSymbol(IkvmReflectionSymbolContext context, IkvmReflectionModuleSymbol module, IkvmReflectionTypeSymbol type, ConstructorInfo ctor) : - base(context, module, type, ctor) + public IkvmReflectionConstructorSymbol(IkvmReflectionSymbolContext context, IkvmReflectionTypeSymbol type, ConstructorInfo ctor) : + base(context, type, ctor) { } + /// + /// Gets the underlying wrapped by this symbol. + /// internal new ConstructorInfo ReflectionObject => (ConstructorInfo)base.ReflectionObject; + /// + /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. + /// + /// + internal void Complete(ConstructorInfo type) + { + base.Complete(type); + } + } } \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionEventSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionEventSymbol.cs index 6ba509c12..f3e8e9546 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionEventSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionEventSymbol.cs @@ -8,7 +8,7 @@ namespace IKVM.CoreLib.Symbols.IkvmReflection class IkvmReflectionEventSymbol : IkvmReflectionMemberSymbol, IEventSymbol { - readonly EventInfo _event; + EventInfo _event; /// /// Initializes a new instance. @@ -17,61 +17,90 @@ class IkvmReflectionEventSymbol : IkvmReflectionMemberSymbol, IEventSymbol /// /// public IkvmReflectionEventSymbol(IkvmReflectionSymbolContext context, IkvmReflectionTypeSymbol type, EventInfo @event) : - base(context, type.ContainingModule, type, @event) + base(context, type, @event) { _event = @event ?? throw new ArgumentNullException(nameof(@event)); } - public IMethodSymbol? AddMethod => _event.AddMethod is { } m ? ResolveMethodSymbol(m) : null; + /// + /// Gets the underlying wrapped by this symbol. + /// + internal new EventInfo ReflectionObject => _event; + /// public System.Reflection.EventAttributes Attributes => (System.Reflection.EventAttributes)_event.Attributes; + /// public ITypeSymbol? EventHandlerType => _event.EventHandlerType is { } m ? ResolveTypeSymbol(m) : null; + /// public bool IsSpecialName => _event.IsSpecialName; - public IMethodSymbol? RaiseMethod => _event.RaiseMethod is { } m ? ResolveMethodSymbol(m) : null; + /// + public IMethodSymbol? AddMethod => _event.AddMethod is { } m ? ResolveMethodSymbol(m) : null; + /// public IMethodSymbol? RemoveMethod => _event.RemoveMethod is { } m ? ResolveMethodSymbol(m) : null; + /// + public IMethodSymbol? RaiseMethod => _event.RaiseMethod is { } m ? ResolveMethodSymbol(m) : null; + + /// public IMethodSymbol? GetAddMethod() { return _event.GetAddMethod() is { } m ? ResolveMethodSymbol(m) : null; } + /// public IMethodSymbol? GetAddMethod(bool nonPublic) { return _event.GetAddMethod(nonPublic) is { } m ? ResolveMethodSymbol(m) : null; } - public IMethodSymbol[] GetOtherMethods() + /// + public IMethodSymbol? GetRemoveMethod() { - return ResolveMethodSymbols(_event.GetOtherMethods()); + return _event.GetRemoveMethod() is { } m ? ResolveMethodSymbol(m) : null; } - public IMethodSymbol[] GetOtherMethods(bool nonPublic) + /// + public IMethodSymbol? GetRemoveMethod(bool nonPublic) { - return ResolveMethodSymbols(_event.GetOtherMethods(nonPublic)); + return _event.GetRemoveMethod(nonPublic) is { } m ? ResolveMethodSymbol(m) : null; } + /// public IMethodSymbol? GetRaiseMethod() { return _event.GetRaiseMethod() is { } m ? ResolveMethodSymbol(m) : null; } + /// public IMethodSymbol? GetRaiseMethod(bool nonPublic) { return _event.GetRaiseMethod(nonPublic) is { } m ? ResolveMethodSymbol(m) : null; } - public IMethodSymbol? GetRemoveMethod(bool nonPublic) + /// + public IMethodSymbol[] GetOtherMethods() { - return _event.GetRemoveMethod(nonPublic) is { } m ? ResolveMethodSymbol(m) : null; + return ResolveMethodSymbols(_event.GetOtherMethods()); } - public IMethodSymbol? GetRemoveMethod() + /// + public IMethodSymbol[] GetOtherMethods(bool nonPublic) { - return _event.GetRemoveMethod() is { } m ? ResolveMethodSymbol(m) : null; + return ResolveMethodSymbols(_event.GetOtherMethods(nonPublic)); + } + + /// + /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. + /// + /// + internal void Complete(EventInfo @event) + { + ResolveEventSymbol(_event = @event); + base.Complete(_event); } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionFieldSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionFieldSymbol.cs index 269606996..4e9448e3e 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionFieldSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionFieldSymbol.cs @@ -8,65 +8,107 @@ namespace IKVM.CoreLib.Symbols.IkvmReflection class IkvmReflectionFieldSymbol : IkvmReflectionMemberSymbol, IFieldSymbol { - readonly FieldInfo _field; + FieldInfo _field; /// /// Initializes a new instance. /// /// - /// + /// /// - public IkvmReflectionFieldSymbol(IkvmReflectionSymbolContext context, IkvmReflectionTypeSymbol type, FieldInfo field) : - base(context, type.ContainingModule, type, field) + public IkvmReflectionFieldSymbol(IkvmReflectionSymbolContext context, IkvmReflectionModuleSymbol containingModule, FieldInfo field) : + base(context, containingModule, field) { _field = field ?? throw new ArgumentNullException(nameof(field)); } + /// + /// Initializes a new instance. + /// + /// + /// + /// + public IkvmReflectionFieldSymbol(IkvmReflectionSymbolContext context, IkvmReflectionTypeSymbol containingType, FieldInfo field) : + base(context, containingType, field) + { + _field = field ?? throw new ArgumentNullException(nameof(field)); + } + + /// + /// Gets the underlying wrapped by this symbol. + /// internal new FieldInfo ReflectionObject => (FieldInfo)base.ReflectionObject; + /// public System.Reflection.FieldAttributes Attributes => (System.Reflection.FieldAttributes)_field.Attributes; + /// public ITypeSymbol FieldType => ResolveTypeSymbol(_field.FieldType); + /// + public bool IsSpecialName => _field.IsSpecialName; + + /// public bool IsAssembly => _field.IsAssembly; + /// public bool IsFamily => _field.IsFamily; + /// public bool IsFamilyAndAssembly => _field.IsFamilyAndAssembly; + /// public bool IsFamilyOrAssembly => _field.IsFamilyOrAssembly; + /// public bool IsInitOnly => _field.IsInitOnly; + /// public bool IsLiteral => _field.IsLiteral; #pragma warning disable SYSLIB0050 // Type or member is obsolete + /// public bool IsNotSerialized => _field.IsNotSerialized; #pragma warning restore SYSLIB0050 // Type or member is obsolete + /// public bool IsPinvokeImpl => _field.IsPinvokeImpl; + /// public bool IsPrivate => _field.IsPrivate; + /// public bool IsPublic => _field.IsPublic; - public bool IsSpecialName => _field.IsSpecialName; - + /// public bool IsStatic => _field.IsStatic; + /// public ITypeSymbol[] GetOptionalCustomModifiers() { return ResolveTypeSymbols(_field.GetOptionalCustomModifiers()); } + /// + public ITypeSymbol[] GetRequiredCustomModifiers() + { + return ResolveTypeSymbols(_field.GetRequiredCustomModifiers()); + } + + /// public object? GetRawConstantValue() { return _field.GetRawConstantValue(); } - public ITypeSymbol[] GetRequiredCustomModifiers() + /// + /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. + /// + /// + internal void Complete(FieldInfo field) { - return ResolveTypeSymbols(_field.GetRequiredCustomModifiers()); + ResolveFieldSymbol(_field = field); + base.Complete(_field); } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs index c01581bda..654f92805 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs @@ -13,6 +13,9 @@ namespace IKVM.CoreLib.Symbols.IkvmReflection { + /// + /// Obtains information about the attributes of a member and provides access to member metadata. + /// abstract class IkvmReflectionMemberSymbol : IkvmReflectionSymbol, IMemberSymbol { @@ -44,9 +47,9 @@ static T[] Concat(List? list) return a; } - readonly IkvmReflectionModuleSymbol _module; - readonly IkvmReflectionTypeSymbol? _type; - readonly MemberInfo _member; + readonly IkvmReflectionModuleSymbol _containingModule; + readonly IkvmReflectionTypeSymbol? _containingType; + MemberInfo _member; CustomAttribute[]? _customAttributes; CustomAttribute[]? _inheritedCustomAttributes; @@ -55,17 +58,27 @@ static T[] Concat(List? list) /// Initializes a new instance. /// /// - /// - /// + /// /// - public IkvmReflectionMemberSymbol(IkvmReflectionSymbolContext context, IkvmReflectionModuleSymbol module, IkvmReflectionTypeSymbol? type, MemberInfo member) : + public IkvmReflectionMemberSymbol(IkvmReflectionSymbolContext context, IkvmReflectionModuleSymbol containingModule, MemberInfo member) : base(context) { - _module = module ?? throw new ArgumentNullException(nameof(module)); - _type = type; + _containingModule = containingModule ?? throw new ArgumentNullException(nameof(containingModule)); _member = member ?? throw new ArgumentNullException(nameof(member)); } + /// + /// Initializes a new instance. + /// + /// + /// + /// + public IkvmReflectionMemberSymbol(IkvmReflectionSymbolContext context, IkvmReflectionTypeSymbol containingType, MemberInfo member) : + this(context, containingType.ContainingModule, member) + { + _containingType = containingType ?? throw new ArgumentNullException(nameof(containingType)); + } + /// /// Resolves the symbol for the specified type. /// @@ -73,10 +86,10 @@ public IkvmReflectionMemberSymbol(IkvmReflectionSymbolContext context, IkvmRefle /// protected internal override IkvmReflectionTypeSymbol ResolveTypeSymbol(Type type) { - if (_type != null && type == _type.ReflectionObject) - return _type; + if (_containingType != null && type == _containingType.ReflectionObject) + return _containingType; else if (type.Module == _member.Module) - return _module.GetOrCreateTypeSymbol(type); + return _containingModule.GetOrCreateTypeSymbol(type); else return base.ResolveTypeSymbol(type); } @@ -88,10 +101,8 @@ protected internal override IkvmReflectionTypeSymbol ResolveTypeSymbol(Type type /// protected internal override IkvmReflectionConstructorSymbol ResolveConstructorSymbol(ConstructorInfo ctor) { - if (_type != null && ctor.DeclaringType == _type.ReflectionObject) - return _type.GetOrCreateConstructorSymbol(ctor); - else if (ctor.DeclaringType != null && ctor.Module == _member.Module) - return _module.GetOrCreateTypeSymbol(ctor.DeclaringType).GetOrCreateConstructorSymbol(ctor); + if (ctor.Module == _member.Module) + return _containingModule.GetOrCreateConstructorSymbol(ctor); else return base.ResolveConstructorSymbol(ctor); } @@ -103,10 +114,8 @@ protected internal override IkvmReflectionConstructorSymbol ResolveConstructorSy /// protected internal override IkvmReflectionMethodSymbol ResolveMethodSymbol(MethodInfo method) { - if (_type != null && method.DeclaringType == _type.ReflectionObject) - return _type.GetOrCreateMethodSymbol(method); - else if (method.DeclaringType != null && method.Module == _member.Module) - return _module.GetOrCreateTypeSymbol(method.DeclaringType).GetOrCreateMethodSymbol(method); + if (method.Module == _member.Module) + return _containingModule.GetOrCreateMethodSymbol(method); else return base.ResolveMethodSymbol(method); } @@ -118,10 +127,8 @@ protected internal override IkvmReflectionMethodSymbol ResolveMethodSymbol(Metho /// protected internal override IkvmReflectionFieldSymbol ResolveFieldSymbol(FieldInfo field) { - if (_type != null && field.DeclaringType == _type.ReflectionObject) - return _type.GetOrCreateFieldSymbol(field); - else if (field.DeclaringType != null && field.Module == _member.Module) - return _module.GetOrCreateTypeSymbol(field.DeclaringType).GetOrCreateFieldSymbol(field); + if (field.Module == _member.Module) + return _containingModule.GetOrCreateFieldSymbol(field); else return base.ResolveFieldSymbol(field); } @@ -134,11 +141,8 @@ protected internal override IkvmReflectionFieldSymbol ResolveFieldSymbol(FieldIn /// protected internal override IkvmReflectionPropertySymbol ResolvePropertySymbol(PropertyInfo property) { - - if (_type != null && property.DeclaringType == _type.ReflectionObject) - return _type.GetOrCreatePropertySymbol(property); - else if (property.DeclaringType != null && property.Module == _member.Module) - return _module.GetOrCreateTypeSymbol(property.DeclaringType).GetOrCreatePropertySymbol(property); + if (property.Module == _member.Module) + return _containingModule.GetOrCreatePropertySymbol(property); else return base.ResolvePropertySymbol(property); } @@ -150,27 +154,32 @@ protected internal override IkvmReflectionPropertySymbol ResolvePropertySymbol(P /// protected internal override IkvmReflectionEventSymbol ResolveEventSymbol(EventInfo @event) { - if (_type != null && @event.DeclaringType == _type.ReflectionObject) - return _type.GetOrCreateEventSymbol(@event); - else if (@event.DeclaringType != null && @event.Module == _member.Module) - return _module.GetOrCreateTypeSymbol(@event.DeclaringType).GetOrCreateEventSymbol(@event); + if (@event.Module == _member.Module) + return _containingModule.GetOrCreateEventSymbol(@event); else return base.ResolveEventSymbol(@event); } /// - /// Gets the wrapped . + /// Gets the underlying wrapped by this symbol. /// internal MemberInfo ReflectionObject => _member; - /// - internal IkvmReflectionModuleSymbol ContainingModule => _module; + /// + /// Gets the which contains the metadata of this member. + /// + internal IkvmReflectionModuleSymbol ContainingModule => _containingModule; + + /// + /// Gets the which contains the metadata of this member, or null if the member is not a member of a type. + /// + internal IkvmReflectionTypeSymbol? ContainingType => _containingType; /// - internal IkvmReflectionTypeSymbol? ContainingType => _type; + public virtual IModuleSymbol Module => Context.GetOrCreateModuleSymbol(_member.Module); /// - public virtual ITypeSymbol? DeclaringType => _member.DeclaringType is Type t ? Context.GetOrCreateTypeSymbol(t) : null; + public virtual ITypeSymbol? DeclaringType => _member.DeclaringType is { } t ? Context.GetOrCreateTypeSymbol(t) : null; /// public virtual System.Reflection.MemberTypes MemberType => (System.Reflection.MemberTypes)_member.MemberType; @@ -178,15 +187,9 @@ protected internal override IkvmReflectionEventSymbol ResolveEventSymbol(EventIn /// public virtual int MetadataToken => _member.MetadataToken; - /// - public virtual IModuleSymbol Module => Context.GetOrCreateModuleSymbol(_member.Module); - /// public virtual string Name => _member.Name; - /// - public override bool IsMissing => _member.__IsMissing; - /// public virtual CustomAttribute[] GetCustomAttributes(bool inherit = false) { @@ -241,7 +244,7 @@ public virtual CustomAttribute[] GetCustomAttributes(bool inherit = false) /// public virtual CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) { - return ResolveCustomAttributes(_member.__GetCustomAttributes(((IkvmReflectionTypeSymbol)attributeType).ReflectionObject, inherit)); + return GetCustomAttributes(inherit).Where(i => i.AttributeType == attributeType).ToArray(); } /// @@ -256,6 +259,17 @@ public virtual bool IsDefined(ITypeSymbol attributeType, bool inherit = false) return _member.IsDefined(((IkvmReflectionTypeSymbol)attributeType).ReflectionObject, inherit); } + /// + /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. + /// + /// + protected void Complete(MemberInfo member) + { + ResolveMemberSymbol(_member = member); + _customAttributes = null; + _inheritedCustomAttributes = null; + } + } } \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodBaseSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodBaseSymbol.cs index f62f4d444..20f097683 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodBaseSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodBaseSymbol.cs @@ -1,10 +1,6 @@ using System; -using System.Diagnostics; -using System.Linq; -using System.Threading; using MethodBase = IKVM.Reflection.MethodBase; -using ParameterInfo = IKVM.Reflection.ParameterInfo; namespace IKVM.CoreLib.Symbols.IkvmReflection { @@ -12,67 +8,34 @@ namespace IKVM.CoreLib.Symbols.IkvmReflection abstract class IkvmReflectionMethodBaseSymbol : IkvmReflectionMemberSymbol, IMethodBaseSymbol { - readonly MethodBase _method; - - ParameterInfo[]? _parametersSource; - IkvmReflectionParameterSymbol?[]? _parameters; - IkvmReflectionParameterSymbol? _returnParameter; + MethodBase _method; /// /// Initializes a new instance. /// /// /// - /// /// - public IkvmReflectionMethodBaseSymbol(IkvmReflectionSymbolContext context, IkvmReflectionModuleSymbol module, IkvmReflectionTypeSymbol? type, MethodBase method) : - base(context, module, type, method) + public IkvmReflectionMethodBaseSymbol(IkvmReflectionSymbolContext context, IkvmReflectionModuleSymbol module, MethodBase method) : + base(context, module, method) { _method = method ?? throw new ArgumentNullException(nameof(method)); } /// - /// Gets or creates the cached for the type by method. + /// Initializes a new instance. /// - /// - /// - internal IkvmReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) + /// + /// + /// + public IkvmReflectionMethodBaseSymbol(IkvmReflectionSymbolContext context, IkvmReflectionTypeSymbol type, MethodBase method) : + this(context, type.ContainingModule, method) { - if (parameter is null) - throw new ArgumentNullException(nameof(parameter)); - - Debug.Assert(parameter.Member == _method); - if (_parametersSource == null) - Interlocked.CompareExchange(ref _parametersSource, _method.GetParameters().OrderBy(i => i.Position).ToArray(), null); - if (_parameters == null) - Interlocked.CompareExchange(ref _parameters, new IkvmReflectionParameterSymbol?[_parametersSource.Length], null); - - // index of current record - var idx = parameter.Position; - Debug.Assert(idx >= -1); - Debug.Assert(idx < _parametersSource.Length); - - // check that our list is long enough to contain the entire table - if (idx >= 0 && _parameters.Length < idx) - throw new IndexOutOfRangeException(); - - // if not yet created, create, allow multiple instances, but only one is eventually inserted - ref var rec = ref _returnParameter; - if (idx >= 0) - rec = ref _parameters[idx]; - if (rec == null) - Interlocked.CompareExchange(ref rec, new IkvmReflectionParameterSymbol(Context, this, parameter), null); - - // this should never happen - if (rec is not IkvmReflectionParameterSymbol sym) - throw new InvalidOperationException(); - - return sym; } /// - /// Gets the wrapped . + /// Gets the underlying wrapped by this symbol. /// internal new MethodBase ReflectionObject => _method; @@ -121,9 +84,6 @@ internal IkvmReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo /// public bool IsPublic => _method.IsPublic; - /// - public bool IsSpecialName => _method.IsSpecialName; - /// public bool IsStatic => _method.IsStatic; @@ -131,10 +91,10 @@ internal IkvmReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo public bool IsVirtual => _method.IsVirtual; /// - public System.Reflection.MethodImplAttributes MethodImplementationFlags => (System.Reflection.MethodImplAttributes)_method.MethodImplementationFlags; + public bool IsSpecialName => _method.IsSpecialName; /// - public override bool ContainsMissing => GetGenericArguments().Any(i => i.IsMissing || i.ContainsMissing) || GetParameters().Any(i => i.IsMissing || i.ContainsMissing); + public System.Reflection.MethodImplAttributes MethodImplementationFlags => (System.Reflection.MethodImplAttributes)_method.MethodImplementationFlags; /// public ITypeSymbol[] GetGenericArguments() @@ -154,6 +114,20 @@ public IParameterSymbol[] GetParameters() return ResolveParameterSymbols(_method.GetParameters()); } + /// + /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. + /// + /// + internal void Complete(MethodBase method) + { + ResolveMethodBaseSymbol(_method = method); + base.Complete(_method); + + foreach (var i in _method.GetParameters()) + ResolveParameterSymbol(i).Complete(i); + + } + } } \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodSymbol.cs index c18969aa2..472021fa7 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodSymbol.cs @@ -1,11 +1,6 @@ using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Threading; using MethodInfo = IKVM.Reflection.MethodInfo; -using Type = IKVM.Reflection.Type; namespace IKVM.CoreLib.Symbols.IkvmReflection { @@ -15,115 +10,60 @@ class IkvmReflectionMethodSymbol : IkvmReflectionMethodBaseSymbol, IMethodSymbol readonly MethodInfo _method; - Type[]? _genericParametersSource; - IkvmReflectionTypeSymbol?[]? _genericParameters; - List<(Type[] Arguments, IkvmReflectionMethodSymbol Symbol)>? _genericTypes; - /// /// Initializes a new instance. /// /// /// - /// /// - public IkvmReflectionMethodSymbol(IkvmReflectionSymbolContext context, IkvmReflectionModuleSymbol module, IkvmReflectionTypeSymbol? type, MethodInfo method) : - base(context, module, type, method) + public IkvmReflectionMethodSymbol(IkvmReflectionSymbolContext context, IkvmReflectionModuleSymbol module, MethodInfo method) : + base(context, module, method) { _method = method ?? throw new ArgumentNullException(nameof(method)); } /// - /// Gets or creates the cached for the generic parameter type. + /// Initializes a new instance. /// - /// - /// - /// - internal IkvmReflectionTypeSymbol GetOrCreateGenericParameterSymbol(Type genericParameterType) + /// + /// + /// + public IkvmReflectionMethodSymbol(IkvmReflectionSymbolContext context, IkvmReflectionTypeSymbol type, MethodInfo method) : + this(context, type.ContainingModule, method) { - if (genericParameterType is null) - throw new ArgumentNullException(nameof(genericParameterType)); - - Debug.Assert(genericParameterType.DeclaringMethod == _method); - - // initialize tables - _genericParametersSource ??= _method.GetGenericArguments(); - _genericParameters ??= new IkvmReflectionTypeSymbol?[_genericParametersSource.Length]; - // position of the parameter in the list - var idx = genericParameterType.GenericParameterPosition; - - // check that our list is long enough to contain the entire table - if (_genericParameters.Length < idx) - throw new IndexOutOfRangeException(); - - // if not yet created, create, allow multiple instances, but only one is eventually inserted - ref var rec = ref _genericParameters[idx]; - if (rec == null) - Interlocked.CompareExchange(ref rec, new IkvmReflectionTypeSymbol(Context, ContainingModule, genericParameterType), null); - - // this should never happen - if (rec is not IkvmReflectionTypeSymbol sym) - throw new InvalidOperationException(); - - return sym; } /// - /// Gets or creates the cached for the generic parameter type. + /// Gets the underlying wrapped by this symbol. /// - /// - /// - /// - internal IkvmReflectionMethodSymbol GetOrCreateGenericTypeSymbol(Type[] genericMethodArguments) - { - if (genericMethodArguments is null) - throw new ArgumentNullException(nameof(genericMethodArguments)); - - if (_method.IsGenericMethodDefinition == false) - throw new InvalidOperationException(); - - // initialize the available parameters - _genericParametersSource ??= _method.GetGenericArguments(); - if (_genericParametersSource.Length != genericMethodArguments.Length) - throw new InvalidOperationException(); - - // initialize generic type map, and lock on it since we're potentially adding items - _genericTypes ??= []; - lock (_genericTypes) - { - // find existing entry - foreach (var i in _genericTypes) - if (i.Arguments.SequenceEqual(genericMethodArguments)) - return i.Symbol; - - // generate new symbol - var sym = new IkvmReflectionMethodSymbol(Context, ContainingModule, ContainingType, _method.MakeGenericMethod(genericMethodArguments)); - _genericTypes.Add((genericMethodArguments, sym)); - return sym; - } - } - - internal new MethodInfo ReflectionObject => (MethodInfo)base.ReflectionObject; + internal new MethodInfo ReflectionObject => _method; + /// public IParameterSymbol ReturnParameter => ResolveParameterSymbol(_method.ReturnParameter); + /// public ITypeSymbol ReturnType => ResolveTypeSymbol(_method.ReturnType); + /// public ICustomAttributeProvider ReturnTypeCustomAttributes => throw new NotImplementedException(); + /// public IMethodSymbol GetBaseDefinition() { return ResolveMethodSymbol(_method.GetBaseDefinition()); } + /// public IMethodSymbol GetGenericMethodDefinition() { return ResolveMethodSymbol(_method.GetGenericMethodDefinition()); } + /// public IMethodSymbol MakeGenericMethod(params ITypeSymbol[] typeArguments) { - return ResolveMethodSymbol(_method.MakeGenericMethod(UnpackTypeSymbols(typeArguments))); + return ResolveMethodSymbol(_method.MakeGenericMethod(typeArguments.Unpack())); } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs index eacc58c3b..daafbe9ac 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs @@ -2,9 +2,10 @@ using System.Diagnostics; using System.Linq; using System.Reflection.Metadata.Ecma335; -using System.Runtime.InteropServices; using System.Threading; +using IKVM.CoreLib.Collections; +using IKVM.CoreLib.Threading; using IKVM.Reflection; using Module = IKVM.Reflection.Module; @@ -29,31 +30,66 @@ static bool IsTypeDefinition(Type type) return type.HasElementType == false && type.IsConstructedGenericType == false && type.IsGenericParameter == false; } - readonly Module _module; + const int MAX_CAPACITY = 65536 * 2; - Type[]? _typesSource; - int _typesBaseRow; - IkvmReflectionTypeSymbol?[]? _types; + const BindingFlags DefaultBindingFlags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance; + + readonly IkvmReflectionAssemblySymbol _containingAssembly; + Module _module; + + IndexRangeDictionary _typeTable = new(maxCapacity: MAX_CAPACITY); + IndexRangeDictionary _typeSymbols = new(maxCapacity: MAX_CAPACITY); + ReaderWriterLockSlim? _typeLock; + + IndexRangeDictionary _methodTable = new(maxCapacity: MAX_CAPACITY); + IndexRangeDictionary _methodSymbols = new(maxCapacity: MAX_CAPACITY); + ReaderWriterLockSlim? _methodLock; + + IndexRangeDictionary _fieldTable = new(maxCapacity: MAX_CAPACITY); + IndexRangeDictionary _fieldSymbols = new(maxCapacity: MAX_CAPACITY); + ReaderWriterLockSlim? _fieldLock; + + IndexRangeDictionary _propertyTable = new(maxCapacity: MAX_CAPACITY); + IndexRangeDictionary _propertySymbols = new(maxCapacity: MAX_CAPACITY); + ReaderWriterLockSlim? _propertyLock; + + IndexRangeDictionary _eventTable = new(maxCapacity: MAX_CAPACITY); + IndexRangeDictionary _eventSymbols = new(maxCapacity: MAX_CAPACITY); + ReaderWriterLockSlim? _eventLock; + + IndexRangeDictionary _parameterTable = new(); + IndexRangeDictionary _parameterSymbols = new(); + ReaderWriterLockSlim? _parameterLock; + + IndexRangeDictionary _genericParameterSymbols = new(); + ReaderWriterLockSlim? _genericParameterLock; /// /// Initializes a new instance. /// /// + /// /// /// - public IkvmReflectionModuleSymbol(IkvmReflectionSymbolContext context, Module module) : + public IkvmReflectionModuleSymbol(IkvmReflectionSymbolContext context, IkvmReflectionAssemblySymbol containingAssembly, Module module) : base(context) { + _containingAssembly = containingAssembly ?? throw new ArgumentNullException(nameof(containingAssembly)); _module = module ?? throw new ArgumentNullException(nameof(module)); } + /// + /// Gets the which contains the metadata of this member. + /// + internal IkvmReflectionAssemblySymbol ContainingAssembly => _containingAssembly; + /// /// Gets the wrapped . /// internal Module ReflectionObject => _module; /// - /// Gets or creates the cached for the module by type. + /// Gets or creates the cached for the module by type. /// /// /// @@ -65,49 +101,41 @@ internal IkvmReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) Debug.Assert(type.Module == _module); - // type is not a definition, but is substituted + // type is a generic parameter (GenericParam) + if (type.IsGenericParameter) + return GetOrCreateGenericParameterSymbol(type); + + // type is not a type definition (TypeDef) if (IsTypeDefinition(type) == false) return GetOrCreateTypeSymbolForSpecification(type); - // look up handle and row - var hnd = MetadataTokens.TypeDefinitionHandle(type.MetadataToken); - var row = MetadataTokens.GetRowNumber(hnd); + // create lock on demand + if (_typeLock == null) + lock (this) + _typeLock ??= new ReaderWriterLockSlim(); - // initialize source table - if (_typesSource == null) + using (_typeLock.CreateUpgradeableReadLock()) { - _typesSource = _module.GetTypes().OrderBy(i => i.MetadataToken).ToArray(); - _typesBaseRow = _typesSource.Length != 0 ? MetadataTokens.GetRowNumber(MetadataTokens.MethodDefinitionHandle(_typesSource[0].MetadataToken)) : 0; + var row = MetadataTokens.GetRowNumber(MetadataTokens.TypeDefinitionHandle(type.MetadataToken)); + if (_typeTable[row] != type) + using (_typeLock.CreateWriteLock()) + _typeTable[row] = type; + + if (_typeSymbols[row] == null) + using (_typeLock.CreateWriteLock()) + return _typeSymbols[row] ??= new IkvmReflectionTypeSymbol(Context, this, type); + else + return _typeSymbols[row] ?? throw new InvalidOperationException(); } - - // initialize cache table - _types ??= new IkvmReflectionTypeSymbol?[_typesSource.Length]; - - // index of current record is specified row - base - var idx = row - _typesBaseRow - 1; - Debug.Assert(idx >= 0); - Debug.Assert(idx < _typesSource.Length); - - // check that our type list is long enough to contain the entire table - if (_types.Length < idx) - throw new IndexOutOfRangeException(); - - // if not yet created, create, allow multiple instances, but only one is eventually inserted - if (_types[idx] == null) - Interlocked.CompareExchange(ref _types[idx], new IkvmReflectionTypeSymbol(Context, this, type), null); - - // this should never happen - if (_types[idx] is not IkvmReflectionTypeSymbol sym) - throw new InvalidOperationException(); - - return sym; } /// - /// For a given + /// Gets or creates a for the specification type: array, pointer, etc. /// /// - /// + /// + /// + /// IkvmReflectionTypeSymbol GetOrCreateTypeSymbolForSpecification(Type type) { if (type is null) @@ -117,7 +145,7 @@ IkvmReflectionTypeSymbol GetOrCreateTypeSymbolForSpecification(Type type) if (type.GetElementType() is { } elementType) { - var elementTypeSymbol = GetOrCreateTypeSymbol(elementType); + var elementTypeSymbol = ResolveTypeSymbol(elementType); // handles both SZ arrays and normal arrays if (type.IsArray) @@ -134,26 +162,234 @@ IkvmReflectionTypeSymbol GetOrCreateTypeSymbolForSpecification(Type type) if (type.IsGenericType) { - var definitionType = type.GetGenericTypeDefinition(); - var definitionTypeSymbol = GetOrCreateTypeSymbol(definitionType); - return definitionTypeSymbol.GetOrCreateGenericTypeSymbol(type.GetGenericArguments()); + var definitionTypeSymbol = ResolveTypeSymbol(type.GetGenericTypeDefinition()); + return definitionTypeSymbol.GetOrCreateGenericTypeSymbol(ResolveTypeSymbols(type.GetGenericArguments())); } - // generic type parameter - if (type.IsGenericParameter && type.DeclaringMethod is null && type.DeclaringType is not null) + throw new InvalidOperationException(); + } + + /// + /// Gets or creates the cached fqor the type by method. + /// + /// + /// + internal IkvmReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method) + { + if (method is null) + throw new ArgumentNullException(nameof(method)); + + Debug.Assert(method.Module.MetadataToken == _module.MetadataToken); + + // create lock on demand + if (_methodLock == null) + lock (this) + _methodLock ??= new ReaderWriterLockSlim(); + + using (_methodLock.CreateUpgradeableReadLock()) { - var declaringType = GetOrCreateTypeSymbol(type.DeclaringType); - return declaringType.GetOrCreateGenericParameterSymbol(type); + var row = MetadataTokens.GetRowNumber(MetadataTokens.MethodDefinitionHandle(method.MetadataToken)); + if (_methodTable[row] != method) + using (_methodLock.CreateWriteLock()) + _methodTable[row] = method; + + if (_methodSymbols[row] == null) + using (_methodLock.CreateWriteLock()) + if (method is ConstructorInfo c) + return _methodSymbols[row] ??= new IkvmReflectionConstructorSymbol(Context, ResolveTypeSymbol(c.DeclaringType ?? throw new InvalidOperationException()), c); + else if (method is MethodInfo m) + if (method.DeclaringType is { } dt) + return _methodSymbols[row] ??= new IkvmReflectionMethodSymbol(Context, ResolveTypeSymbol(dt), m); + else + return _methodSymbols[row] ??= new IkvmReflectionMethodSymbol(Context, this, m); + else + throw new InvalidOperationException(); + else + return _methodSymbols[row] ?? throw new InvalidOperationException(); } + } + + /// + /// Gets or creates the cached for the type by ctor. + /// + /// + /// + internal IkvmReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) + { + return (IkvmReflectionConstructorSymbol)GetOrCreateMethodBaseSymbol(ctor); + } + + /// + /// Gets or creates the cached for the type by method. + /// + /// + /// + internal IkvmReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) + { + return (IkvmReflectionMethodSymbol)GetOrCreateMethodBaseSymbol(method); + } + + /// + /// Gets or creates the cached for the type by field. + /// + /// + /// + /// + internal IkvmReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) + { + if (field is null) + throw new ArgumentNullException(nameof(field)); + + Debug.Assert(field.Module == _module); - // generic method parameter - if (type.IsGenericParameter && type.DeclaringMethod is not null && type.DeclaringMethod.DeclaringType is not null) + // create lock on demand + if (_fieldLock == null) + lock (this) + _fieldLock ??= new ReaderWriterLockSlim(); + + using (_fieldLock.CreateUpgradeableReadLock()) { - var declaringMethod = GetOrCreateTypeSymbol(type.DeclaringMethod.DeclaringType); - return declaringMethod.GetOrCreateGenericParameterSymbol(type); + var row = MetadataTokens.GetRowNumber(MetadataTokens.FieldDefinitionHandle(field.MetadataToken)); + if (_fieldTable[row] != field) + using (_fieldLock.CreateWriteLock()) + _fieldTable[row] = field; + + if (_fieldSymbols[row] == null) + using (_fieldLock.CreateWriteLock()) + if (field.DeclaringType is { } dt) + return _fieldSymbols[row] ??= new IkvmReflectionFieldSymbol(Context, ResolveTypeSymbol(dt), field); + else + return _fieldSymbols[row] ??= new IkvmReflectionFieldSymbol(Context, this, field); + else + return _fieldSymbols[row] ?? throw new InvalidOperationException(); } + } - throw new InvalidOperationException(); + /// + /// Gets or creates the cached for the type by property. + /// + /// + /// + /// + internal IkvmReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) + { + if (property is null) + throw new ArgumentNullException(nameof(property)); + + Debug.Assert(property.Module == _module); + + // create lock on demand + if (_propertyLock == null) + lock (this) + _propertyLock ??= new ReaderWriterLockSlim(); + + using (_propertyLock.CreateUpgradeableReadLock()) + { + var row = MetadataTokens.GetRowNumber(MetadataTokens.PropertyDefinitionHandle(property.MetadataToken)); + if (_propertyTable[row] != property) + using (_propertyLock.CreateWriteLock()) + _propertyTable[row] = property; + + if (_propertySymbols[row] == null) + using (_propertyLock.CreateWriteLock()) + return _propertySymbols[row] ??= new IkvmReflectionPropertySymbol(Context, ResolveTypeSymbol(property.DeclaringType!), property); + else + return _propertySymbols[row] ?? throw new InvalidOperationException(); + } + } + + /// + /// Gets or creates the cached for the type by event. + /// + /// + /// + /// + internal IkvmReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) + { + if (@event is null) + throw new ArgumentNullException(nameof(@event)); + + Debug.Assert(@event.Module == _module); + + // create lock on demand + if (_eventLock == null) + lock (this) + _eventLock ??= new ReaderWriterLockSlim(); + + using (_eventLock.CreateUpgradeableReadLock()) + { + var row = MetadataTokens.GetRowNumber(MetadataTokens.EventDefinitionHandle(@event.MetadataToken)); + if (_eventTable[row] is not EventInfo i || i != @event) + using (_eventLock.CreateWriteLock()) + _eventTable[row] = @event; + + if (_eventSymbols[row] == null) + using (_eventLock.CreateWriteLock()) + return _eventSymbols[row] ??= new IkvmReflectionEventSymbol(Context, ResolveTypeSymbol(@event.DeclaringType!), @event); + else + return _eventSymbols[row] ?? throw new InvalidOperationException(); + } + } + + /// + /// Gets or creates the cached for the type by method. + /// + /// + /// + internal IkvmReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) + { + if (parameter is null) + throw new ArgumentNullException(nameof(parameter)); + + Debug.Assert(parameter.Member.Module == _module); + + // create lock on demand + if (_parameterLock == null) + lock (this) + _parameterLock ??= new ReaderWriterLockSlim(); + + using (_parameterLock.CreateUpgradeableReadLock()) + { + var position = parameter.Position; + if (_parameterTable[position] != parameter) + using (_parameterLock.CreateWriteLock()) + _parameterTable[position] = parameter; + + if (_parameterSymbols[position] == null) + using (_parameterLock.CreateWriteLock()) + return _parameterSymbols[position] ??= new IkvmReflectionParameterSymbol(Context, ResolveMethodBaseSymbol((MethodBase)parameter.Member), parameter); + else + return _parameterSymbols[position] ?? throw new InvalidOperationException(); + } + } + + /// + /// Gets or creates the cached for the module by type. + /// + /// + /// + /// + internal IkvmReflectionTypeSymbol GetOrCreateGenericParameterSymbol(Type genericParameterType) + { + if (genericParameterType is null) + throw new ArgumentNullException(nameof(genericParameterType)); + + Debug.Assert(genericParameterType.Module == _module); + + // create lock on demand + if (_genericParameterLock == null) + Interlocked.CompareExchange(ref _genericParameterLock, new ReaderWriterLockSlim(), null); + + using (_genericParameterLock.CreateUpgradeableReadLock()) + { + var hnd = MetadataTokens.GenericParameterHandle(genericParameterType.MetadataToken); + var row = MetadataTokens.GetRowNumber(hnd); + if (_genericParameterSymbols[row] == null) + using (_genericParameterLock.CreateWriteLock()) + return _genericParameterSymbols[row] ??= new IkvmReflectionTypeSymbol(Context, this, genericParameterType); + else + return _genericParameterSymbols[row] ?? throw new InvalidOperationException(); + } } /// @@ -174,12 +410,6 @@ IkvmReflectionTypeSymbol GetOrCreateTypeSymbolForSpecification(Type type) /// public string ScopeName => _module.ScopeName; - /// - public override bool IsMissing => _module.__IsMissing; - - /// - public override bool ContainsMissing => GetTypes().Any(t => t.IsMissing || t.ContainsMissing); - /// public IFieldSymbol? GetField(string name) { @@ -213,16 +443,13 @@ public IFieldSymbol[] GetFields() /// public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) { - return _module.GetMethod(name, UnpackTypeSymbols(types)) is { } m ? ResolveMethodSymbol(m) : null; + return _module.GetMethod(name, types.Unpack()) is { } m ? ResolveMethodSymbol(m) : null; } /// public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - if (modifiers != null) - throw new NotImplementedException(); - - return _module.GetMethod(name, (BindingFlags)bindingAttr, null, (CallingConventions)callConvention, UnpackTypeSymbols(types), null) is { } m ? ResolveMethodSymbol(m) : null; + throw new NotImplementedException(); } /// @@ -236,8 +463,8 @@ public IMethodSymbol[] GetMethods(System.Reflection.BindingFlags bindingFlags) { return ResolveMethodSymbols(_module.GetMethods((BindingFlags)bindingFlags)); } - /// + /// public ITypeSymbol? GetType(string className) { return _module.GetType(className) is { } t ? ResolveTypeSymbol(t) : null; @@ -276,9 +503,7 @@ public bool IsResource() /// public IFieldSymbol? ResolveField(int metadataToken, ITypeSymbol[]? genericTypeArguments, ITypeSymbol[]? genericMethodArguments) { - var _genericTypeArguments = genericTypeArguments != null ? UnpackTypeSymbols(genericTypeArguments) : null; - var _genericMethodArguments = genericMethodArguments != null ? UnpackTypeSymbols(genericMethodArguments) : null; - return _module.ResolveField(metadataToken, _genericTypeArguments, _genericMethodArguments) is { } f ? ResolveFieldSymbol(f) : null; + return _module.ResolveField(metadataToken, genericTypeArguments?.Unpack(), genericMethodArguments?.Unpack()) is { } f ? ResolveFieldSymbol(f) : null; } /// @@ -290,17 +515,13 @@ public bool IsResource() /// public IMemberSymbol? ResolveMember(int metadataToken, ITypeSymbol[]? genericTypeArguments, ITypeSymbol[]? genericMethodArguments) { - var _genericTypeArguments = genericTypeArguments != null ? UnpackTypeSymbols(genericTypeArguments) : null; - var _genericMethodArguments = genericMethodArguments != null ? UnpackTypeSymbols(genericMethodArguments) : null; - return _module.ResolveMember(metadataToken, _genericTypeArguments, _genericMethodArguments) is { } m ? ResolveMemberSymbol(m) : null; + return _module.ResolveMember(metadataToken, genericTypeArguments?.Unpack(), genericMethodArguments?.Unpack()) is { } m ? ResolveMemberSymbol(m) : null; } /// public IMethodBaseSymbol? ResolveMethod(int metadataToken, ITypeSymbol[]? genericTypeArguments, ITypeSymbol[]? genericMethodArguments) { - var _genericTypeArguments = genericTypeArguments != null ? UnpackTypeSymbols(genericTypeArguments) : null; - var _genericMethodArguments = genericMethodArguments != null ? UnpackTypeSymbols(genericMethodArguments) : null; - return _module.ResolveMethod(metadataToken, _genericTypeArguments, _genericMethodArguments) is { } m ? ResolveMethodBaseSymbol(m) : null; + return _module.ResolveMethod(metadataToken, genericTypeArguments?.Unpack(), genericMethodArguments?.Unpack()) is { } m ? ResolveMethodBaseSymbol(m) : null; } /// @@ -330,9 +551,7 @@ public ITypeSymbol ResolveType(int metadataToken) /// public ITypeSymbol ResolveType(int metadataToken, ITypeSymbol[]? genericTypeArguments, ITypeSymbol[]? genericMethodArguments) { - var _genericTypeArguments = genericTypeArguments != null ? UnpackTypeSymbols(genericTypeArguments) : null; - var _genericMethodArguments = genericMethodArguments != null ? UnpackTypeSymbols(genericMethodArguments) : null; - return ResolveTypeSymbol(_module.ResolveType(metadataToken, _genericTypeArguments, _genericMethodArguments)); + return ResolveTypeSymbol(_module.ResolveType(metadataToken, genericTypeArguments?.Unpack(), genericMethodArguments?.Unpack())); } /// @@ -344,7 +563,7 @@ public CustomAttribute[] GetCustomAttributes(bool inherit = false) /// public CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) { - return ResolveCustomAttributes(_module.__GetCustomAttributes(((IkvmReflectionTypeSymbol)attributeType).ReflectionObject, false)); + return ResolveCustomAttributes(_module.GetCustomAttributesData().Where(i => i.AttributeType == ((IkvmReflectionTypeSymbol)attributeType).ReflectionObject)); } /// @@ -359,6 +578,16 @@ public bool IsDefined(ITypeSymbol attributeType, bool inherit = false) return _module.IsDefined(((IkvmReflectionTypeSymbol)attributeType).ReflectionObject, false); } + /// + /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. + /// + /// + internal void Complete(Module module) + { + ResolveModuleSymbol(_module = module); + ContainingAssembly.Complete(_module.Assembly); + } + } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterSymbol.cs index cc3e18be6..a0dca4626 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterSymbol.cs @@ -10,7 +10,9 @@ class IkvmReflectionParameterSymbol : IkvmReflectionSymbol, IParameterSymbol { readonly IkvmReflectionMethodBaseSymbol _containingMethod; - readonly ParameterInfo _parameter; + ParameterInfo _parameter; + + CustomAttribute[]? _customAttributes; /// /// Initializes a new instance. @@ -28,10 +30,10 @@ public IkvmReflectionParameterSymbol(IkvmReflectionSymbolContext context, IkvmRe internal IkvmReflectionMethodBaseSymbol ContainingMethod => _containingMethod; /// - public System.Reflection.ParameterAttributes Attributes => (System.Reflection.ParameterAttributes)_parameter.Attributes; + public System.Reflection.ParameterAttributes Attributes =>(System.Reflection.ParameterAttributes)_parameter.Attributes; /// - public object DefaultValue => _parameter.RawDefaultValue; + public object? DefaultValue => _parameter.RawDefaultValue; /// public bool HasDefaultValue => _parameter.HasDefaultValue; @@ -69,13 +71,13 @@ public IkvmReflectionParameterSymbol(IkvmReflectionSymbolContext context, IkvmRe /// public CustomAttribute[] GetCustomAttributes(bool inherit = false) { - return ResolveCustomAttributes(_parameter.GetCustomAttributesData()); + return _customAttributes ??= ResolveCustomAttributes(_parameter.GetCustomAttributesData()); } /// public virtual CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) { - return ResolveCustomAttributes(_parameter.__GetCustomAttributes(((IkvmReflectionTypeSymbol)attributeType).ReflectionObject, inherit)); + return GetCustomAttributes(inherit).Where(i => i.AttributeType == attributeType).ToArray(); } /// @@ -102,6 +104,16 @@ public ITypeSymbol[] GetRequiredCustomModifiers() return ResolveTypeSymbols(_parameter.GetRequiredCustomModifiers()); } + /// + /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. + /// + /// + internal void Complete(ParameterInfo parameter) + { + ResolveParameterSymbol(_parameter = parameter); + _customAttributes = null; + } + } } \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionPropertySymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionPropertySymbol.cs index f16d0b9a0..a257b0015 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionPropertySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionPropertySymbol.cs @@ -10,7 +10,7 @@ namespace IKVM.CoreLib.Symbols.IkvmReflection class IkvmReflectionPropertySymbol : IkvmReflectionMemberSymbol, IPropertySymbol { - readonly PropertyInfo _property; + PropertyInfo _property; /// /// Initializes a new instance. @@ -19,19 +19,19 @@ class IkvmReflectionPropertySymbol : IkvmReflectionMemberSymbol, IPropertySymbol /// /// public IkvmReflectionPropertySymbol(IkvmReflectionSymbolContext context, IkvmReflectionTypeSymbol type, PropertyInfo property) : - base(context, type.ContainingModule, type, property) + base(context, type, property) { _property = property ?? throw new ArgumentNullException(nameof(property)); } - public new PropertyInfo ReflectionObject => (PropertyInfo)base.ReflectionObject; + /// + /// Gets the underlying wrapped by this symbol. + /// + internal new PropertyInfo ReflectionObject => _property; /// public System.Reflection.PropertyAttributes Attributes => (System.Reflection.PropertyAttributes)_property.Attributes; - /// - public ITypeSymbol PropertyType => ResolveTypeSymbol(_property.PropertyType); - /// public bool CanRead => _property.CanRead; @@ -41,6 +41,9 @@ public IkvmReflectionPropertySymbol(IkvmReflectionSymbolContext context, IkvmRef /// public bool IsSpecialName => _property.IsSpecialName; + /// + public ITypeSymbol PropertyType => ResolveTypeSymbol(_property.PropertyType); + /// public IMethodSymbol? GetMethod => _property.GetMethod is { } m ? ResolveMethodSymbol(m) : null; @@ -54,27 +57,21 @@ public IkvmReflectionPropertySymbol(IkvmReflectionSymbolContext context, IkvmRef } /// - public IParameterSymbol[] GetIndexParameters() - { - return ResolveParameterSymbols(_property.GetIndexParameters()); - } - - /// - public ITypeSymbol GetModifiedPropertyType() + public IMethodSymbol[] GetAccessors() { - throw new NotImplementedException(); + return ResolveMethodSymbols(_property.GetAccessors()); } /// - public IMethodSymbol[] GetAccessors() + public IMethodSymbol[] GetAccessors(bool nonPublic) { - return ResolveMethodSymbols(_property.GetAccessors()); + return ResolveMethodSymbols(_property.GetAccessors(nonPublic)); } /// - public IMethodSymbol[] GetAccessors(bool nonPublic) + public IParameterSymbol[] GetIndexParameters() { - throw new NotImplementedException(); + return ResolveParameterSymbols(_property.GetIndexParameters()); } /// @@ -101,6 +98,12 @@ public IMethodSymbol[] GetAccessors(bool nonPublic) return _property.GetSetMethod(nonPublic) is MethodInfo m ? ResolveMethodSymbol(m) : null; } + /// + public ITypeSymbol GetModifiedPropertyType() + { + throw new NotImplementedException(); + } + /// public ITypeSymbol[] GetOptionalCustomModifiers() { @@ -112,6 +115,17 @@ public ITypeSymbol[] GetRequiredCustomModifiers() { return ResolveTypeSymbols(_property.GetRequiredCustomModifiers()); } + + /// + /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. + /// + /// + internal void Complete(PropertyInfo property) + { + ResolvePropertySymbol(_property = property); + base.Complete(_property); + } + } } \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs index f0d642b56..a469bb946 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs @@ -18,6 +18,9 @@ namespace IKVM.CoreLib.Symbols.IkvmReflection { + /// + /// Base class for managed symbols. + /// abstract class IkvmReflectionSymbol : ISymbol { @@ -38,10 +41,10 @@ public IkvmReflectionSymbol(IkvmReflectionSymbolContext context) protected IkvmReflectionSymbolContext Context => _context; /// - public virtual bool IsMissing => false; + public bool IsMissing => false; /// - public virtual bool ContainsMissing => false; + public bool ContainsMissing => false; /// /// Resolves the symbol for the specified type. @@ -78,20 +81,6 @@ protected internal IEnumerable ResolveModuleSymbols( yield return ResolveModuleSymbol(module); } - /// - /// Unpacks the symbols into their original type. - /// - /// - /// - protected internal Module[] UnpackModuleSymbols(IModuleSymbol[] modules) - { - var a = new Module[modules.Length]; - for (int i = 0; i < modules.Length; i++) - a[i] = ((IkvmReflectionModuleSymbol)modules[i]).ReflectionObject; - - return a; - } - /// /// Resolves the symbol for the specified type. /// @@ -128,20 +117,6 @@ protected internal IkvmReflectionMemberSymbol[] ResolveMemberSymbols(MemberInfo[ return a; } - /// - /// Unpacks the symbols into their original type. - /// - /// - /// - protected internal MemberInfo[] UnpackMemberSymbols(IMemberSymbol[] members) - { - var a = new MemberInfo[members.Length]; - for (int i = 0; i < members.Length; i++) - a[i] = ((IkvmReflectionMemberSymbol)members[i]).ReflectionObject; - - return a; - } - /// /// Resolves the symbol for the specified type. /// @@ -177,20 +152,6 @@ protected internal IEnumerable ResolveTypeSymbols(IEnu yield return ResolveTypeSymbol(type); } - /// - /// Unpacks the symbols into their original type. - /// - /// - /// - protected internal Type[] UnpackTypeSymbols(ITypeSymbol[] types) - { - var a = new Type[types.Length]; - for (int i = 0; i < types.Length; i++) - a[i] = ((IkvmReflectionTypeSymbol)types[i]).ReflectionObject; - - return a; - } - /// /// Resolves the symbol for the specified method. /// @@ -252,30 +213,6 @@ protected internal IkvmReflectionMethodSymbol[] ResolveMethodSymbols(MethodInfo[ return a; } - /// - /// Resolves the symbol for the specified parameter. - /// - /// - /// - protected virtual internal IkvmReflectionParameterSymbol ResolveParameterSymbol(ParameterInfo parameter) - { - return _context.GetOrCreateParameterSymbol(parameter); - } - - /// - /// Resolves the symbols for the specified parameters. - /// - /// - /// - protected internal IkvmReflectionParameterSymbol[] ResolveParameterSymbols(ParameterInfo[] parameters) - { - var a = new IkvmReflectionParameterSymbol[parameters.Length]; - for (int i = 0; i < parameters.Length; i++) - a[i] = ResolveParameterSymbol(parameters[i]); - - return a; - } - /// /// Resolves the symbol for the specified field. /// @@ -348,6 +285,30 @@ protected internal IkvmReflectionEventSymbol[] ResolveEventSymbols(EventInfo[] e return a; } + /// + /// Resolves the symbol for the specified parameter. + /// + /// + /// + protected virtual internal IkvmReflectionParameterSymbol ResolveParameterSymbol(ParameterInfo parameter) + { + return _context.GetOrCreateParameterSymbol(parameter); + } + + /// + /// Resolves the symbols for the specified parameters. + /// + /// + /// + protected internal IkvmReflectionParameterSymbol[] ResolveParameterSymbols(ParameterInfo[] parameters) + { + var a = new IkvmReflectionParameterSymbol[parameters.Length]; + for (int i = 0; i < parameters.Length; i++) + a[i] = ResolveParameterSymbol(parameters[i]); + + return a; + } + /// /// Transforms a custom set of custom attribute data records to a symbol record. /// @@ -362,12 +323,25 @@ protected internal CustomAttribute[] ResolveCustomAttributes(IList + /// Transforms a custom set of custom attribute data records to a symbol record. + /// + /// + /// + protected internal CustomAttribute[] ResolveCustomAttributes(IEnumerable attributes) + { + var a = new List(); + foreach (var i in attributes) + a.Add(ResolveCustomAttribute(i)); + + return a.ToArray(); + } + /// /// Transforms a custom attribute data record to a symbol record. /// /// /// - /// protected internal CustomAttribute ResolveCustomAttribute(CustomAttributeData customAttributeData) { return new CustomAttribute( @@ -408,7 +382,7 @@ CustomAttributeTypedArgument ResolveCustomAttributeTypedArgument(IKVM.Reflection /// object? ResolveCustomAttributeTypedValue(object? value) { - if (value is IKVM.Reflection.Type v) + if (value is Type v) return ResolveTypeSymbol(v); return value; @@ -425,11 +399,11 @@ ImmutableArray ResolveCustomAttributeNamedArgument for (int i = 0; i < args.Count; i++) a[i] = ResolveCustomAttributeNamedArgument(args[i]); - return a.ToImmutableArray(); + return ImmutableArray.Create(a); } /// - /// Transforms a values into a symbol. + /// Transforms a values into a symbol. /// /// /// diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolContext.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolContext.cs index fcbc6d34d..53ce1511f 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolContext.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolContext.cs @@ -1,6 +1,11 @@ using System; +using System.Collections.Concurrent; using System.Runtime.CompilerServices; +using IKVM.CoreLib.Reflection; +using IKVM.CoreLib.Symbols.IkvmReflection.Emit; +using IKVM.Reflection.Emit; + using Assembly = IKVM.Reflection.Assembly; using ConstructorInfo = IKVM.Reflection.ConstructorInfo; using EventInfo = IKVM.Reflection.EventInfo; @@ -21,7 +26,8 @@ namespace IKVM.CoreLib.Symbols.IkvmReflection class IkvmReflectionSymbolContext { - readonly ConditionalWeakTable _assemblies = new(); + readonly ConcurrentDictionary> _symbolByName = new(AssemblyNameEqualityComparer.Instance); + readonly ConditionalWeakTable _symbolByAssembly = new(); /// /// Initializes a new instance. @@ -31,6 +37,30 @@ public IkvmReflectionSymbolContext() } + /// + /// Gets or creates a indexed based on the assembly's name. + /// + /// + /// + IkvmReflectionAssemblySymbol GetOrCreateAssemblySymbolByName(Assembly assembly) + { + var r = _symbolByName.GetOrAdd(assembly.GetName().ToAssemblyName(), _ => new WeakReference(new IkvmReflectionAssemblySymbol(this, assembly))); + + // reference has valid symbol + if (r.TryGetTarget(out var s)) + return s; + + // no valid symbol, must have been released, lock to restore + lock (r) + { + // still gone, recreate + if (r.TryGetTarget(out s) == false) + r.SetTarget(s = new IkvmReflectionAssemblySymbol(this, assembly)); + + return s; + } + } + /// /// Gets or creates a for the specified . /// @@ -38,10 +68,7 @@ public IkvmReflectionSymbolContext() /// public IkvmReflectionAssemblySymbol GetOrCreateAssemblySymbol(Assembly assembly) { - if (assembly is null) - throw new ArgumentNullException(nameof(assembly)); - - return _assemblies.GetValue(assembly, _ => new IkvmReflectionAssemblySymbol(this, _)); + return _symbolByAssembly.GetValue(assembly, GetOrCreateAssemblySymbolByName); } /// @@ -51,9 +78,6 @@ public IkvmReflectionAssemblySymbol GetOrCreateAssemblySymbol(Assembly assembly) /// public IkvmReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) { - if (module is null) - throw new ArgumentNullException(nameof(module)); - return GetOrCreateAssemblySymbol(module.Assembly).GetOrCreateModuleSymbol(module); } @@ -64,12 +88,22 @@ public IkvmReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) /// public IkvmReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) { - if (type is null) - throw new ArgumentNullException(nameof(type)); - return GetOrCreateModuleSymbol(type.Module).GetOrCreateTypeSymbol(type); } + /// + /// Gets or creates a for the specified . + /// + /// + /// + public IkvmReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method) + { + if (method is ConstructorInfo ctor) + return GetOrCreateConstructorSymbol(ctor); + else + return GetOrCreateMethodSymbol((MethodInfo)method); + } + /// /// Gets or creates a for the specified . /// @@ -77,23 +111,17 @@ public IkvmReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) /// public IkvmReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) { - if (ctor is null) - throw new ArgumentNullException(nameof(ctor)); - - return GetOrCreateAssemblySymbol(ctor.Module.Assembly).GetOrCreateModuleSymbol(ctor.Module).GetOrCreateTypeSymbol(ctor.DeclaringType!).GetOrCreateConstructorSymbol(ctor); + return GetOrCreateModuleSymbol(ctor.Module).GetOrCreateConstructorSymbol(ctor); } /// - /// Gets or creates a for the specified . + /// Gets or creates a for the specified . /// /// /// public IkvmReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) { - if (method is null) - throw new ArgumentNullException(nameof(method)); - - return GetOrCreateAssemblySymbol(method.Module.Assembly).GetOrCreateModuleSymbol(method.Module).GetOrCreateTypeSymbol(method.DeclaringType!).GetOrCreateMethodSymbol(method); + return GetOrCreateModuleSymbol(method.Module).GetOrCreateMethodSymbol(method); } /// @@ -103,10 +131,7 @@ public IkvmReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) /// public IkvmReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) { - if (parameter is null) - throw new ArgumentNullException(nameof(parameter)); - - return GetOrCreateAssemblySymbol(parameter.Member.Module.Assembly).GetOrCreateModuleSymbol(parameter.Member.Module).GetOrCreateTypeSymbol(parameter.Member.DeclaringType!).GetOrCreateMethodBaseSymbol((MethodBase)parameter.Member).GetOrCreateParameterSymbol(parameter); + return GetOrCreateModuleSymbol(parameter.Member.Module).GetOrCreateParameterSymbol(parameter); } /// @@ -116,10 +141,7 @@ public IkvmReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo pa /// public IkvmReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) { - if (field is null) - throw new ArgumentNullException(nameof(field)); - - return GetOrCreateAssemblySymbol(field.Module.Assembly).GetOrCreateModuleSymbol(field.Module).GetOrCreateTypeSymbol(field.DeclaringType!).GetOrCreateFieldSymbol(field); + return GetOrCreateModuleSymbol(field.Module).GetOrCreateFieldSymbol(field); } /// @@ -129,10 +151,7 @@ public IkvmReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) /// public IkvmReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) { - if (property is null) - throw new ArgumentNullException(nameof(property)); - - return GetOrCreateAssemblySymbol(property.Module.Assembly).GetOrCreateModuleSymbol(property.Module).GetOrCreateTypeSymbol(property.DeclaringType!).GetOrCreatePropertySymbol(property); + return GetOrCreateModuleSymbol(property.Module).GetOrCreatePropertySymbol(property); } /// @@ -142,10 +161,18 @@ public IkvmReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo prope /// public IkvmReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) { - if (@event is null) - throw new ArgumentNullException(nameof(@event)); + return GetOrCreateModuleSymbol(@event.Module).GetOrCreateEventSymbol(@event); + } - return GetOrCreateAssemblySymbol(@event.Module.Assembly).GetOrCreateModuleSymbol(@event.Module).GetOrCreateTypeSymbol(@event.DeclaringType!).GetOrCreateEventSymbol(@event); + /// + /// Gets or creates a for the specified . + /// + /// + /// + /// + public IkvmReflectionParameterSymbol GetOrCreateParameterSymbol(MethodBuilder method, ParameterBuilder parameter) + { + return GetOrCreateParameterSymbol(new IkvmReflectionParameterBuilderInfo(method, parameter)); } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs index aad2c1979..a3d3ef7c5 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs @@ -1,18 +1,16 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Linq; -using System.Reflection.Metadata.Ecma335; using System.Threading; +using IKVM.CoreLib.Symbols.Reflection; using IKVM.Reflection; using ConstructorInfo = IKVM.Reflection.ConstructorInfo; -using EventInfo = IKVM.Reflection.EventInfo; using FieldInfo = IKVM.Reflection.FieldInfo; -using MethodBase = IKVM.Reflection.MethodBase; using MethodInfo = IKVM.Reflection.MethodInfo; -using PropertyInfo = IKVM.Reflection.PropertyInfo; using Type = IKVM.Reflection.Type; namespace IKVM.CoreLib.Symbols.IkvmReflection @@ -21,35 +19,17 @@ namespace IKVM.CoreLib.Symbols.IkvmReflection class IkvmReflectionTypeSymbol : IkvmReflectionMemberSymbol, ITypeSymbol { - const BindingFlags DefaultBindingFlags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance; - - readonly Type _type; - - MethodBase[]? _methodsSource; - int _methodsBaseRow; - IkvmReflectionMethodBaseSymbol?[]? _methods; - - FieldInfo[]? _fieldsSource; - int _fieldsBaseRow; - IkvmReflectionFieldSymbol?[]? _fields; + const int MAX_CAPACITY = 65536 * 2; - PropertyInfo[]? _propertiesSource; - int _propertiesBaseRow; - IkvmReflectionPropertySymbol?[]? _properties; + const BindingFlags DefaultBindingFlags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance; - EventInfo[]? _eventsSource; - int _eventsBaseRow; - IkvmReflectionEventSymbol?[]? _events; + Type _type; IkvmReflectionTypeSymbol?[]? _asArray; IkvmReflectionTypeSymbol? _asSZArray; IkvmReflectionTypeSymbol? _asPointer; IkvmReflectionTypeSymbol? _asByRef; - - Type[]? _genericParametersSource; - IkvmReflectionTypeSymbol?[]? _genericParameters; - List<(Type[] Arguments, IkvmReflectionTypeSymbol Symbol)>? _genericTypes; - ReaderWriterLockSlim? _genericTypesLock; + ConcurrentDictionary? _genericTypeSymbols; /// /// Initializes a new instance. @@ -58,278 +38,18 @@ class IkvmReflectionTypeSymbol : IkvmReflectionMemberSymbol, ITypeSymbol /// /// public IkvmReflectionTypeSymbol(IkvmReflectionSymbolContext context, IkvmReflectionModuleSymbol module, Type type) : - base(context, module, null, type) + base(context, module, type) { Debug.Assert(module.ReflectionObject == type.Module); _type = type ?? throw new ArgumentNullException(nameof(type)); } - /// - /// Gets or creates the cached for the type by method. - /// - /// - /// - internal IkvmReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) - { - return (IkvmReflectionMethodSymbol)GetOrCreateMethodBaseSymbol(method); - } - - /// - /// Gets or creates the cached for the type by ctor. - /// - /// - /// - internal IkvmReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) - { - return (IkvmReflectionConstructorSymbol)GetOrCreateMethodBaseSymbol(ctor); - } - - /// - /// Gets or creates the cached for the type by method. - /// - /// - /// - internal IkvmReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method) - { - if (method is null) - throw new ArgumentNullException(nameof(method)); - - Debug.Assert(method.DeclaringType == _type); - - var hnd = MetadataTokens.MethodDefinitionHandle(method.MetadataToken); - var row = MetadataTokens.GetRowNumber(hnd); - - // initialize source table - if (_methodsSource == null) - { - Interlocked.CompareExchange(ref _methodsSource, _type.GetConstructors(DefaultBindingFlags).Cast().Concat(_type.GetMethods(DefaultBindingFlags)).OrderBy(i => i.MetadataToken).ToArray(), null); - _methodsBaseRow = _methodsSource.Length != 0 ? MetadataTokens.GetRowNumber(MetadataTokens.MethodDefinitionHandle(_methodsSource[0].MetadataToken)) : 0; - } - - // initialize cache table - if (_methods == null) - Interlocked.CompareExchange(ref _methods, new IkvmReflectionMethodBaseSymbol?[_methodsSource.Length], null); - - // index of current record is specified row - base - var idx = row - _methodsBaseRow; - Debug.Assert(idx >= 0); - Debug.Assert(idx < _methodsSource.Length); - - // check that our list is long enough to contain the entire table - if (_methods.Length < idx) - throw new IndexOutOfRangeException(); - - // if not yet created, create, allow multiple instances, but only one is eventually inserted - ref var rec = ref _methods[idx]; - if (rec == null) - { - switch (method) - { - case ConstructorInfo c: - Interlocked.CompareExchange(ref rec, new IkvmReflectionConstructorSymbol(Context, ContainingModule, this, c), null); - break; - case MethodInfo m: - Interlocked.CompareExchange(ref rec, new IkvmReflectionMethodSymbol(Context, ContainingModule, this, m), null); - break; - } - } - - // this should never happen - if (rec is not IkvmReflectionMethodBaseSymbol sym) - throw new InvalidOperationException(); - - return sym; - } - - /// - /// Gets or creates the cached for the type by field. - /// - /// - /// - /// - internal IkvmReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) - { - if (field is null) - throw new ArgumentNullException(nameof(field)); - - Debug.Assert(field.DeclaringType == _type); - - var hnd = MetadataTokens.FieldDefinitionHandle(field.MetadataToken); - var row = MetadataTokens.GetRowNumber(hnd); - - // initialize source table - if (_fieldsSource == null) - { - Interlocked.CompareExchange(ref _fieldsSource, _type.GetFields(DefaultBindingFlags).OrderBy(i => i.MetadataToken).ToArray(), null); - _fieldsBaseRow = _fieldsSource.Length != 0 ? MetadataTokens.GetRowNumber(MetadataTokens.MethodDefinitionHandle(_fieldsSource[0].MetadataToken)) : 0; - } - - // initialize cache table - if (_fields == null) - Interlocked.CompareExchange(ref _fields, new IkvmReflectionFieldSymbol?[_fieldsSource.Length], null); - - // index of current field is specified row - base - var idx = row - _fieldsBaseRow; - Debug.Assert(idx >= 0); - Debug.Assert(idx < _fieldsSource.Length); - - // check that our list is long enough to contain the entire table - if (_fields.Length < idx) - throw new IndexOutOfRangeException(); - - // if not yet created, create, allow multiple instances, but only one is eventually inserted - ref var rec = ref _fields[idx]; - if (rec == null) - Interlocked.CompareExchange(ref rec, new IkvmReflectionFieldSymbol(Context, this, field), null); - - // this should never happen - if (rec is not IkvmReflectionFieldSymbol sym) - throw new InvalidOperationException(); - - return sym; - } - - /// - /// Gets or creates the cached for the type by property. - /// - /// - /// - /// - internal IkvmReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) - { - if (property is null) - throw new ArgumentNullException(nameof(property)); - - Debug.Assert(property.DeclaringType == _type); - - var hnd = MetadataTokens.PropertyDefinitionHandle(property.MetadataToken); - var row = MetadataTokens.GetRowNumber(hnd); - - // initialize source table - if (_propertiesSource == null) - { - Interlocked.CompareExchange(ref _propertiesSource, _type.GetProperties(DefaultBindingFlags).OrderBy(i => i.MetadataToken).ToArray(), null); - _propertiesBaseRow = _propertiesSource.Length != 0 ? MetadataTokens.GetRowNumber(MetadataTokens.MethodDefinitionHandle(_propertiesSource[0].MetadataToken)) : 0; - } - - // initialize cache table - if (_properties == null) - Interlocked.CompareExchange(ref _properties, new IkvmReflectionPropertySymbol?[_propertiesSource.Length], null); - - // index of current property is specified row - base - var idx = row - _propertiesBaseRow; - Debug.Assert(idx >= 0); - Debug.Assert(idx < _propertiesSource.Length); - - // check that our list is long enough to contain the entire table - if (_properties.Length < idx) - throw new IndexOutOfRangeException(); - - // if not yet created, create, allow multiple instances, but only one is eventually inserted - ref var rec = ref _properties[idx]; - if (rec == null) - Interlocked.CompareExchange(ref rec, new IkvmReflectionPropertySymbol(Context, this, property), null); - - // this should never happen - if (rec is not IkvmReflectionPropertySymbol sym) - throw new InvalidOperationException(); - - return sym; - } - - /// - /// Gets or creates the cached for the type by event. - /// - /// - /// - /// - internal IkvmReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) - { - if (@event is null) - throw new ArgumentNullException(nameof(@event)); - - Debug.Assert(@event.DeclaringType == _type); - - var hnd = MetadataTokens.PropertyDefinitionHandle(@event.MetadataToken); - var row = MetadataTokens.GetRowNumber(hnd); - - // initialize source events - if (_eventsSource == null) - { - Interlocked.CompareExchange(ref _eventsSource, _type.GetEvents(DefaultBindingFlags).OrderBy(i => i.MetadataToken).ToArray(), null); - _eventsBaseRow = _eventsSource.Length != 0 ? MetadataTokens.GetRowNumber(MetadataTokens.EventDefinitionHandle(_eventsSource[0].MetadataToken)) : 0; - } - - // initialize cache table - if (_events == null) - Interlocked.CompareExchange(ref _events, new IkvmReflectionEventSymbol?[_eventsSource.Length], null); - - // index of current event is specified row - base - var idx = row - _eventsBaseRow; - Debug.Assert(idx >= 0); - Debug.Assert(idx < _eventsSource.Length); - - // check that our list is long enough to contain the entire table - if (_events.Length < idx) - throw new IndexOutOfRangeException(); - - // if not yet created, create, allow multiple instances, but only one is eventually inserted - ref var rec = ref _events[idx]; - if (rec == null) - Interlocked.CompareExchange(ref rec, new IkvmReflectionEventSymbol(Context, this, @event), null); - - // this should never happen - if (rec is not IkvmReflectionEventSymbol sym) - throw new InvalidOperationException(); - - return sym; - } - - /// - /// Gets or creates the cached for the generic parameter type. - /// - /// - /// - /// - internal IkvmReflectionTypeSymbol GetOrCreateGenericParameterSymbol(Type genericTypeParameterType) - { - if (genericTypeParameterType is null) - throw new ArgumentNullException(nameof(genericTypeParameterType)); - - Debug.Assert(genericTypeParameterType.DeclaringType == _type); - - // initialize tables - if (_genericParametersSource == null) - Interlocked.CompareExchange(ref _genericParametersSource, _type.GetGenericArguments(), null); - if (_genericParameters == null) - Interlocked.CompareExchange(ref _genericParameters, new IkvmReflectionTypeSymbol?[_genericParametersSource.Length], null); - - // position of the parameter in the list - var idx = genericTypeParameterType.GenericParameterPosition; - - // check that our list is long enough to contain the entire table - if (_genericParameters.Length < idx) - throw new IndexOutOfRangeException(); - - // if not yet created, create, allow multiple instances, but only one is eventually inserted - ref var rec = ref _genericParameters[idx]; - if (rec == null) - Interlocked.CompareExchange(ref rec, new IkvmReflectionTypeSymbol(Context, ContainingModule, genericTypeParameterType), null); - - // this should never happen - if (rec is not IkvmReflectionTypeSymbol sym) - throw new InvalidOperationException(); - - return sym; - } - /// /// Gets or creates the cached for the generic parameter type. /// /// /// - /// - internal IkvmReflectionTypeSymbol GetOrCreateGenericTypeSymbol(Type[] genericTypeArguments) + internal IkvmReflectionTypeSymbol GetOrCreateGenericTypeSymbol(ITypeSymbol[] genericTypeArguments) { if (genericTypeArguments is null) throw new ArgumentNullException(nameof(genericTypeArguments)); @@ -337,45 +57,12 @@ internal IkvmReflectionTypeSymbol GetOrCreateGenericTypeSymbol(Type[] genericTyp if (_type.IsGenericTypeDefinition == false) throw new InvalidOperationException(); - // initialize the available parameters - if (_genericParametersSource == null) - Interlocked.CompareExchange(ref _genericParametersSource, _type.GetGenericArguments(), null); - if (_genericParametersSource.Length != genericTypeArguments.Length) - throw new InvalidOperationException(); + if (_genericTypeSymbols == null) + Interlocked.CompareExchange(ref _genericTypeSymbols, new ConcurrentDictionary(TypeSymbolListEqualityComparer.Instance), null); - // initialize generic type map, and lock on it since we're potentially adding items - if (_genericTypes == null) - Interlocked.CompareExchange(ref _genericTypes, [], null); - if (_genericTypesLock == null) - Interlocked.CompareExchange(ref _genericTypesLock, new(), null); - - try - { - _genericTypesLock.EnterUpgradeableReadLock(); - - // find existing entry - foreach (var i in _genericTypes) - if (i.Arguments.SequenceEqual(genericTypeArguments)) - return i.Symbol; - - try - { - _genericTypesLock.EnterWriteLock(); - - // generate new symbol - var sym = new IkvmReflectionTypeSymbol(Context, ContainingModule, _type.MakeGenericType(genericTypeArguments)); - _genericTypes.Add((genericTypeArguments, sym)); - return sym; - } - finally - { - _genericTypesLock.ExitWriteLock(); - } - } - finally - { - _genericTypesLock.ExitUpgradeableReadLock(); - } + return _genericTypeSymbols.GetOrAdd( + genericTypeArguments, + _ => new IkvmReflectionTypeSymbol(Context, ContainingModule, _type.MakeGenericType(genericTypeArguments.Unpack()))); } /// @@ -391,71 +78,6 @@ protected internal override IkvmReflectionTypeSymbol ResolveTypeSymbol(Type type return base.ResolveTypeSymbol(type); } - /// - /// Resolves the symbol for the specified constructor. - /// - /// - /// - protected internal override IkvmReflectionConstructorSymbol ResolveConstructorSymbol(ConstructorInfo ctor) - { - if (ctor.DeclaringType == _type) - return GetOrCreateConstructorSymbol(ctor); - else - return base.ResolveConstructorSymbol(ctor); - } - - /// - /// Resolves the symbol for the specified method. - /// - /// - /// - protected internal override IkvmReflectionMethodSymbol ResolveMethodSymbol(MethodInfo method) - { - if (method.DeclaringType == _type) - return GetOrCreateMethodSymbol(method); - else - return base.ResolveMethodSymbol(method); - } - - /// - /// Resolves the symbol for the specified field. - /// - /// - /// - protected internal override IkvmReflectionFieldSymbol ResolveFieldSymbol(FieldInfo field) - { - if (field.DeclaringType == _type) - return GetOrCreateFieldSymbol(field); - else - return base.ResolveFieldSymbol(field); - } - - /// - /// Resolves the symbol for the specified field. - /// - /// - /// - protected internal override IkvmReflectionPropertySymbol ResolvePropertySymbol(PropertyInfo property) - { - if (property.DeclaringType == _type) - return GetOrCreatePropertySymbol(property); - else - return base.ResolvePropertySymbol(property); - } - - /// - /// Resolves the symbol for the specified event. - /// - /// - /// - protected internal override IkvmReflectionEventSymbol ResolveEventSymbol(EventInfo @event) - { - if (@event.DeclaringType == _type) - return GetOrCreateEventSymbol(@event); - else - return base.ResolveEventSymbol(@event); - } - /// /// Gets the wrapped . /// @@ -468,7 +90,7 @@ protected internal override IkvmReflectionEventSymbol ResolveEventSymbol(EventIn public string? AssemblyQualifiedName => _type.AssemblyQualifiedName; /// - public System.Reflection.TypeAttributes Attributes => (System.Reflection.TypeAttributes)(int)_type.Attributes; + public System.Reflection.TypeAttributes Attributes => (System.Reflection.TypeAttributes)_type.Attributes; /// public ITypeSymbol? BaseType => _type.BaseType != null ? ResolveTypeSymbol(_type.BaseType) : null; @@ -486,7 +108,7 @@ protected internal override IkvmReflectionEventSymbol ResolveEventSymbol(EventIn public string? Namespace => _type.Namespace; /// - public System.Reflection.GenericParameterAttributes GenericParameterAttributes => (System.Reflection.GenericParameterAttributes)(int)_type.GenericParameterAttributes; + public System.Reflection.GenericParameterAttributes GenericParameterAttributes => (System.Reflection.GenericParameterAttributes)_type.GenericParameterAttributes; /// public int GenericParameterPosition => _type.GenericParameterPosition; @@ -497,12 +119,29 @@ protected internal override IkvmReflectionEventSymbol ResolveEventSymbol(EventIn /// public bool HasElementType => _type.HasElementType; + /// + public TypeCode TypeCode => Type.GetTypeCode(_type); + /// public bool IsAbstract => _type.IsAbstract; +#if NETFRAMEWORK + + /// + /// + /// There's no API to distinguish an array of rank 1 from a vector, + /// so we check if the type name ends in [], which indicates it's a vector + /// (non-vectors will have [*] or [,]). + /// + public bool IsSZArray => _type.IsArray && _type.Name.EndsWith("[]"); + +#else + /// public bool IsSZArray => _type.IsSZArray; +#endif + /// public bool IsArray => _type.IsArray; @@ -519,10 +158,13 @@ protected internal override IkvmReflectionEventSymbol ResolveEventSymbol(EventIn public bool IsClass => _type.IsClass; /// - public bool IsConstructedGenericType => _type.IsConstructedGenericType; + public bool IsEnum => _type.IsEnum; /// - public bool IsEnum => _type.IsEnum; + public bool IsInterface => _type.IsInterface; + + /// + public bool IsConstructedGenericType => _type.IsConstructedGenericType; /// public bool IsGenericParameter => _type.IsGenericParameter; @@ -533,9 +175,6 @@ protected internal override IkvmReflectionEventSymbol ResolveEventSymbol(EventIn /// public bool IsGenericTypeDefinition => _type.IsGenericTypeDefinition; - /// - public bool IsInterface => _type.IsInterface; - /// public bool IsLayoutSequential => _type.IsLayoutSequential; @@ -566,12 +205,24 @@ protected internal override IkvmReflectionEventSymbol ResolveEventSymbol(EventIn /// public bool IsPointer => _type.IsPointer; +#if NET8_0_OR_GREATER + /// public bool IsFunctionPointer => _type.IsFunctionPointer; /// public bool IsUnmanagedFunctionPointer => _type.IsUnmanagedFunctionPointer; +#else + + /// + public bool IsFunctionPointer => throw new NotImplementedException(); + + /// + public bool IsUnmanagedFunctionPointer => throw new NotImplementedException(); + +#endif + /// public bool IsPrimitive => _type.IsPrimitive; @@ -581,10 +232,8 @@ protected internal override IkvmReflectionEventSymbol ResolveEventSymbol(EventIn /// public bool IsSealed => _type.IsSealed; -#pragma warning disable SYSLIB0050 // Type or member is obsolete /// public bool IsSerializable => _type.IsSerializable; -#pragma warning restore SYSLIB0050 // Type or member is obsolete /// public bool IsValueType => _type.IsValueType; @@ -598,18 +247,9 @@ protected internal override IkvmReflectionEventSymbol ResolveEventSymbol(EventIn /// public bool IsSpecialName => _type.IsSpecialName; - /// - public TypeCode TypeCode => Type.GetTypeCode(_type); - /// public IConstructorSymbol? TypeInitializer => _type.TypeInitializer is ConstructorInfo ctor ? ResolveConstructorSymbol(ctor) : null; - /// - public override bool IsMissing => _type.__IsMissing; - - /// - public override bool ContainsMissing => _type.__ContainsMissingType; - /// public int GetArrayRank() { @@ -619,13 +259,13 @@ public int GetArrayRank() /// public IConstructorSymbol? GetConstructor(System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) { - return _type.GetConstructor((BindingFlags)bindingAttr, binder: null, UnpackTypeSymbols(types), modifiers: null) is ConstructorInfo ctor ? ResolveConstructorSymbol(ctor) : null; + return _type.GetConstructor((BindingFlags)bindingAttr, binder: null, types.Unpack(), modifiers: null) is ConstructorInfo ctor ? ResolveConstructorSymbol(ctor) : null; } /// public IConstructorSymbol? GetConstructor(ITypeSymbol[] types) { - return _type.GetConstructor(UnpackTypeSymbols(types)) is ConstructorInfo ctor ? ResolveConstructorSymbol(ctor) : null; + return _type.GetConstructor(types.Unpack()) is ConstructorInfo ctor ? ResolveConstructorSymbol(ctor) : null; } /// @@ -670,10 +310,16 @@ public ITypeSymbol GetEnumUnderlyingType() return ResolveTypeSymbol(_type.GetEnumUnderlyingType()); } + /// + public Array GetEnumValues() + { + return _type.GetEnumValues(); + } + /// public IEventSymbol? GetEvent(string name, System.Reflection.BindingFlags bindingAttr) { - return _type.GetEvent(name, (BindingFlags)bindingAttr) is { } f ? ResolveEventSymbol(f) : null; + throw new NotImplementedException(); } /// @@ -760,7 +406,7 @@ public ITypeSymbol[] GetInterfaces(bool inherit = true) if (inherit) return ResolveTypeSymbols(_type.GetInterfaces()); else - return ResolveTypeSymbols(_type.__GetDeclaredInterfaces()); + throw new NotImplementedException(); } /// @@ -800,15 +446,15 @@ public IMemberSymbol[] GetMembers() } /// - public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) + public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) { - return _type.GetMethod(name, (BindingFlags)bindingAttr, null, UnpackTypeSymbols(types), null) is { } m ? ResolveMethodSymbol(m) : null; + return _type.GetMethod(name, types.Unpack()) is { } m ? ResolveMethodSymbol(m) : null; } /// - public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) { - return _type.GetMethod(name, UnpackTypeSymbols(types)) is { } m ? ResolveMethodSymbol(m) : null; + return _type.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), null) is { } m ? ResolveMethodSymbol(m) : null; } /// @@ -818,12 +464,33 @@ public IMemberSymbol[] GetMembers() } /// - public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - if (modifiers != null) - throw new NotImplementedException(); + return _type.GetMethod(name, (BindingFlags)bindingAttr, null, (CallingConventions)callConvention, types.Unpack(), modifiers?.Unpack()) is { } m ? ResolveMethodSymbol(m) : null; + } + + /// + public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + { + throw new NotImplementedException(); + } + + /// + public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + { + throw new NotImplementedException(); + } - return _type.GetMethod(name, UnpackTypeSymbols(types), null) is { } m ? ResolveMethodSymbol(m) : null; + /// + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + { + return _type.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), modifiers?.Unpack()) is { } m ? ResolveMethodSymbol(m) : null; + } + + /// + public IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + { + throw new NotImplementedException(); } /// @@ -874,27 +541,16 @@ public IPropertySymbol[] GetProperties(System.Reflection.BindingFlags bindingAtt return ResolvePropertySymbols(_type.GetProperties((BindingFlags)bindingAttr)); } - /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) - { - if (modifiers != null) - throw new NotImplementedException(); - - var _returnType = returnType != null ? ((IkvmReflectionTypeSymbol)returnType).ReflectionObject : null; - return _type.GetProperty(name, _returnType, UnpackTypeSymbols(types), null) is { } p ? ResolvePropertySymbol(p) : null; - } - /// public IPropertySymbol? GetProperty(string name, ITypeSymbol[] types) { - return _type.GetProperty(name, UnpackTypeSymbols(types)) is { } p ? ResolvePropertySymbol(p) : null; + return _type.GetProperty(name, types.Unpack()) is { } p ? ResolvePropertySymbol(p) : null; } /// public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types) { - var _returnType = returnType != null ? ((IkvmReflectionTypeSymbol)returnType).ReflectionObject : null; - return _type.GetProperty(name, _returnType, UnpackTypeSymbols(types)) is { } p ? ResolvePropertySymbol(p) : null; + return _type.GetProperty(name, returnType?.Unpack(), types.Unpack()) is { } p ? ResolvePropertySymbol(p) : null; } /// @@ -912,15 +568,13 @@ public IPropertySymbol[] GetProperties(System.Reflection.BindingFlags bindingAtt /// public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) { - var _returnType = returnType != null ? ((IkvmReflectionTypeSymbol)returnType).ReflectionObject : null; - - return _type.GetProperty(name, _returnType) is { } p ? ResolvePropertySymbol(p) : null; + return _type.GetProperty(name, returnType?.Unpack()) is { } p ? ResolvePropertySymbol(p) : null; } /// public bool IsAssignableFrom(ITypeSymbol? c) { - return _type.IsAssignableFrom(c != null ? ((IkvmReflectionTypeSymbol)c).ReflectionObject : null); + return _type.IsAssignableFrom(c?.Unpack()); } /// @@ -932,7 +586,7 @@ public bool IsEnumDefined(object value) /// public bool IsSubclassOf(ITypeSymbol c) { - return _type.IsSubclassOf(((IkvmReflectionTypeSymbol)c).ReflectionObject); + return _type.IsSubclassOf(c.Unpack()); } /// @@ -984,6 +638,32 @@ public ITypeSymbol MakePointerType() return _asPointer; } + /// + /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. + /// + /// + internal void Complete(Type type) + { + ResolveTypeSymbol(_type = type); + base.Complete(_type); + + ContainingModule.Complete(_type.Module); + + foreach (var i in _type.GetConstructors(DefaultBindingFlags)) + ResolveConstructorSymbol(i).Complete(i); + + foreach (var i in _type.GetMethods(DefaultBindingFlags)) + ResolveMethodSymbol(i).Complete(i); + + foreach (var i in _type.GetFields(DefaultBindingFlags)) + ResolveFieldSymbol(i).Complete(i); + + foreach (var i in _type.GetProperties(DefaultBindingFlags)) + ResolvePropertySymbol(i).Complete(i); + + foreach (var i in _type.GetEvents(DefaultBindingFlags)) + ResolveEventSymbol(i).Complete(i); + } } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionUtil.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionUtil.cs new file mode 100644 index 000000000..d00e0ff60 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionUtil.cs @@ -0,0 +1,195 @@ +using System; + +using IKVM.Reflection; + +using ConstructorInfo = IKVM.Reflection.ConstructorInfo; +using MethodInfo = IKVM.Reflection.MethodInfo; +using Type = IKVM.Reflection.Type; + +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + static class IkvmReflectionUtil + { + + /// + /// Converts the to a . + /// + /// + /// + public static System.Reflection.AssemblyName ToAssemblyName(this AssemblyName src) + { +#pragma warning disable SYSLIB0037 // Type or member is obsolete + return new System.Reflection.AssemblyName() + { + Name = src.Name, + Version = src.Version, + CultureName = src.CultureName, + HashAlgorithm = (System.Configuration.Assemblies.AssemblyHashAlgorithm)src.HashAlgorithm, + Flags = (System.Reflection.AssemblyNameFlags)src.Flags, + ContentType = (System.Reflection.AssemblyContentType)src.ContentType, + }; +#pragma warning restore SYSLIB0037 // Type or member is obsolete + } + + /// + /// Unpacks the symbol into their original type. + /// + /// + /// + public static Module Unpack(this IModuleSymbol module) + { + return ((IkvmReflectionModuleSymbol)module).ReflectionObject; + } + + /// + /// Unpacks the symbols into their original type. + /// + /// + /// + public static Module[] Unpack(this IModuleSymbol[] modules) + { + var a = new Module[modules.Length]; + for (int i = 0; i < modules.Length; i++) + a[i] = modules[i].Unpack(); + + return a; + } + + /// + /// Unpacks the symbol into their original type. + /// + /// + /// + public static Type Unpack(this ITypeSymbol type) + { + return ((IkvmReflectionTypeSymbol)type).ReflectionObject; + } + + /// + /// Unpacks the symbols into their original type. + /// + /// + /// + public static Type[] Unpack(this ITypeSymbol[] types) + { + var a = new Type[types.Length]; + for (int i = 0; i < types.Length; i++) + a[i] = types[i].Unpack(); + + return a; + } + + /// + /// Unpacks the symbols into their original type. + /// + /// + /// + public static Type[][] Unpack(this ITypeSymbol[][] types) + { + var a = new Type[types.Length][]; + for (int i = 0; i < types.Length; i++) + a[i] = types[i].Unpack(); + + return a; + } + + /// + /// Unpacks the symbol into their original type. + /// + /// + /// + public static MemberInfo Unpack(this IMemberSymbol member) + { + return ((IkvmReflectionMemberSymbol)member).ReflectionObject; + } + + /// + /// Unpacks the symbols into their original type. + /// + /// + /// + public static MemberInfo[] Unpack(this IMemberSymbol[] members) + { + var a = new MemberInfo[members.Length]; + for (int i = 0; i < members.Length; i++) + a[i] = members[i].Unpack(); + + return a; + } + + /// + /// Unpacks the symbol into their original type. + /// + /// + /// + public static ConstructorInfo Unpack(this IConstructorSymbol ctor) + { + return ((IkvmReflectionConstructorSymbol)ctor).ReflectionObject; + } + + /// + /// Unpacks the symbols into their original type. + /// + /// + /// + public static ConstructorInfo[] Unpack(this IConstructorSymbol[] ctor) + { + var a = new ConstructorInfo[ctor.Length]; + for (int i = 0; i < ctor.Length; i++) + a[i] = ctor[i].Unpack(); + + return a; + } + + /// + /// Unpacks the symbol into their original type. + /// + /// + /// + public static MethodInfo Unpack(this IMethodSymbol ctor) + { + return ((IkvmReflectionMethodSymbol)ctor).ReflectionObject; + } + + /// + /// Unpacks the symbols into their original type. + /// + /// + /// + public static MethodInfo[] Unpack(this IMethodSymbol[] ctor) + { + var a = new MethodInfo[ctor.Length]; + for (int i = 0; i < ctor.Length; i++) + a[i] = ctor[i].Unpack(); + + return a; + } + + /// + /// Unpacks the modifier into their original type. + /// + /// + /// + public static ParameterModifier Unpack(this System.Reflection.ParameterModifier modifier) + { + throw new NotImplementedException(); + } + + /// + /// Unpacks the modifiers into their original types. + /// + /// + /// + public static ParameterModifier[] Unpack(this System.Reflection.ParameterModifier[] ctor) + { + var a = new ParameterModifier[ctor.Length]; + for (int i = 0; i < ctor.Length; i++) + a[i] = ctor[i].Unpack(); + + return a; + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs index 25f8018f3..ee05a37ce 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs @@ -32,6 +32,26 @@ public IModuleSymbolBuilder DefineModule(string name) return new ReflectionModuleSymbolBuilder(Context, _builder.DefineDynamicModule(name)); } + /// + public IModuleSymbolBuilder DefineModule(string name, string fileName) + { +#if NETFRAMEWORK + return new ReflectionModuleSymbolBuilder(Context, _builder.DefineDynamicModule(name, fileName)); +#else + return new ReflectionModuleSymbolBuilder(Context, _builder.DefineDynamicModule(name)); +#endif + } + + /// + public IModuleSymbolBuilder DefineModule(string name, string fileName, bool emitSymbolInfo) + { +#if NETFRAMEWORK + return new ReflectionModuleSymbolBuilder(Context, _builder.DefineDynamicModule(name, fileName, emitSymbolInfo)); +#else + return new ReflectionModuleSymbolBuilder(Context, _builder.DefineDynamicModule(name)); +#endif + } + /// public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) { diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionConstructorSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionConstructorSymbolBuilder.cs index e351e1813..80c895b09 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionConstructorSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionConstructorSymbolBuilder.cs @@ -46,13 +46,13 @@ public IParameterSymbolBuilder DefineParameter(int iSequence, ParameterAttribute } /// - public ILGenerator GetILGenerator() + public IILGenerator GetILGenerator() { throw new NotImplementedException(); } /// - public ILGenerator GetILGenerator(int streamSize) + public IILGenerator GetILGenerator(int streamSize) { throw new NotImplementedException(); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs index 56030a0d7..dd970e657 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs @@ -1,9 +1,5 @@ using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; using System.Reflection; -using System.Threading; namespace IKVM.CoreLib.Symbols.Reflection { @@ -13,10 +9,6 @@ class ReflectionMethodSymbol : ReflectionMethodBaseSymbol, IMethodSymbol readonly MethodInfo _method; - Type[]? _genericParametersSource; - ReflectionTypeSymbol?[]? _genericParameters; - List<(Type[] Arguments, ReflectionMethodSymbol Symbol)>? _genericTypes; - /// /// Initializes a new instance. /// @@ -42,85 +34,6 @@ public ReflectionMethodSymbol(ReflectionSymbolContext context, ReflectionTypeSym } - /// - /// Gets or creates the cached for the generic parameter type. - /// - /// - /// - /// - internal ReflectionTypeSymbol GetOrCreateGenericParameterSymbol(Type genericParameterType) - { - if (genericParameterType is null) - throw new ArgumentNullException(nameof(genericParameterType)); - - Debug.Assert(genericParameterType.DeclaringMethod == _method); - - // initialize tables - _genericParametersSource ??= _method.GetGenericArguments(); - _genericParameters ??= new ReflectionTypeSymbol?[_genericParametersSource.Length]; - - // position of the parameter in the list - var idx = genericParameterType.GenericParameterPosition; - - // check that our list is long enough to contain the entire table - if (_genericParameters.Length < idx) - throw new IndexOutOfRangeException(); - - // if not yet created, create, allow multiple instances, but only one is eventually inserted - ref var rec = ref _genericParameters[idx]; - if (rec == null) - Interlocked.CompareExchange(ref rec, new ReflectionTypeSymbol(Context, ContainingModule, genericParameterType), null); - - // this should never happen - if (rec is not ReflectionTypeSymbol sym) - throw new InvalidOperationException(); - - return sym; - } - - /// - /// Gets or creates the cached for the generic parameter type. - /// - /// - /// - /// - internal ReflectionMethodSymbol GetOrCreateGenericTypeSymbol(Type[] genericMethodArguments) - { - if (genericMethodArguments is null) - throw new ArgumentNullException(nameof(genericMethodArguments)); - - if (_method.IsGenericMethodDefinition == false) - throw new InvalidOperationException(); - - // initialize the available parameters - if (_genericParametersSource == null) - Interlocked.CompareExchange(ref _genericParametersSource, _method.GetGenericArguments(), null); - if (_genericParametersSource.Length != genericMethodArguments.Length) - throw new InvalidOperationException(); - - // initialize generic type map, and lock on it since we're potentially adding items - if (_genericTypes == null) - Interlocked.CompareExchange(ref _genericTypes, [], null); - - lock (_genericTypes) - { - // find existing entry - foreach (var i in _genericTypes) - if (i.Arguments.SequenceEqual(genericMethodArguments)) - return i.Symbol; - - // generate new symbol - ReflectionMethodSymbol sym; - if (ContainingType != null) - sym = new ReflectionMethodSymbol(Context, ContainingType, _method.MakeGenericMethod(genericMethodArguments)); - else - sym = new ReflectionMethodSymbol(Context, ContainingModule, _method.MakeGenericMethod(genericMethodArguments)); - - _genericTypes.Add((genericMethodArguments, sym)); - return sym; - } - } - /// /// Gets the underlying wrapped by this symbol. /// @@ -155,4 +68,4 @@ public IMethodSymbol MakeGenericMethod(params ITypeSymbol[] typeArguments) } -} \ No newline at end of file +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs index 40e757344..f09c9748c 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs @@ -2,6 +2,7 @@ using System.Diagnostics; using System.Linq; using System.Reflection; +using System.Reflection.Metadata.Ecma335; using System.Threading; using IKVM.CoreLib.Collections; @@ -61,6 +62,9 @@ static bool IsTypeDefinition(Type type) IndexRangeDictionary _parameterSymbols = new(); ReaderWriterLockSlim? _parameterLock; + IndexRangeDictionary _genericParameterSymbols = new(); + ReaderWriterLockSlim? _genericParameterLock; + /// /// Initializes a new instance. /// @@ -98,14 +102,17 @@ internal ReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) Debug.Assert(type.Module == _module); - // type is not a definition, but is substituted + // type is a generic parameter (GenericParam) + if (type.IsGenericParameter) + return GetOrCreateGenericParameterSymbol(type); + + // type is not a type definition (TypeDef) if (IsTypeDefinition(type) == false) return GetOrCreateTypeSymbolForSpecification(type); // create lock on demand if (_typeLock == null) - lock (this) - _typeLock ??= new ReaderWriterLockSlim(); + Interlocked.CompareExchange(ref _typeLock, new ReaderWriterLockSlim(), null); using (_typeLock.CreateUpgradeableReadLock()) { @@ -156,21 +163,7 @@ ReflectionTypeSymbol GetOrCreateTypeSymbolForSpecification(Type type) if (type.IsGenericType) { var definitionTypeSymbol = ResolveTypeSymbol(type.GetGenericTypeDefinition()); - return definitionTypeSymbol.GetOrCreateGenericTypeSymbol(type.GetGenericArguments()); - } - - // generic type parameter - if (type.IsGenericParameter && type.DeclaringMethod is null && type.DeclaringType is not null) - { - var declaringType = ResolveTypeSymbol(type.DeclaringType); - return declaringType.GetOrCreateGenericParameterSymbol(type); - } - - // generic method parameter - if (type.IsGenericParameter && type.DeclaringMethod is not null && type.DeclaringMethod.DeclaringType is not null) - { - var declaringMethod = ResolveTypeSymbol(type.DeclaringMethod.DeclaringType); - return declaringMethod.GetOrCreateGenericParameterSymbol(type); + return definitionTypeSymbol.GetOrCreateGenericTypeSymbol(ResolveTypeSymbols(type.GetGenericArguments())); } throw new InvalidOperationException(); @@ -190,8 +183,7 @@ internal ReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase metho // create lock on demand if (_methodLock == null) - lock (this) - _methodLock ??= new ReaderWriterLockSlim(); + Interlocked.CompareExchange(ref _methodLock, new ReaderWriterLockSlim(), null); using (_methodLock.CreateUpgradeableReadLock()) { @@ -251,8 +243,7 @@ internal ReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) // create lock on demand if (_fieldLock == null) - lock (this) - _fieldLock ??= new ReaderWriterLockSlim(); + Interlocked.CompareExchange(ref _fieldLock, new ReaderWriterLockSlim(), null); using (_fieldLock.CreateUpgradeableReadLock()) { @@ -287,8 +278,7 @@ internal ReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo propert // create lock on demand if (_propertyLock == null) - lock (this) - _propertyLock ??= new ReaderWriterLockSlim(); + Interlocked.CompareExchange(ref _propertyLock, new ReaderWriterLockSlim(), null); using (_propertyLock.CreateUpgradeableReadLock()) { @@ -320,8 +310,7 @@ internal ReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) // create lock on demand if (_eventLock == null) - lock (this) - _eventLock ??= new ReaderWriterLockSlim(); + Interlocked.CompareExchange(ref _eventLock, new ReaderWriterLockSlim(), null); using (_eventLock.CreateUpgradeableReadLock()) { @@ -352,8 +341,7 @@ internal ReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo para // create lock on demand if (_parameterLock == null) - lock (this) - _parameterLock ??= new ReaderWriterLockSlim(); + Interlocked.CompareExchange(ref _parameterLock, new ReaderWriterLockSlim(), null); using (_parameterLock.CreateUpgradeableReadLock()) { @@ -370,6 +358,35 @@ internal ReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo para } } + /// + /// Gets or creates the cached for the module by type. + /// + /// + /// + /// + internal ReflectionTypeSymbol GetOrCreateGenericParameterSymbol(Type genericParameterType) + { + if (genericParameterType is null) + throw new ArgumentNullException(nameof(genericParameterType)); + + Debug.Assert(genericParameterType.Module == _module); + + // create lock on demand + if (_genericParameterLock == null) + Interlocked.CompareExchange(ref _genericParameterLock, new ReaderWriterLockSlim(), null); + + using (_genericParameterLock.CreateUpgradeableReadLock()) + { + var hnd = MetadataTokens.GenericParameterHandle(genericParameterType.GetMetadataTokenSafe()); + var row = MetadataTokens.GetRowNumber(hnd); + if (_genericParameterSymbols[row] == null) + using (_genericParameterLock.CreateWriteLock()) + return _genericParameterSymbols[row] ??= new ReflectionTypeSymbol(Context, this, genericParameterType); + else + return _genericParameterSymbols[row] ?? throw new InvalidOperationException(); + } + } + /// public IAssemblySymbol Assembly => Context.GetOrCreateAssemblySymbol(_module.Assembly); diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbol.cs index 8ee7be109..5ad5fe2ab 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbol.cs @@ -297,6 +297,20 @@ protected internal ReflectionParameterSymbol[] ResolveParameterSymbols(Parameter return a; } + /// + /// Resolves the symbols for the specified parameters. + /// + /// + /// + protected internal ReflectionParameterSymbol[] ResolveGenericParameterSymbols(ParameterInfo[] parameters) + { + var a = new ReflectionParameterSymbol[parameters.Length]; + for (int i = 0; i < parameters.Length; i++) + a[i] = ResolveParameterSymbol(parameters[i]); + + return a; + } + /// /// Transforms a custom set of custom attribute data records to a symbol record. /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbol.cs index 652a3c8fc..d59075d06 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbol.cs @@ -1,7 +1,6 @@ using System; -using System.Collections.Generic; +using System.Collections.Concurrent; using System.Diagnostics; -using System.Linq; using System.Reflection; using System.Threading; @@ -21,12 +20,7 @@ class ReflectionTypeSymbol : ReflectionMemberSymbol, ITypeSymbol ReflectionTypeSymbol? _asSZArray; ReflectionTypeSymbol? _asPointer; ReflectionTypeSymbol? _asByRef; - - Type[]? _genericParameterList; - ReflectionTypeSymbol?[]? _genericParameterSymbols; - - List<(Type[] Arguments, ReflectionTypeSymbol Symbol)>? _genericTypeSymbols; - ReaderWriterLockSlim? _genericTypeLock; + ConcurrentDictionary? _genericTypeSymbols; /// /// Initializes a new instance. @@ -41,51 +35,12 @@ public ReflectionTypeSymbol(ReflectionSymbolContext context, ReflectionModuleSym _type = type ?? throw new ArgumentNullException(nameof(type)); } - /// - /// Gets or creates the cached for the generic parameter type. - /// - /// - /// - /// - internal ReflectionTypeSymbol GetOrCreateGenericParameterSymbol(Type genericTypeParameterType) - { - if (genericTypeParameterType is null) - throw new ArgumentNullException(nameof(genericTypeParameterType)); - - Debug.Assert(genericTypeParameterType.DeclaringType == _type); - - // initialize tables - if (_genericParameterList == null) - Interlocked.CompareExchange(ref _genericParameterList, _type.GetGenericArguments(), null); - if (_genericParameterSymbols == null) - Interlocked.CompareExchange(ref _genericParameterSymbols, new ReflectionTypeSymbol?[_genericParameterList.Length], null); - - // position of the parameter in the list - var idx = genericTypeParameterType.GenericParameterPosition; - - // check that our list is long enough to contain the entire table - if (_genericParameterSymbols.Length < idx) - throw new IndexOutOfRangeException(); - - // if not yet created, create, allow multiple instances, but only one is eventually inserted - ref var rec = ref _genericParameterSymbols[idx]; - if (rec == null) - Interlocked.CompareExchange(ref rec, new ReflectionTypeSymbol(Context, ContainingModule, genericTypeParameterType), null); - - // this should never happen - if (rec is not ReflectionTypeSymbol sym) - throw new InvalidOperationException(); - - return sym; - } - /// /// Gets or creates the cached for the generic parameter type. /// /// /// - /// - internal ReflectionTypeSymbol GetOrCreateGenericTypeSymbol(Type[] genericTypeArguments) + internal ReflectionTypeSymbol GetOrCreateGenericTypeSymbol(ITypeSymbol[] genericTypeArguments) { if (genericTypeArguments is null) throw new ArgumentNullException(nameof(genericTypeArguments)); @@ -93,45 +48,12 @@ internal ReflectionTypeSymbol GetOrCreateGenericTypeSymbol(Type[] genericTypeArg if (_type.IsGenericTypeDefinition == false) throw new InvalidOperationException(); - // initialize the available parameters - if (_genericParameterList == null) - Interlocked.CompareExchange(ref _genericParameterList, _type.GetGenericArguments(), null); - if (_genericParameterList.Length != genericTypeArguments.Length) - throw new InvalidOperationException(); - - // initialize generic type map, and lock on it since we're potentially adding items if (_genericTypeSymbols == null) - Interlocked.CompareExchange(ref _genericTypeSymbols, [], null); - if (_genericTypeLock == null) - Interlocked.CompareExchange(ref _genericTypeLock, new(), null); - - try - { - _genericTypeLock.EnterUpgradeableReadLock(); - - // find existing entry - foreach (var i in _genericTypeSymbols) - if (i.Arguments.SequenceEqual(genericTypeArguments)) - return i.Symbol; - - try - { - _genericTypeLock.EnterWriteLock(); - - // generate new symbol - var sym = new ReflectionTypeSymbol(Context, ContainingModule, _type.MakeGenericType(genericTypeArguments)); - _genericTypeSymbols.Add((genericTypeArguments, sym)); - return sym; - } - finally - { - _genericTypeLock.ExitWriteLock(); - } - } - finally - { - _genericTypeLock.ExitUpgradeableReadLock(); - } + Interlocked.CompareExchange(ref _genericTypeSymbols, new ConcurrentDictionary(TypeSymbolListEqualityComparer.Instance), null); + + return _genericTypeSymbols.GetOrAdd( + genericTypeArguments, + _ => new ReflectionTypeSymbol(Context, ContainingModule, _type.MakeGenericType(genericTypeArguments.Unpack()))); } /// @@ -543,6 +465,48 @@ public IMemberSymbol[] GetMembers() return _type.GetMethod(name) is { } m ? ResolveMethodSymbol(m) : null; } + /// + public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers) + { + return _type.GetMethod(name, bindingAttr, null, callConvention, types.Unpack(), modifiers) is { } m ? ResolveMethodSymbol(m) : null; + } + + /// + public IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers) + { +#if NETFRAMEWORK + throw new NotImplementedException(); +#else + return _type.GetMethod(name, genericParameterCount, bindingAttr, null, callConvention, types.Unpack(), modifiers) is { } m ? ResolveMethodSymbol(m) : null; +#endif + } + + /// + public IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, ITypeSymbol[] types, ParameterModifier[]? modifiers) + { +#if NETFRAMEWORK + throw new NotImplementedException(); +#else + return _type.GetMethod(name, genericParameterCount, bindingAttr, null, types.Unpack(), modifiers) is { } m ? ResolveMethodSymbol(m) : null; +#endif + } + + /// + public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types, ParameterModifier[]? modifiers) + { + return _type.GetMethod(name, bindingAttr, null, types.Unpack(), modifiers) is { } m ? ResolveMethodSymbol(m) : null; + } + + /// + public IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, ParameterModifier[]? modifiers) + { +#if NETFRAMEWORK + throw new NotImplementedException(); +#else + return _type.GetMethod(name, genericParameterCount, types.Unpack(), modifiers) is { } m ? ResolveMethodSymbol(m) : null; +#endif + } + /// public IMethodSymbol[] GetMethods(BindingFlags bindingAttr) { @@ -676,7 +640,7 @@ public ITypeSymbol MakeByRefType() /// public ITypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments) { - throw new NotImplementedException(); + return GetOrCreateGenericTypeSymbol(typeArguments); } /// diff --git a/src/IKVM.CoreLib/Symbols/TypeSymbolListEqualityComparer.cs b/src/IKVM.CoreLib/Symbols/TypeSymbolListEqualityComparer.cs new file mode 100644 index 000000000..f4a39c701 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/TypeSymbolListEqualityComparer.cs @@ -0,0 +1,49 @@ +using System.Collections.Generic; + +namespace IKVM.CoreLib.Symbols +{ + + /// + /// Compares two ReflectionTypeSymbol array instances for equality. + /// + class TypeSymbolListEqualityComparer : IEqualityComparer + { + + public static readonly TypeSymbolListEqualityComparer Instance = new(); + + public bool Equals(ITypeSymbol[]? x, ITypeSymbol[]? y) + { + if (x == y) + return true; + + if (x == null || y == null) + return false; + + if (x.Length != y.Length) + return false; + + for (int i = 0; i < x.Length; i++) + if (x[i] != y[i]) + return false; + + return true; + } + + public int GetHashCode(ITypeSymbol[] obj) + { + int result = 17; + + for (int i = 0; i < obj.Length; i++) + { + unchecked + { + result = result * 23 + obj[i].GetHashCode(); + } + } + + return result; + } + + } + +} diff --git a/src/IKVM.Reflection/BuiltinArrayMethod.cs b/src/IKVM.Reflection/BuiltinArrayMethod.cs index 1785c0f20..b008e0520 100644 --- a/src/IKVM.Reflection/BuiltinArrayMethod.cs +++ b/src/IKVM.Reflection/BuiltinArrayMethod.cs @@ -94,7 +94,7 @@ public override int MetadataToken get { return 0x08000000; } } - internal override Module Module + public override Module Module { get { return method.Module; } } diff --git a/src/IKVM.Reflection/Emit/MethodBuilder.cs b/src/IKVM.Reflection/Emit/MethodBuilder.cs index a7271bffc..db75abaf6 100644 --- a/src/IKVM.Reflection/Emit/MethodBuilder.cs +++ b/src/IKVM.Reflection/Emit/MethodBuilder.cs @@ -510,7 +510,7 @@ public override int MetadataToken } } - internal override Module Module + public override Module Module { get { return method.Module; } } diff --git a/src/IKVM.Reflection/Emit/ParameterBuilder.cs b/src/IKVM.Reflection/Emit/ParameterBuilder.cs index dd9831b57..153c18cd5 100644 --- a/src/IKVM.Reflection/Emit/ParameterBuilder.cs +++ b/src/IKVM.Reflection/Emit/ParameterBuilder.cs @@ -22,7 +22,6 @@ Jeroen Frijters */ using System.Reflection.Metadata; -using System.Reflection.Metadata.Ecma335; namespace IKVM.Reflection.Emit { diff --git a/src/IKVM.Reflection/GenericParameterInfoImpl.cs b/src/IKVM.Reflection/GenericParameterInfoImpl.cs index 18b3c2857..45f48a7e0 100644 --- a/src/IKVM.Reflection/GenericParameterInfoImpl.cs +++ b/src/IKVM.Reflection/GenericParameterInfoImpl.cs @@ -86,7 +86,7 @@ public override int MetadataToken get { return parameterInfo.MetadataToken; } } - internal override Module Module + public override Module Module { get { return method.Module; } } diff --git a/src/IKVM.Reflection/MissingMethod.cs b/src/IKVM.Reflection/MissingMethod.cs index 67e9bd0c2..6f06daf4d 100644 --- a/src/IKVM.Reflection/MissingMethod.cs +++ b/src/IKVM.Reflection/MissingMethod.cs @@ -157,7 +157,7 @@ public override int MetadataToken get { return Forwarder.MetadataToken; } } - internal override Module Module + public override Module Module { get { return method.Module; } } diff --git a/src/IKVM.Reflection/ParameterInfo.cs b/src/IKVM.Reflection/ParameterInfo.cs index 655f54efc..2d2a8aa5f 100644 --- a/src/IKVM.Reflection/ParameterInfo.cs +++ b/src/IKVM.Reflection/ParameterInfo.cs @@ -32,7 +32,7 @@ public abstract class ParameterInfo : ICustomAttributeProvider /// /// Initializes a new instance. /// - internal ParameterInfo() + public ParameterInfo() { } @@ -76,7 +76,7 @@ public sealed override int GetHashCode() public abstract int MetadataToken { get; } - internal abstract Module Module { get; } + public abstract Module Module { get; } public Type[] GetOptionalCustomModifiers() { @@ -201,7 +201,7 @@ public override int MetadataToken get { return forward.MetadataToken; } } - internal override Module Module + public override Module Module { get { return member.Module; } } diff --git a/src/IKVM.Reflection/PropertyInfo.cs b/src/IKVM.Reflection/PropertyInfo.cs index 7ee8f8289..ab053a03f 100644 --- a/src/IKVM.Reflection/PropertyInfo.cs +++ b/src/IKVM.Reflection/PropertyInfo.cs @@ -125,7 +125,7 @@ public override int MetadataToken get { return 0x08000000; } } - internal override Module Module + public override Module Module { get { return property.Module; } } diff --git a/src/IKVM.Reflection/Reader/ParameterInfoImpl.cs b/src/IKVM.Reflection/Reader/ParameterInfoImpl.cs index e73bc63ea..451995e57 100644 --- a/src/IKVM.Reflection/Reader/ParameterInfoImpl.cs +++ b/src/IKVM.Reflection/Reader/ParameterInfoImpl.cs @@ -144,7 +144,7 @@ public override int MetadataToken } } - internal override Module Module + public override Module Module { get { return method.Module; } } diff --git a/src/IKVM.Reflection/Type.cs b/src/IKVM.Reflection/Type.cs index 4d90961cf..38bea7747 100644 --- a/src/IKVM.Reflection/Type.cs +++ b/src/IKVM.Reflection/Type.cs @@ -553,6 +553,21 @@ public bool IsEnumDefined(object value) return false; } + public Array GetEnumValues() + { + if (!IsEnum) + throw new ArgumentException(); + + var l = __GetDeclaredFields(); + var a = new object[l.Length]; + + for (int i = 0; i < l.Length; i++) + if (l[i].IsLiteral) + a[i] = l[i]; + + return a; + } + public override string ToString() { return FullName; From 5eeefa0517c279a0f9dfcc5d5dda5b4d4b48d875 Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Sun, 15 Sep 2024 23:28:14 -0500 Subject: [PATCH 05/51] ! --- .../Reflection/ReflectionSymbolTests.cs | 54 ------------------- .../IkvmReflectionAssemblySymbol.cs | 3 +- .../IkvmReflectionModuleSymbol.cs | 24 ++++----- .../Reflection/ReflectionModuleSymbol.cs | 41 +++----------- 4 files changed, 18 insertions(+), 104 deletions(-) diff --git a/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs b/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs index c27511937..93ce79548 100644 --- a/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs +++ b/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs @@ -420,60 +420,6 @@ public void CanCompleteTypeBuilder() moduleSymbol.GetType("DynamicType1").Should().BeSameAs(type1SymbolAgain); } - [TestMethod] - public void CanCreateAndResolveDynamicMethodOnModule() - { - var c = new ReflectionSymbolContext(); - - var method1 = new DynamicMethod("DynamicMethod1", null, null, typeof(ReflectionSymbolTests).Module); - var method1Symbol = c.GetOrCreateMethodSymbol(method1); - method1Symbol.Should().BeOfType(); - method1Symbol.Should().BeSameAs(c.GetOrCreateMethodSymbol(method1)); - } - - [TestMethod] - public void CanCreateAndResolveMultipleDynamicMethodsOnModule() - { - var c = new ReflectionSymbolContext(); - - var method1 = new DynamicMethod("DynamicMethod1", null, null, typeof(ReflectionSymbolTests).Module); - var method1Symbol = c.GetOrCreateMethodSymbol(method1); - method1Symbol.Should().BeOfType(); - method1Symbol.Should().BeSameAs(c.GetOrCreateMethodSymbol(method1)); - - var method2 = new DynamicMethod("DynamicMethod2", null, null, typeof(ReflectionSymbolTests).Module); - var method2Symbol = c.GetOrCreateMethodSymbol(method2); - method2Symbol.Should().BeOfType(); - method2Symbol.Should().BeSameAs(c.GetOrCreateMethodSymbol(method2)); - } - - [TestMethod] - public void CanCreateAndResolveDynamicMethodOnType() - { - var c = new ReflectionSymbolContext(); - - var method1 = new DynamicMethod("DynamicMethod", null, null, typeof(ReflectionSymbolTests)); - var method1Symbol = c.GetOrCreateMethodSymbol(method1); - method1Symbol.Should().BeOfType(); - method1Symbol.Should().BeSameAs(c.GetOrCreateMethodSymbol(method1)); - } - - [TestMethod] - public void CanCreateAndResolveMultipleDynamicMethodsOnType() - { - var c = new ReflectionSymbolContext(); - - var method1 = new DynamicMethod("DynamicMethod1", null, null, typeof(ReflectionSymbolTests)); - var method1Symbol = c.GetOrCreateMethodSymbol(method1); - method1Symbol.Should().BeOfType(); - method1Symbol.Should().BeSameAs(c.GetOrCreateMethodSymbol(method1)); - - var method2 = new DynamicMethod("DynamicMethod2", null, null, typeof(ReflectionSymbolTests)); - var method2Symbol = c.GetOrCreateMethodSymbol(method2); - method2Symbol.Should().BeOfType(); - method2Symbol.Should().BeSameAs(c.GetOrCreateMethodSymbol(method2)); - } - } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs index 50bb64af9..239580c9b 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs @@ -53,8 +53,7 @@ internal IkvmReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) // create lock on demand if (_moduleLock == null) - lock (this) - _moduleLock ??= new ReaderWriterLockSlim(); + Interlocked.CompareExchange(ref _moduleLock, new ReaderWriterLockSlim(), null); using (_moduleLock.CreateUpgradeableReadLock()) { diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs index daafbe9ac..e1ad04c5d 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs @@ -57,11 +57,11 @@ static bool IsTypeDefinition(Type type) IndexRangeDictionary _eventSymbols = new(maxCapacity: MAX_CAPACITY); ReaderWriterLockSlim? _eventLock; - IndexRangeDictionary _parameterTable = new(); - IndexRangeDictionary _parameterSymbols = new(); + IndexRangeDictionary _parameterTable = new(maxCapacity: MAX_CAPACITY); + IndexRangeDictionary _parameterSymbols = new(maxCapacity: MAX_CAPACITY); ReaderWriterLockSlim? _parameterLock; - IndexRangeDictionary _genericParameterSymbols = new(); + IndexRangeDictionary _genericParameterSymbols = new(maxCapacity: MAX_CAPACITY); ReaderWriterLockSlim? _genericParameterLock; /// @@ -111,8 +111,7 @@ internal IkvmReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) // create lock on demand if (_typeLock == null) - lock (this) - _typeLock ??= new ReaderWriterLockSlim(); + Interlocked.CompareExchange(ref _typeLock, new ReaderWriterLockSlim(), null); using (_typeLock.CreateUpgradeableReadLock()) { @@ -183,8 +182,7 @@ internal IkvmReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase m // create lock on demand if (_methodLock == null) - lock (this) - _methodLock ??= new ReaderWriterLockSlim(); + Interlocked.CompareExchange(ref _methodLock, new ReaderWriterLockSlim(), null); using (_methodLock.CreateUpgradeableReadLock()) { @@ -244,8 +242,7 @@ internal IkvmReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) // create lock on demand if (_fieldLock == null) - lock (this) - _fieldLock ??= new ReaderWriterLockSlim(); + Interlocked.CompareExchange(ref _fieldLock, new ReaderWriterLockSlim(), null); using (_fieldLock.CreateUpgradeableReadLock()) { @@ -280,8 +277,7 @@ internal IkvmReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo pro // create lock on demand if (_propertyLock == null) - lock (this) - _propertyLock ??= new ReaderWriterLockSlim(); + Interlocked.CompareExchange(ref _propertyLock, new ReaderWriterLockSlim(), null); using (_propertyLock.CreateUpgradeableReadLock()) { @@ -313,8 +309,7 @@ internal IkvmReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) // create lock on demand if (_eventLock == null) - lock (this) - _eventLock ??= new ReaderWriterLockSlim(); + Interlocked.CompareExchange(ref _eventLock, new ReaderWriterLockSlim(), null); using (_eventLock.CreateUpgradeableReadLock()) { @@ -345,8 +340,7 @@ internal IkvmReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo // create lock on demand if (_parameterLock == null) - lock (this) - _parameterLock ??= new ReaderWriterLockSlim(); + Interlocked.CompareExchange(ref _parameterLock, new ReaderWriterLockSlim(), null); using (_parameterLock.CreateUpgradeableReadLock()) { diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs index f09c9748c..57717f7bc 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs @@ -2,6 +2,7 @@ using System.Diagnostics; using System.Linq; using System.Reflection; +using System.Reflection.Emit; using System.Reflection.Metadata.Ecma335; using System.Threading; @@ -38,31 +39,25 @@ static bool IsTypeDefinition(Type type) readonly ReflectionAssemblySymbol _containingAssembly; Module _module; - IndexRangeDictionary _typeTable = new(maxCapacity: MAX_CAPACITY); IndexRangeDictionary _typeSymbols = new(maxCapacity: MAX_CAPACITY); ReaderWriterLockSlim? _typeLock; - IndexRangeDictionary _methodTable = new(maxCapacity: MAX_CAPACITY); IndexRangeDictionary _methodSymbols = new(maxCapacity: MAX_CAPACITY); ReaderWriterLockSlim? _methodLock; - IndexRangeDictionary _fieldTable = new(maxCapacity: MAX_CAPACITY); IndexRangeDictionary _fieldSymbols = new(maxCapacity: MAX_CAPACITY); ReaderWriterLockSlim? _fieldLock; - IndexRangeDictionary _propertyTable = new(maxCapacity: MAX_CAPACITY); IndexRangeDictionary _propertySymbols = new(maxCapacity: MAX_CAPACITY); ReaderWriterLockSlim? _propertyLock; - IndexRangeDictionary _eventTable = new(maxCapacity: MAX_CAPACITY); IndexRangeDictionary _eventSymbols = new(maxCapacity: MAX_CAPACITY); ReaderWriterLockSlim? _eventLock; - IndexRangeDictionary _parameterTable = new(); - IndexRangeDictionary _parameterSymbols = new(); + IndexRangeDictionary _parameterSymbols = new(maxCapacity: MAX_CAPACITY); ReaderWriterLockSlim? _parameterLock; - IndexRangeDictionary _genericParameterSymbols = new(); + IndexRangeDictionary _genericParameterSymbols = new(maxCapacity: MAX_CAPACITY); ReaderWriterLockSlim? _genericParameterLock; /// @@ -117,10 +112,6 @@ internal ReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) using (_typeLock.CreateUpgradeableReadLock()) { var row = type.GetMetadataTokenRowNumberSafe(); - if (_typeTable[row] != type) - using (_typeLock.CreateWriteLock()) - _typeTable[row] = type; - if (_typeSymbols[row] == null) using (_typeLock.CreateWriteLock()) return _typeSymbols[row] ??= new ReflectionTypeSymbol(Context, this, type); @@ -170,7 +161,7 @@ ReflectionTypeSymbol GetOrCreateTypeSymbolForSpecification(Type type) } /// - /// Gets or creates the cached fqor the type by method. + /// Gets or creates the cached for the type by method. /// /// /// @@ -181,6 +172,10 @@ internal ReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase metho Debug.Assert(method.Module.GetMetadataTokenSafe() == _module.GetMetadataTokenSafe()); + // they are methods, but they are associated differently + if (method is DynamicMethod) + throw new ArgumentException("Dynamic methods cannot be attached to context."); + // create lock on demand if (_methodLock == null) Interlocked.CompareExchange(ref _methodLock, new ReaderWriterLockSlim(), null); @@ -188,10 +183,6 @@ internal ReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase metho using (_methodLock.CreateUpgradeableReadLock()) { var row = method.GetMetadataTokenRowNumberSafe(); - if (_methodTable[row] != method) - using (_methodLock.CreateWriteLock()) - _methodTable[row] = method; - if (_methodSymbols[row] == null) using (_methodLock.CreateWriteLock()) if (method is ConstructorInfo c) @@ -248,10 +239,6 @@ internal ReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) using (_fieldLock.CreateUpgradeableReadLock()) { var row = field.GetMetadataTokenRowNumberSafe(); - if (_fieldTable[row] != field) - using (_fieldLock.CreateWriteLock()) - _fieldTable[row] = field; - if (_fieldSymbols[row] == null) using (_fieldLock.CreateWriteLock()) if (field.DeclaringType is { } dt) @@ -283,10 +270,6 @@ internal ReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo propert using (_propertyLock.CreateUpgradeableReadLock()) { var row = property.GetMetadataTokenRowNumberSafe(); - if (_propertyTable[row] != property) - using (_propertyLock.CreateWriteLock()) - _propertyTable[row] = property; - if (_propertySymbols[row] == null) using (_propertyLock.CreateWriteLock()) return _propertySymbols[row] ??= new ReflectionPropertySymbol(Context, ResolveTypeSymbol(property.DeclaringType!), property); @@ -315,10 +298,6 @@ internal ReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) using (_eventLock.CreateUpgradeableReadLock()) { var row = @event.GetMetadataTokenRowNumberSafe(); - if (_eventTable[row] is not EventInfo i || i != @event) - using (_eventLock.CreateWriteLock()) - _eventTable[row] = @event; - if (_eventSymbols[row] == null) using (_eventLock.CreateWriteLock()) return _eventSymbols[row] ??= new ReflectionEventSymbol(Context, ResolveTypeSymbol(@event.DeclaringType!), @event); @@ -346,10 +325,6 @@ internal ReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo para using (_parameterLock.CreateUpgradeableReadLock()) { var position = parameter.Position; - if (_parameterTable[position] != parameter) - using (_parameterLock.CreateWriteLock()) - _parameterTable[position] = parameter; - if (_parameterSymbols[position] == null) using (_parameterLock.CreateWriteLock()) return _parameterSymbols[position] ??= new ReflectionParameterSymbol(Context, ResolveMethodBaseSymbol((MethodBase)parameter.Member), parameter); From cc527085c5ce81c85f53d36f1d41caa7d0abaa07 Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Wed, 18 Sep 2024 10:51:40 -0500 Subject: [PATCH 06/51] Rebuild. --- .../IkvmReflectionSymbolTests.cs | 451 ++++++------ .../Reflection/ReflectionSymbolTests.cs | 51 +- src/IKVM.CoreLib/IKVM.CoreLib.csproj | 12 + .../ReflectionExtensions.cs} | 128 +++- .../Symbols/Emit/IAssemblySymbolBuilder.cs | 11 +- .../Symbols/Emit/IConstructorSymbolBuilder.cs | 2 +- .../Symbols/Emit/IEventSymbolBuilder.cs | 2 +- .../Symbols/Emit/IFieldSymbolBuilder.cs | 2 +- .../IGenericTypeParameterSymbolBuilder.cs | 21 +- src/IKVM.CoreLib/Symbols/Emit/IILGenerator.cs | 257 +++++++ src/IKVM.CoreLib/Symbols/Emit/ILabel.cs | 6 + .../Symbols/Emit/ILocalBuilder.cs | 42 ++ .../Symbols/Emit/IMemberSymbolBuilder.cs | 11 + .../Symbols/Emit/IMethodBaseSymbolBuilder.cs | 11 + .../Symbols/Emit/IMethodSymbolBuilder.cs | 2 +- .../Symbols/Emit/IModuleSymbolBuilder.cs | 7 +- .../Symbols/Emit/IParameterSymbolBuilder.cs | 2 +- .../Symbols/Emit/IPropertySymbolBuilder.cs | 26 +- .../Symbols/Emit/ISignatureHelper.cs | 6 + .../Symbols/Emit/ISymbolBuilder.cs | 10 +- .../Symbols/Emit/ITypeSymbolBuilder.cs | 9 +- src/IKVM.CoreLib/Symbols/IAssemblySymbol.cs | 2 + src/IKVM.CoreLib/Symbols/IEventSymbol.cs | 2 + src/IKVM.CoreLib/Symbols/IFieldSymbol.cs | 2 + src/IKVM.CoreLib/Symbols/IMethodSymbol.cs | 4 +- src/IKVM.CoreLib/Symbols/IParameterSymbol.cs | 2 + src/IKVM.CoreLib/Symbols/IPropertySymbol.cs | 2 + src/IKVM.CoreLib/Symbols/ISymbol.cs | 5 + src/IKVM.CoreLib/Symbols/ISymbolContext.cs | 48 ++ .../IkvmReflectionAssemblySymbolBuilder.cs | 79 --- .../IkvmReflectionConstructorSymbolBuilder.cs | 74 -- .../IkvmReflectionCustomAttributeBuilder.cs | 29 - .../Emit/IkvmReflectionEventSymbolBuilder.cs | 70 -- .../Emit/IkvmReflectionFieldSymbolBuilder.cs | 88 --- .../IkvmReflectionMethodBaseSymbolBuilder.cs | 49 -- .../Emit/IkvmReflectionMethodSymbolBuilder.cs | 107 --- .../Emit/IkvmReflectionModuleSymbolBuilder.cs | 98 --- .../IkvmReflectionParameterBuilderInfo.cs | 68 -- .../IkvmReflectionParameterSymbolBuilder.cs | 106 --- .../IkvmReflectionAssemblySymbol.cs | 196 ----- .../IkvmReflectionConstructorSymbol.cs | 37 - .../IkvmReflectionEventSymbol.cs | 108 --- .../IkvmReflectionFieldSymbol.cs | 116 --- .../IkvmReflectionMemberSymbol.cs | 275 ------- .../IkvmReflectionMethodBaseSymbol.cs | 133 ---- .../IkvmReflectionMethodSymbol.cs | 71 -- .../IkvmReflectionModuleSymbol.cs | 587 --------------- .../IkvmReflectionParameterSymbol.cs | 119 ---- .../IkvmReflectionPropertySymbol.cs | 131 ---- .../IkvmReflection/IkvmReflectionSymbol.cs | 417 ----------- .../IkvmReflectionSymbolContext.cs | 180 ----- .../IkvmReflectionTypeSymbol.cs | 669 ------------------ .../IkvmReflection/IkvmReflectionUtil.cs | 195 ----- .../Emit/IReflectionAssemblySymbolBuilder.cs | 18 + .../IReflectionConstructorSymbolBuilder.cs | 15 + .../Emit/IReflectionEventSymbolBuilder.cs | 15 + .../Emit/IReflectionFieldSymbolBuilder.cs | 15 + ...ectionGenericTypeParameterSymbolBuilder.cs | 24 + .../Emit/IReflectionMemberSymbolBuilder.cs | 17 + .../IReflectionMethodBaseSymbolBuilder.cs | 13 + .../Emit/IReflectionMethodSymbolBuilder.cs | 18 + .../Emit/IReflectionModuleSymbolBuilder.cs | 18 + .../Emit/IReflectionParameterSymbolBuilder.cs | 23 + .../Emit/IReflectionPropertySymbolBuilder.cs | 15 + .../Emit/IReflectionSymbolBuilder.cs | 19 + .../Emit/IReflectionTypeSymbolBuilder.cs | 18 + .../Emit/ReflectionAssemblySymbolBuilder.cs | 168 ++++- .../ReflectionConstructorSymbolBuilder.cs | 53 +- .../Emit/ReflectionCustomAttributeBuilder.cs | 2 +- .../Emit/ReflectionEventBuilderInfo.cs | 1 + .../Emit/ReflectionEventSymbolBuilder.cs | 125 +++- .../Emit/ReflectionFieldSymbolBuilder.cs | 141 ++-- ...ectionGenericTypeParameterSymbolBuilder.cs | 583 +++++++++++++++ .../Emit/ReflectionMemberSymbolBuilder.cs | 392 ++++++++++ .../Emit/ReflectionMethodBaseSymbolBuilder.cs | 131 +++- .../Emit/ReflectionMethodSymbolBuilder.cs | 103 ++- .../Emit/ReflectionModuleSymbolBuilder.cs | 323 ++++++++- .../Emit/ReflectionParameterBuilderInfo.cs | 9 +- .../Emit/ReflectionParameterSymbolBuilder.cs | 160 +++-- .../Emit/ReflectionPropertySymbolBuilder.cs | 161 ++++- .../Emit/ReflectionSymbolBuilder.cs | 74 +- .../Emit/ReflectionTypeSymbolBuilder.cs | 660 +++++++++++++++-- .../Reflection/IReflectionAssemblySymbol.cs | 33 + .../IReflectionConstructorSymbol.cs | 16 + .../Reflection/IReflectionEventSymbol.cs | 11 + .../Reflection/IReflectionFieldSymbol.cs | 16 + .../Reflection/IReflectionMemberSymbol.cs | 26 + .../Reflection/IReflectionMethodBaseSymbol.cs | 16 + .../Reflection/IReflectionMethodSymbol.cs | 16 + .../Reflection/IReflectionModuleSymbol.cs | 123 ++++ .../Reflection/IReflectionParameterSymbol.cs | 26 + .../Reflection/IReflectionPropertySymbol.cs | 16 + .../Symbols/Reflection/IReflectionSymbol.cs | 335 +++++++++ .../Reflection/IReflectionTypeSymbol.cs | 16 + .../Reflection/ReflectionAssemblyMetadata.cs | 66 ++ .../Reflection/ReflectionAssemblySymbol.cs | 76 +- .../Reflection/ReflectionConstructorSymbol.cs | 29 +- .../Reflection/ReflectionEventSymbol.cs | 53 +- .../Reflection/ReflectionFieldSymbol.cs | 73 +- .../ReflectionGenericTypeParameterSymbol.cs | 562 +++++++++++++++ .../Reflection/ReflectionMemberSymbol.cs | 346 +++++---- .../Reflection/ReflectionMethodBaseSymbol.cs | 85 +-- .../Reflection/ReflectionMethodSymbol.cs | 34 +- .../Reflection/ReflectionModuleMetadata.cs | 488 +++++++++++++ .../Reflection/ReflectionModuleSymbol.cs | 504 ++++--------- .../Reflection/ReflectionParameterSymbol.cs | 72 +- .../Reflection/ReflectionPropertySymbol.cs | 59 +- .../Symbols/Reflection/ReflectionSymbol.cs | 527 ++++++++------ .../Reflection/ReflectionSymbolContext.cs | 214 ++++-- .../Reflection/ReflectionSymbolExtensions.cs | 11 + .../Symbols/Reflection/ReflectionTypeImpl.cs | 633 +++++++++++++++++ .../Reflection/ReflectionTypeSymbol.cs | 486 +++++-------- .../Symbols/Reflection/ReflectionUtil.cs | 79 ++- src/IKVM.Runtime/Annotation.cs | 15 +- src/IKVM.Runtime/AttributeHelper.cs | 289 ++++---- .../Attributes/EnclosingMethodAttribute.cs | 3 +- src/IKVM.Runtime/BootstrapClassLoader.cs | 6 +- src/IKVM.Runtime/CodeEmitter.cs | 659 ++++++++--------- src/IKVM.Runtime/CodeEmitterLabel.cs | 11 +- src/IKVM.Runtime/DefineMethodHelper.cs | 30 +- src/IKVM.Runtime/DynamicClassLoader.cs | 94 +-- src/IKVM.Runtime/IRuntimeSymbolResolver.cs | 23 + src/IKVM.Runtime/ReflectUtil.cs | 10 +- src/IKVM.Runtime/RuntimeArrayJavaType.cs | 11 +- .../RuntimeByteCodeJavaType.DynamicImpl.cs | 11 +- ...untimeByteCodeJavaType.FinishedTypeImpl.cs | 19 +- .../RuntimeByteCodeJavaType.JavaTypeImpl.cs | 106 ++- src/IKVM.Runtime/RuntimeByteCodeJavaType.cs | 172 ++--- .../RuntimeByteCodePropertyJavaField.cs | 39 +- src/IKVM.Runtime/RuntimeClassLoader.cs | 9 +- src/IKVM.Runtime/RuntimeClassLoaderFactory.cs | 21 +- src/IKVM.Runtime/RuntimeGhostJavaMethod.cs | 13 +- src/IKVM.Runtime/RuntimeJavaTypeFactory.cs | 3 +- ...anagedByteCodeJavaType.RemappedJavaType.cs | 5 +- .../RuntimeManagedByteCodeJavaType.cs | 29 +- ...tionJavaType.MultipleAnnotationJavaType.cs | 25 +- ...nJavaType.ReturnValueAnnotationJavaType.cs | 22 +- ...gedJavaType.AttributeAnnotationJavaType.cs | 36 +- ...ntimeManagedJavaType.DelegateJavaMethod.cs | 7 +- ...ntimeManagedJavaType.EnumValueJavaField.cs | 6 +- src/IKVM.Runtime/RuntimeManagedJavaType.cs | 2 +- .../RuntimeManagedJavaTypeFactory.cs | 2 +- .../RuntimeSimpleCallJavaMethod.cs | 3 +- src/IKVM.Runtime/RuntimeUnloadableJavaType.cs | 2 +- src/IKVM.Runtime/RuntimeVerifierJavaType.cs | 4 +- src/IKVM.Runtime/StubGen/StubGenerator.cs | 65 +- src/IKVM.Runtime/SymbolExtensions.cs | 77 ++ src/IKVM.Tools.Exporter/ExportImpl.cs | 7 +- src/IKVM.Tools.Exporter/FakeTypes.cs | 15 +- .../ManagedTypeResolver.cs | 62 +- .../RuntimeBootstrapClassLoader.cs | 12 +- .../RuntimeStubJavaType.cs | 5 +- src/IKVM.Tools.Importer/ImportClassLoader.cs | 8 +- .../RuntimeImportByteCodeJavaType.cs | 160 +++-- 154 files changed, 8562 insertions(+), 7035 deletions(-) rename src/IKVM.CoreLib/{System/TypeExtensions.cs => Reflection/ReflectionExtensions.cs} (76%) create mode 100644 src/IKVM.CoreLib/Symbols/Emit/ILabel.cs create mode 100644 src/IKVM.CoreLib/Symbols/Emit/ILocalBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Emit/IMemberSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Emit/IMethodBaseSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Emit/ISignatureHelper.cs create mode 100644 src/IKVM.CoreLib/Symbols/ISymbolContext.cs delete mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionAssemblySymbolBuilder.cs delete mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionConstructorSymbolBuilder.cs delete mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionCustomAttributeBuilder.cs delete mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionEventSymbolBuilder.cs delete mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionFieldSymbolBuilder.cs delete mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodBaseSymbolBuilder.cs delete mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodSymbolBuilder.cs delete mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionModuleSymbolBuilder.cs delete mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterBuilderInfo.cs delete mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterSymbolBuilder.cs delete mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs delete mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionConstructorSymbol.cs delete mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionEventSymbol.cs delete mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionFieldSymbol.cs delete mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs delete mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodBaseSymbol.cs delete mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodSymbol.cs delete mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs delete mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterSymbol.cs delete mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionPropertySymbol.cs delete mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs delete mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolContext.cs delete mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs delete mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionUtil.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionAssemblySymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionConstructorSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionEventSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionFieldSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionGenericTypeParameterSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionMemberSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionMethodBaseSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionMethodSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionModuleSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionParameterSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionPropertySymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionTypeSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionGenericTypeParameterSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMemberSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/IReflectionAssemblySymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/IReflectionConstructorSymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/IReflectionEventSymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/IReflectionFieldSymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/IReflectionMemberSymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/IReflectionMethodBaseSymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/IReflectionMethodSymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/IReflectionModuleSymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/IReflectionParameterSymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/IReflectionPropertySymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/IReflectionSymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/IReflectionTypeSymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblyMetadata.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericTypeParameterSymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleMetadata.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolExtensions.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeImpl.cs diff --git a/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs b/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs index 22936c64d..47eb9aed4 100644 --- a/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs +++ b/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs @@ -1,230 +1,221 @@ -using System.IO; - -using FluentAssertions; - -using IKVM.CoreLib.Symbols.IkvmReflection; -using IKVM.Reflection; - -using Microsoft.VisualStudio.TestPlatform.PlatformAbstractions; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace IKVM.CoreLib.Tests.Symbols.IkvmReflection -{ - - [TestClass] - public class IkvmReflectionSymbolTests - { - - class Foo - { - - T? field; - - bool Method(int p1) => true; - - } - - Universe? universe; - Assembly? coreAssembly; - Assembly? thisAssembly; - - [TestInitialize] - public void Setup() - { - universe = new Universe(typeof(object).Assembly.GetName().Name); - universe.AssemblyResolve += Universe_AssemblyResolve; - coreAssembly = universe.LoadFile(typeof(object).Assembly.GetAssemblyLocation()); - thisAssembly = universe.LoadFile(typeof(IkvmReflectionSymbolTests).Assembly.GetAssemblyLocation()); - } - - /// - /// Attempt to load assembly from system. - /// - /// - /// - /// - Assembly? Universe_AssemblyResolve(object sender, ResolveEventArgs args) - { - try - { - var asm = System.Reflection.Assembly.Load(args.Name); - if (asm != null && File.Exists(asm.Location)) - return universe!.LoadFile(asm.Location); - } - catch - { - - } - - return null; - } - - [TestMethod] - public void SameTypeShouldBeSame() - { - var c = new IkvmReflectionSymbolContext(); - var s1 = c.GetOrCreateTypeSymbol(universe!.GetBuiltInType("System", "Object")); - var s2 = c.GetOrCreateTypeSymbol(universe!.GetBuiltInType("System", "Object")); - s1.Should().BeSameAs(s2); - } - - [TestMethod] - public void GenericTypeDefinitionShouldBeSame() - { - var t = thisAssembly!.GetType("IKVM.CoreLib.Tests.Symbols.IkvmReflection.IkvmReflectionSymbolTests+Foo`1"); - var c = new IkvmReflectionSymbolContext(); - var s1 = c.GetOrCreateTypeSymbol(t); - var s2 = c.GetOrCreateTypeSymbol(t); - s1.Should().BeSameAs(s2); - } - - [TestMethod] - public void GenericTypeShouldBeSame() - { - var t = thisAssembly!.GetType("IKVM.CoreLib.Tests.Symbols.IkvmReflection.IkvmReflectionSymbolTests+Foo`1").MakeGenericType(universe!.GetBuiltInType("System", "Int32")); - var c = new IkvmReflectionSymbolContext(); - var s1 = c.GetOrCreateTypeSymbol(t); - var s2 = c.GetOrCreateTypeSymbol(t); - s1.Should().BeSameAs(s2); - } - - [TestMethod] - public void ArrayTypeShouldBeSame() - { - var t = universe!.GetBuiltInType("System", "Object").MakeArrayType(2); - var c = new IkvmReflectionSymbolContext(); - var s1 = c.GetOrCreateTypeSymbol(t); - var s2 = c.GetOrCreateTypeSymbol(t); - s1.Should().BeSameAs(s2); - } - - [TestMethod] - public void SZArrayTypeShouldBeSame() - { - var t = universe!.GetBuiltInType("System", "Object").MakeArrayType(); - var c = new IkvmReflectionSymbolContext(); - var s1 = c.GetOrCreateTypeSymbol(t); - var s2 = c.GetOrCreateTypeSymbol(t); - s1.Should().BeSameAs(s2); - } - - [TestMethod] - public unsafe void PointerTypeShouldBeSame() - { - var t = universe!.GetBuiltInType("System", "Int32").MakePointerType(); - var c = new IkvmReflectionSymbolContext(); - var s1 = c.GetOrCreateTypeSymbol(t); - var s2 = c.GetOrCreateTypeSymbol(t); - s1.Should().BeSameAs(s2); - } - - [TestMethod] - public unsafe void ByRefTypeShouldBeSame() - { - var t = universe!.GetBuiltInType("System", "Int32").MakeByRefType(); - var c = new IkvmReflectionSymbolContext(); - var s1 = c.GetOrCreateTypeSymbol(t); - var s2 = c.GetOrCreateTypeSymbol(t); - s1.Should().BeSameAs(s2); - } - - [TestMethod] - public void EnumTypeShouldBeSame() - { - var a = universe!.Load(typeof(System.AttributeTargets).Assembly.FullName); - var t = a.GetType("System.AttributeTargets"); - var c = new IkvmReflectionSymbolContext(); - var s1 = c.GetOrCreateTypeSymbol(t); - var s2 = c.GetOrCreateTypeSymbol(t); - s1.Should().BeSameAs(s2); - } - - [TestMethod] - public void CanGetType() - { - var t = universe!.GetBuiltInType("System", "Object"); - var c = new IkvmReflectionSymbolContext(); - var s = c.GetOrCreateTypeSymbol(t); - s.Name.Should().Be("Object"); - s.FullName.Should().Be("System.Object"); - } - - [TestMethod] - public void CanGetFieldOfGenericTypeDefinition() - { - var t = thisAssembly!.GetType("IKVM.CoreLib.Tests.Symbols.IkvmReflection.IkvmReflectionSymbolTests+Foo`1"); - var c = new IkvmReflectionSymbolContext(); - var s = c.GetOrCreateTypeSymbol(t); - s.IsGenericType.Should().BeTrue(); - s.IsGenericTypeDefinition.Should().BeTrue(); - var f = s.GetField("field", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); - f.Name.Should().Be("field"); - f.FieldType.IsGenericType.Should().BeFalse(); - f.FieldType.IsGenericParameter.Should().BeTrue(); - } - - [TestMethod] - public void CanGetFieldOfGenericType() - { - var t = thisAssembly!.GetType("IKVM.CoreLib.Tests.Symbols.IkvmReflection.IkvmReflectionSymbolTests+Foo`1").MakeGenericType(universe!.GetBuiltInType("System", "Int32")); - var c = new IkvmReflectionSymbolContext(); - var s = c.GetOrCreateTypeSymbol(t); - s.IsGenericType.Should().BeTrue(); - s.IsGenericTypeDefinition.Should().BeFalse(); - var f = s.GetField("field", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); - f.Name.Should().Be("field"); - f.FieldType.IsGenericType.Should().BeFalse(); - f.FieldType.IsGenericParameter.Should().BeFalse(); - f.FieldType.Should().BeSameAs(c.GetOrCreateTypeSymbol(universe!.GetBuiltInType("System", "Int32"))); - } - - [TestMethod] - public void CanGetMethod() - { - var t = universe!.GetBuiltInType("System", "Object"); - var c = new IkvmReflectionSymbolContext(); - var s = c.GetOrCreateTypeSymbol(t); - var m = s.GetMethod("ToString"); - m.Name.Should().Be("ToString"); - m.ReturnType.Should().BeSameAs(c.GetOrCreateTypeSymbol(universe!.GetBuiltInType("System", "String"))); - m.ReturnParameter.ParameterType.Should().BeSameAs(c.GetOrCreateTypeSymbol(universe!.GetBuiltInType("System", "String"))); - m.IsGenericMethod.Should().BeFalse(); - m.IsGenericMethodDefinition.Should().BeFalse(); - m.IsPublic.Should().BeTrue(); - m.IsPrivate.Should().BeFalse(); - } - - [System.AttributeUsage(System.AttributeTargets.Class)] - class AttributeWithType : System.Attribute - { - - public AttributeWithType(System.Type type) - { - Type = type; - } - - public System.Type Type { get; } - - } - - [AttributeWithType(typeof(object))] - class ClassWithAttributeWithType - { - - - - } - - [TestMethod] - public void CanReadCustomAttributes() - { - var c = new IkvmReflectionSymbolContext(); - var s = c.GetOrCreateTypeSymbol(thisAssembly!.GetType("IKVM.CoreLib.Tests.Symbols.IkvmReflection.IkvmReflectionSymbolTests+ClassWithAttributeWithType")); - var a = s.GetCustomAttribute(c.GetOrCreateTypeSymbol(thisAssembly!.GetType("IKVM.CoreLib.Tests.Symbols.IkvmReflection.IkvmReflectionSymbolTests+AttributeWithType"))); - var v = a.Value.ConstructorArguments[0].Value; - v.Should().BeOfType(); - } - - } - -} +//using System.IO; + +//using FluentAssertions; + +//using IKVM.CoreLib.Symbols.IkvmReflection; +//using IKVM.Reflection; + +//using Microsoft.VisualStudio.TestPlatform.PlatformAbstractions; +//using Microsoft.VisualStudio.TestTools.UnitTesting; + +//namespace IKVM.CoreLib.Tests.Symbols.IkvmReflection +//{ + +// [TestClass] +// public class IkvmReflectionSymbolTests +// { + +// class Foo +// { + +// T? field; + +// bool Method(int p1) => true; + +// } + +// Universe? universe; +// Assembly? coreAssembly; +// Assembly? thisAssembly; + +// [TestInitialize] +// public void Setup() +// { +// universe = new Universe(typeof(object).Assembly.GetName().Name); +// universe.AssemblyResolve += Universe_AssemblyResolve; +// coreAssembly = universe.LoadFile(typeof(object).Assembly.GetAssemblyLocation()); +// thisAssembly = universe.LoadFile(typeof(IkvmReflectionSymbolTests).Assembly.GetAssemblyLocation()); +// } + +// /// +// /// Attempt to load assembly from system. +// /// +// /// +// /// +// /// +// Assembly? Universe_AssemblyResolve(object sender, ResolveEventArgs args) +// { +// try +// { +// var asm = System.Reflection.Assembly.Load(args.Name); +// if (asm != null && File.Exists(asm.Location)) +// return universe!.LoadFile(asm.Location); +// } +// catch +// { + +// } + +// return null; +// } + +// [TestMethod] +// public void SameTypeShouldBeSame() +// { +// var c = new IkvmReflectionSymbolContext(); +// var s1 = c.GetOrCreateTypeSymbol(universe!.GetBuiltInType("System", "Object")); +// var s2 = c.GetOrCreateTypeSymbol(universe!.GetBuiltInType("System", "Object")); +// s1.Should().BeSameAs(s2); +// } + +// [TestMethod] +// public void GenericTypeDefinitionShouldBeSame() +// { +// var t = thisAssembly!.GetType("IKVM.CoreLib.Tests.Symbols.IkvmReflection.IkvmReflectionSymbolTests+Foo`1"); +// var c = new IkvmReflectionSymbolContext(); +// var s1 = c.GetOrCreateTypeSymbol(t); +// var s2 = c.GetOrCreateTypeSymbol(t); +// s1.Should().BeSameAs(s2); +// } + +// [TestMethod] +// public void GenericTypeShouldBeSame() +// { +// var t = thisAssembly!.GetType("IKVM.CoreLib.Tests.Symbols.IkvmReflection.IkvmReflectionSymbolTests+Foo`1").MakeGenericType(universe!.GetBuiltInType("System", "Int32")); +// var c = new IkvmReflectionSymbolContext(); +// var s1 = c.GetOrCreateTypeSymbol(t); +// var s2 = c.GetOrCreateTypeSymbol(t); +// s1.Should().BeSameAs(s2); +// } + +// [TestMethod] +// public void ArrayTypeShouldBeSame() +// { +// var t = universe!.GetBuiltInType("System", "Object").MakeArrayType(2); +// var c = new IkvmReflectionSymbolContext(); +// var s1 = c.GetOrCreateTypeSymbol(t); +// var s2 = c.GetOrCreateTypeSymbol(t); +// s1.Should().BeSameAs(s2); +// } + +// [TestMethod] +// public void SZArrayTypeShouldBeSame() +// { +// var t = universe!.GetBuiltInType("System", "Object").MakeArrayType(); +// var c = new IkvmReflectionSymbolContext(); +// var s1 = c.GetOrCreateTypeSymbol(t); +// var s2 = c.GetOrCreateTypeSymbol(t); +// s1.Should().BeSameAs(s2); +// } + +// [TestMethod] +// public unsafe void PointerTypeShouldBeSame() +// { +// var t = universe!.GetBuiltInType("System", "Int32").MakePointerType(); +// var c = new IkvmReflectionSymbolContext(); +// var s1 = c.GetOrCreateTypeSymbol(t); +// var s2 = c.GetOrCreateTypeSymbol(t); +// s1.Should().BeSameAs(s2); +// } + +// [TestMethod] +// public unsafe void ByRefTypeShouldBeSame() +// { +// var t = universe!.GetBuiltInType("System", "Int32").MakeByRefType(); +// var c = new IkvmReflectionSymbolContext(); +// var s1 = c.GetOrCreateTypeSymbol(t); +// var s2 = c.GetOrCreateTypeSymbol(t); +// s1.Should().BeSameAs(s2); +// } + +// [TestMethod] +// public void EnumTypeShouldBeSame() +// { +// var a = universe!.Load(typeof(System.AttributeTargets).Assembly.FullName); +// var t = a.GetType("System.AttributeTargets"); +// var c = new IkvmReflectionSymbolContext(); +// var s1 = c.GetOrCreateTypeSymbol(t); +// var s2 = c.GetOrCreateTypeSymbol(t); +// s1.Should().BeSameAs(s2); +// } + +// [TestMethod] +// public void CanGetType() +// { +// var t = universe!.GetBuiltInType("System", "Object"); +// var c = new IkvmReflectionSymbolContext(); +// var s = c.GetOrCreateTypeSymbol(t); +// s.Name.Should().Be("Object"); +// s.FullName.Should().Be("System.Object"); +// } + +// [TestMethod] +// public void CanGetFieldOfGenericTypeDefinition() +// { +// var t = thisAssembly!.GetType("IKVM.CoreLib.Tests.Symbols.IkvmReflection.IkvmReflectionSymbolTests+Foo`1"); +// var c = new IkvmReflectionSymbolContext(); +// var s = c.GetOrCreateTypeSymbol(t); +// s.IsGenericType.Should().BeTrue(); +// s.IsGenericTypeDefinition.Should().BeTrue(); +// var f = s.GetField("field", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); +// f.Name.Should().Be("field"); +// f.FieldType.IsGenericType.Should().BeFalse(); +// f.FieldType.IsGenericParameter.Should().BeTrue(); +// } + +// [TestMethod] +// public void CanGetFieldOfGenericType() +// { +// var t = thisAssembly!.GetType("IKVM.CoreLib.Tests.Symbols.IkvmReflection.IkvmReflectionSymbolTests+Foo`1").MakeGenericType(universe!.GetBuiltInType("System", "Int32")); +// var c = new IkvmReflectionSymbolContext(); +// var s = c.GetOrCreateTypeSymbol(t); +// s.IsGenericType.Should().BeTrue(); +// s.IsGenericTypeDefinition.Should().BeFalse(); +// var f = s.GetField("field", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); +// f.Name.Should().Be("field"); +// f.FieldType.IsGenericType.Should().BeFalse(); +// f.FieldType.IsGenericParameter.Should().BeFalse(); +// f.FieldType.Should().BeSameAs(c.GetOrCreateTypeSymbol(universe!.GetBuiltInType("System", "Int32"))); +// } + +// [TestMethod] +// public void CanGetMethod() +// { +// var t = universe!.GetBuiltInType("System", "Object"); +// var c = new IkvmReflectionSymbolContext(); +// var s = c.GetOrCreateTypeSymbol(t); +// var m = s.GetMethod("ToString"); +// m.Name.Should().Be("ToString"); +// m.ReturnType.Should().BeSameAs(c.GetOrCreateTypeSymbol(universe!.GetBuiltInType("System", "String"))); +// m.ReturnParameter.ParameterType.Should().BeSameAs(c.GetOrCreateTypeSymbol(universe!.GetBuiltInType("System", "String"))); +// m.IsGenericMethod.Should().BeFalse(); +// m.IsGenericMethodDefinition.Should().BeFalse(); +// m.IsPublic.Should().BeTrue(); +// m.IsPrivate.Should().BeFalse(); +// } + +// [System.AttributeUsage(System.AttributeTargets.Class)] +// class AttributeWithType : System.Attribute +// { + +// public AttributeWithType(System.Type type) +// { +// Type = type; +// } + +// public System.Type Type { get; } + +// } +// [TestMethod] +// public void CanReadCustomAttributes() +// { +// var c = new IkvmReflectionSymbolContext(); +// var s = c.GetOrCreateTypeSymbol(thisAssembly!.GetType("IKVM.CoreLib.Tests.Symbols.IkvmReflection.IkvmReflectionSymbolTests+ClassWithAttributeWithType")); +// var a = s.GetCustomAttribute(c.GetOrCreateTypeSymbol(thisAssembly!.GetType("IKVM.CoreLib.Tests.Symbols.IkvmReflection.IkvmReflectionSymbolTests+AttributeWithType"))); +// var v = a.Value.ConstructorArguments[0].Value; +// v.Should().BeOfType(); +// } + +// } + +//} diff --git a/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs b/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs index 93ce79548..5d01df942 100644 --- a/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs +++ b/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs @@ -5,6 +5,7 @@ using FluentAssertions; +using IKVM.CoreLib.Symbols; using IKVM.CoreLib.Symbols.Reflection; using IKVM.CoreLib.Symbols.Reflection.Emit; @@ -219,7 +220,7 @@ public void CanResolveAssemblyBuilder() var c = new ReflectionSymbolContext(); var a = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.RunAndCollect); var assemblySymbol = c.GetOrCreateAssemblySymbol(a); - assemblySymbol.Should().BeOfType(); + assemblySymbol.Should().BeOfType(); assemblySymbol.Should().BeSameAs(c.GetOrCreateAssemblySymbol(a)); } @@ -230,7 +231,7 @@ public void CanResolveModuleBuilder() var a = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.RunAndCollect); var module = a.DefineDynamicModule("Test"); var moduleSymbol = c.GetOrCreateModuleSymbol(module); - moduleSymbol.Should().BeOfType(); + moduleSymbol.Should().BeOfType(); moduleSymbol.Should().BeSameAs(c.GetOrCreateModuleSymbol(module)); } @@ -243,7 +244,7 @@ public void CanResolveTypeBuilder() var type1 = m.DefineType("DynamicType1"); var type1Symbol = c.GetOrCreateTypeSymbol(type1); - type1Symbol.Should().BeOfType(); + type1Symbol.Should().BeOfType(); type1Symbol.Should().BeSameAs(c.GetOrCreateTypeSymbol(type1)); } @@ -256,13 +257,13 @@ public void CanResolveMultipleTypeBuilders() var type1 = m.DefineType("DynamicType1"); var type1Symbol = c.GetOrCreateTypeSymbol(type1); - type1Symbol.Should().BeOfType(); + type1Symbol.Should().BeOfType(); type1Symbol.Should().BeSameAs(c.GetOrCreateTypeSymbol(type1)); type1.CreateType(); var type2 = m.DefineType("DynamicType2"); var type2Symbol = c.GetOrCreateTypeSymbol(type2); - type2Symbol.Should().BeOfType(); + type2Symbol.Should().BeOfType(); type2Symbol.Should().BeSameAs(c.GetOrCreateTypeSymbol(type2)); } @@ -276,7 +277,7 @@ public void CanResolveMethodBuilder() var method1 = t.DefineMethod("DynamicMethod1", MethodAttributes.Public | MethodAttributes.Static); var method1Symbol = c.GetOrCreateMethodSymbol(method1); - method1Symbol.Should().BeOfType(); + method1Symbol.Should().BeOfType(); method1Symbol.Should().BeSameAs(c.GetOrCreateMethodSymbol(method1)); } @@ -290,12 +291,12 @@ public void CanResolveMultipleMethodBuilders() var method1 = t.DefineMethod("DynamicMethod1", MethodAttributes.Public | MethodAttributes.Static); var method1Symbol = c.GetOrCreateMethodSymbol(method1); - method1Symbol.Should().BeOfType(); + method1Symbol.Should().BeOfType(); method1Symbol.Should().BeSameAs(c.GetOrCreateMethodSymbol(method1)); var method2 = t.DefineMethod("DynamicMethod2", MethodAttributes.Public | MethodAttributes.Static); var method2Symbol = c.GetOrCreateMethodSymbol(method2); - method2Symbol.Should().BeOfType(); + method2Symbol.Should().BeOfType(); method2Symbol.Should().BeSameAs(c.GetOrCreateMethodSymbol(method2)); } @@ -309,7 +310,7 @@ public void CanResolveFieldBuilder() var field = t.DefineField("dynamicField", typeof(object), FieldAttributes.Public); var fieldSymbol = c.GetOrCreateFieldSymbol(field); - fieldSymbol.Should().BeOfType(); + fieldSymbol.Should().BeOfType(); fieldSymbol.Should().BeSameAs(c.GetOrCreateFieldSymbol(field)); } @@ -323,12 +324,12 @@ public void CanResolveMultipleFieldBuilders() var field1 = t.DefineField("dynamicField1", typeof(object), FieldAttributes.Public); var field1Symbol = c.GetOrCreateFieldSymbol(field1); - field1Symbol.Should().BeOfType(); + field1Symbol.Should().BeOfType(); field1Symbol.Should().BeSameAs(c.GetOrCreateFieldSymbol(field1)); var field2 = t.DefineField("dynamicField2", typeof(object), FieldAttributes.Public); var field2Symbol = c.GetOrCreateFieldSymbol(field2); - field2Symbol.Should().BeOfType(); + field2Symbol.Should().BeOfType(); field2Symbol.Should().BeSameAs(c.GetOrCreateFieldSymbol(field2)); } @@ -342,7 +343,7 @@ public void CanResolvePropertyBuilder() var property = t.DefineProperty("DynamicProperty", PropertyAttributes.None, typeof(object), []); var propertySymbol = c.GetOrCreatePropertySymbol(property); - propertySymbol.Should().BeOfType(); + propertySymbol.Should().BeOfType(); propertySymbol.Should().BeSameAs(c.GetOrCreatePropertySymbol(property)); } @@ -356,12 +357,12 @@ public void CanResolveMultiplePropertyBuilders() var property1 = t.DefineProperty("DynamicProperty1", PropertyAttributes.None, typeof(object), []); var property1Symbol = c.GetOrCreatePropertySymbol(property1); - property1Symbol.Should().BeOfType(); + property1Symbol.Should().BeOfType(); property1Symbol.Should().BeSameAs(c.GetOrCreatePropertySymbol(property1)); var property2 = t.DefineProperty("DynamicProperty2", PropertyAttributes.None, typeof(object), []); var property2Symbol = c.GetOrCreatePropertySymbol(property2); - property2Symbol.Should().BeOfType(); + property2Symbol.Should().BeOfType(); property2Symbol.Should().BeSameAs(c.GetOrCreatePropertySymbol(property2)); } @@ -375,7 +376,7 @@ public void CanResolveEventBuilder() var event1 = t.DefineEvent("DynamicEvent", EventAttributes.None, typeof(EventHandler)); var event1Symbol = c.GetOrCreateEventSymbol(event1); - event1Symbol.Should().BeOfType(); + event1Symbol.Should().BeOfType(); event1Symbol.Should().BeSameAs(c.GetOrCreateEventSymbol(event1)); } @@ -389,12 +390,12 @@ public void CanResolveMultipleEventBuilders() var event1 = t.DefineEvent("DynamicEvent", EventAttributes.None, typeof(EventHandler)); var event1Symbol = c.GetOrCreateEventSymbol(event1); - event1Symbol.Should().BeOfType(); + event1Symbol.Should().BeOfType(); event1Symbol.Should().BeSameAs(c.GetOrCreateEventSymbol(event1)); var event2 = t.DefineEvent("DynamicEvent", EventAttributes.None, typeof(EventHandler)); var event2Symbol = c.GetOrCreateEventSymbol(event2); - event2Symbol.Should().BeOfType(); + event2Symbol.Should().BeOfType(); event2Symbol.Should().BeSameAs(c.GetOrCreateEventSymbol(event2)); } @@ -402,22 +403,22 @@ public void CanResolveMultipleEventBuilders() public void CanCompleteTypeBuilder() { var c = new ReflectionSymbolContext(); - var a = new ReflectionAssemblySymbolBuilder(c, AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.RunAndCollect)); + var a = c.GetOrCreateAssemblySymbol(AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.RunAndCollect)); var moduleBuilder = a.DefineModule("DynamicModule"); - var moduleSymbol = moduleBuilder.Symbol; + var moduleSymbol = (IModuleSymbol)moduleBuilder; var type1Builder = moduleBuilder.DefineType("DynamicType1"); - var type1Symbol = type1Builder.Symbol; - type1Symbol.Should().BeOfType(); + var type1Symbol = (ITypeSymbol)type1Builder; + type1Symbol.Should().BeOfType(); type1Builder.Complete(); - var type1SymbolAgain = type1Builder.Symbol; - type1SymbolAgain.Should().BeSameAs(type1Symbol); - type1SymbolAgain.Name.Should().Be("DynamicType1"); + var type1Again = moduleBuilder.GetType("DynamicType1"); + type1Again.Should().BeSameAs(type1Symbol); + type1Again.Name.Should().Be("DynamicType1"); // check that we can relookup type - moduleSymbol.GetType("DynamicType1").Should().BeSameAs(type1SymbolAgain); + moduleSymbol.GetType("DynamicType1").Should().BeSameAs(type1Symbol); } } diff --git a/src/IKVM.CoreLib/IKVM.CoreLib.csproj b/src/IKVM.CoreLib/IKVM.CoreLib.csproj index 5e31c90e3..13b96c3da 100644 --- a/src/IKVM.CoreLib/IKVM.CoreLib.csproj +++ b/src/IKVM.CoreLib/IKVM.CoreLib.csproj @@ -20,6 +20,10 @@ + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + @@ -102,4 +106,12 @@ + + + + PreserveNewest + + + + diff --git a/src/IKVM.CoreLib/System/TypeExtensions.cs b/src/IKVM.CoreLib/Reflection/ReflectionExtensions.cs similarity index 76% rename from src/IKVM.CoreLib/System/TypeExtensions.cs rename to src/IKVM.CoreLib/Reflection/ReflectionExtensions.cs index ea2a69932..0defa18ab 100644 --- a/src/IKVM.CoreLib/System/TypeExtensions.cs +++ b/src/IKVM.CoreLib/Reflection/ReflectionExtensions.cs @@ -1,24 +1,45 @@ -using System.Linq.Expressions; +using System; +using System.Linq.Expressions; using System.Reflection; using System.Reflection.Emit; using System.Reflection.Metadata.Ecma335; -namespace System +namespace IKVM.CoreLib.Reflection { - static class TypeExtensions + static class ReflectionExtensions { + static readonly ParameterExpression _assemblyBuilderRuntimeAssemblyParameter = Expression.Parameter(typeof(AssemblyBuilder), "p"); static readonly ParameterExpression _propertyBuilderParameter = Expression.Parameter(typeof(PropertyBuilder), "p"); static readonly ParameterExpression _eventBuilderParameter = Expression.Parameter(typeof(EventBuilder), "p"); static readonly ParameterExpression _parameterBuilderParameter = Expression.Parameter(typeof(ParameterBuilder), "p"); #if NET +#if NET8_0_OR_GREATER + + static readonly Type _assemblyBuilderType = typeof(AssemblyBuilder).Assembly.GetType("System.Reflection.Emit.RuntimeAssemblyBuilder", true)!; static readonly Type _propertyBuilderType = typeof(PropertyBuilder).Assembly.GetType("System.Reflection.Emit.RuntimePropertyBuilder", true)!; static readonly Type _eventBuilderType = typeof(EventBuilder).Assembly.GetType("System.Reflection.Emit.RuntimeEventBuilder", true)!; static readonly Type _parameterBuilderType = typeof(ParameterBuilder).Assembly.GetType("System.Reflection.Emit.RuntimeParameterBuilder", true)!; +#else + + static readonly Type _assemblyBuilderType = typeof(AssemblyBuilder).Assembly.GetType("System.Reflection.Emit.AssemblyBuilder", true)!; + static readonly Type _propertyBuilderType = typeof(PropertyBuilder).Assembly.GetType("System.Reflection.Emit.PropertyBuilder", true)!; + static readonly Type _eventBuilderType = typeof(EventBuilder).Assembly.GetType("System.Reflection.Emit.EventBuilder", true)!; + static readonly Type _parameterBuilderType = typeof(ParameterBuilder).Assembly.GetType("System.Reflection.Emit.ParameterBuilder", true)!; + +#endif + + static readonly Func _getAssemblyBuilderRuntimeAssemblyFunc = Expression.Lambda>( + Expression.Property( + Expression.ConvertChecked(_assemblyBuilderRuntimeAssemblyParameter, _assemblyBuilderType), + _assemblyBuilderType.GetProperty("InternalAssembly", BindingFlags.NonPublic | BindingFlags.Instance) ?? throw new InvalidOperationException()), + _assemblyBuilderRuntimeAssemblyParameter) + .Compile(); + static readonly Func _getPropertyMetadataTokenFunc = Expression.Lambda>( Expression.Field( Expression.ConvertChecked(_propertyBuilderParameter, _propertyBuilderType), @@ -26,7 +47,6 @@ static class TypeExtensions _propertyBuilderParameter) .Compile(); - static readonly Func _getEventMetadataTokenFunc = Expression.Lambda>( Expression.Field( Expression.ConvertChecked(_eventBuilderParameter, _eventBuilderType), @@ -50,9 +70,17 @@ static class TypeExtensions #else + static readonly Type _assemblyBuilderType = typeof(AssemblyBuilder).Assembly.GetType("System.Reflection.Emit.AssemblyBuilder", true)!; static readonly Type _eventBuilderType = typeof(EventBuilder).Assembly.GetType("System.Reflection.Emit.EventBuilder", true)!; static readonly Type _parameterBuilderType = typeof(ParameterBuilder).Assembly.GetType("System.Reflection.Emit.ParameterBuilder", true)!; + static readonly Func _getAssemblyBuilderRuntimeAssemblyFunc = Expression.Lambda>( + Expression.Call( + Expression.ConvertChecked(_assemblyBuilderRuntimeAssemblyParameter, _assemblyBuilderType), + _assemblyBuilderType.GetMethod("GetNativeHandle", BindingFlags.NonPublic | BindingFlags.Instance) ?? throw new InvalidOperationException()), + _assemblyBuilderRuntimeAssemblyParameter) + .Compile(); + static readonly Func _getParameterMethodBuilderFunc = Expression.Lambda>( Expression.Field( Expression.ConvertChecked(_parameterBuilderParameter, _parameterBuilderType), @@ -116,6 +144,24 @@ public static int GetMetadataTokenRowNumberSafe(this Module module) return MetadataTokens.GetRowNumber(MetadataTokens.EntityHandle(module.GetMetadataTokenSafe())); } + /// + /// Gets the metadata token for the specified . + /// + /// + /// + public static int GetMetadataTokenSafe(this MemberInfo member) + { + return member switch + { + Type t => t.GetMetadataTokenSafe(), + MethodBase m => m.GetMetadataTokenSafe(), + FieldInfo f => f.GetMetadataTokenSafe(), + PropertyInfo p => p.GetMetadataTokenSafe(), + EventInfo e => e.GetMetadataTokenSafe(), + _ => throw new InvalidOperationException(), + }; + } + /// /// Gets the metadata token for the specified . /// @@ -352,7 +398,7 @@ public static int GetMetadataToken(this EventBuilder @event) /// public static int GetMetadataTokenSafe(this EventBuilder @event) { - var t = GetMetadataToken(@event); + var t = @event.GetMetadataToken(); if (t == 0) throw new InvalidOperationException(); @@ -410,6 +456,76 @@ public static int GetMetadataToken(this ParameterBuilder parameter) #endif } + /// + /// Gets the associated with a . + /// + /// + /// + public static Assembly GetRuntimeAssembly(this AssemblyBuilder assembly) + { + return _getAssemblyBuilderRuntimeAssemblyFunc(assembly); + } + + /// + /// Gets the associated with a . + /// + /// + /// + public static ModuleBuilder GetModuleBuilder(this ParameterBuilder parameter) + { + return (ModuleBuilder)_getParameterMethodBuilderFunc(parameter).Module; + } + + /// + /// Gets the associated with a . + /// + /// + /// + public static TypeBuilder GetTypeBuilder(this ParameterBuilder parameter) + { + return (TypeBuilder?)_getParameterMethodBuilderFunc(parameter).DeclaringType ?? throw new InvalidOperationException(); + } + + /// + /// Gets the associated with a . + /// + /// + /// + public static ModuleBuilder GetModuleBuilder(this FieldBuilder field) + { + return (ModuleBuilder)field.Module; + } + + /// + /// Gets the associated with a . + /// + /// + /// + public static TypeBuilder GetTypeBuilder(this FieldBuilder field) + { + return (TypeBuilder?)field.DeclaringType ?? throw new InvalidOperationException(); + } + + /// + /// Gets the associated with a . + /// + /// + /// + public static ModuleBuilder GetModuleBuilder(this PropertyBuilder property) + { + return (ModuleBuilder)property.Module; + } + + /// + /// Gets the associated with a . + /// + /// + /// + public static TypeBuilder GetTypeBuilder(this PropertyBuilder property) + { + return (TypeBuilder)property.DeclaringType!; + } + /// /// Gets the associated with a . /// @@ -455,7 +571,7 @@ public static EventAttributes GetEventAttributes(this EventBuilder @event) /// /// /// - public static MemberInfo GetMethodBuilder(this ParameterBuilder parameter) + public static MethodBuilder GetMethodBuilder(this ParameterBuilder parameter) { return _getParameterMethodBuilderFunc(parameter); } diff --git a/src/IKVM.CoreLib/Symbols/Emit/IAssemblySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IAssemblySymbolBuilder.cs index 1bac977b7..d99608a52 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/IAssemblySymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/IAssemblySymbolBuilder.cs @@ -1,9 +1,7 @@ -using System.Xml.Linq; - -namespace IKVM.CoreLib.Symbols.Emit +namespace IKVM.CoreLib.Symbols.Emit { - interface IAssemblySymbolBuilder : ISymbolBuilder + interface IAssemblySymbolBuilder : ISymbolBuilder, IAssemblySymbol { /// @@ -43,11 +41,6 @@ interface IAssemblySymbolBuilder : ISymbolBuilder /// void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute); - /// - /// Finishes all modules of the assembly, updating the associated symbols. - /// - void Complete(); - } } diff --git a/src/IKVM.CoreLib/Symbols/Emit/IConstructorSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IConstructorSymbolBuilder.cs index e98f8e770..e3ca76885 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/IConstructorSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/IConstructorSymbolBuilder.cs @@ -3,7 +3,7 @@ namespace IKVM.CoreLib.Symbols.Emit { - interface IConstructorSymbolBuilder : ISymbolBuilder + interface IConstructorSymbolBuilder : ISymbolBuilder, IMethodBaseSymbolBuilder, IConstructorSymbol { /// diff --git a/src/IKVM.CoreLib/Symbols/Emit/IEventSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IEventSymbolBuilder.cs index b5378a41d..36b725765 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/IEventSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/IEventSymbolBuilder.cs @@ -1,7 +1,7 @@ namespace IKVM.CoreLib.Symbols.Emit { - interface IEventSymbolBuilder : ISymbolBuilder + interface IEventSymbolBuilder : ISymbolBuilder, IMemberSymbolBuilder, IEventSymbol { /// diff --git a/src/IKVM.CoreLib/Symbols/Emit/IFieldSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IFieldSymbolBuilder.cs index 5b6706e3f..ad3048c16 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/IFieldSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/IFieldSymbolBuilder.cs @@ -1,7 +1,7 @@ namespace IKVM.CoreLib.Symbols.Emit { - interface IFieldSymbolBuilder : ISymbolBuilder + interface IFieldSymbolBuilder : ISymbolBuilder, IMemberSymbolBuilder, IFieldSymbol { /// diff --git a/src/IKVM.CoreLib/Symbols/Emit/IGenericTypeParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IGenericTypeParameterSymbolBuilder.cs index 38bcde837..cfd742441 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/IGenericTypeParameterSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/IGenericTypeParameterSymbolBuilder.cs @@ -1,11 +1,28 @@ namespace IKVM.CoreLib.Symbols.Emit { - interface IGenericTypeParameterSymbolBuilder : ISymbolBuilder + interface IGenericTypeParameterSymbolBuilder : ISymbolBuilder, ITypeSymbol { + /// + /// Sets the base type that a type must inherit in order to be substituted for the type parameter. + /// + /// + void SetBaseTypeConstraint(ITypeSymbol? baseTypeConstraint); + + /// + /// Sets the variance characteristics and special constraints of the generic parameter, such as the parameterless constructor constraint. + /// + /// + void SetGenericParameterAttributes(System.Reflection.GenericParameterAttributes genericParameterAttributes); + + /// + /// Sets the interfaces a type must implement in order to be substituted for the type parameter. + /// + /// + void SetInterfaceConstraints(params ITypeSymbol[]? interfaceConstraints); } -} \ No newline at end of file +} diff --git a/src/IKVM.CoreLib/Symbols/Emit/IILGenerator.cs b/src/IKVM.CoreLib/Symbols/Emit/IILGenerator.cs index 69f29dfa3..1677d7076 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/IILGenerator.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/IILGenerator.cs @@ -4,7 +4,264 @@ interface IILGenerator { + /// + /// Gets the current offset, in bytes, in the Microsoft intermediate language (MSIL) stream that is being emitted by the . + /// + int ILOffset { get; } + /// + /// Begins a lexical scope. + /// + void BeginScope(); + + /// + /// Specifies the namespace to be used in evaluating locals and watches for the current active lexical scope. + /// + /// + void UsingNamespace(string usingNamespace); + + /// + /// Ends a lexical scope. + /// + void EndScope(); + + /// + /// Marks a sequence point in the Microsoft intermediate language (MSIL) stream. + /// + /// + /// + /// + /// + /// + void MarkSequencePoint(System.Diagnostics.SymbolStore.ISymbolDocumentWriter document, int startLine, int startColumn, int endLine, int endColumn); + + /// + /// Declares a local variable of the specified type, optionally pinning the object referred to by the variable. + /// + /// + /// + /// + ILocalBuilder DeclareLocal(ITypeSymbol localType, bool pinned); + + /// + /// Declares a local variable of the specified type. + /// + /// + /// + ILocalBuilder DeclareLocal(ITypeSymbol localType); + + /// + /// Declares a new label. + /// + /// + System.Reflection.Emit.Label DefineLabel(); + + /// + /// Begins an exception block for a non-filtered exception. + /// + /// + System.Reflection.Emit.Label BeginExceptionBlock(); + + /// + /// Marks the Microsoft intermediate language (MSIL) stream's current position with the given label. + /// + /// + void MarkLabel(System.Reflection.Emit.Label loc); + + /// + /// Begins an exception block for a filtered exception. + /// + void BeginExceptFilterBlock(); + + /// + /// Begins a catch block. + /// + /// + void BeginCatchBlock(ITypeSymbol? exceptionType); + + /// + /// Begins an exception fault block in the Microsoft intermediate language (MSIL) stream. + /// + void BeginFaultBlock(); + + /// + /// Begins a finally block in the Microsoft intermediate language (MSIL) instruction stream. + /// + void BeginFinallyBlock(); + + /// + /// Ends an exception block. + /// + void EndExceptionBlock(); + + /// + /// Emits an instruction to throw an exception. + /// + /// + void ThrowException(ITypeSymbol excType); + + /// + /// Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the index of the given local variable. + /// + /// + /// + void Emit(System.Reflection.Emit.OpCode opcode, ILocalBuilder local); + + /// + /// Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the metadata token for the given type. + /// + /// + /// + void Emit(System.Reflection.Emit.OpCode opcode, ITypeSymbol cls); + + /// + /// Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the metadata token for the given string. + /// + /// + /// + void Emit(System.Reflection.Emit.OpCode opcode, string str); + + /// + /// Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions. + /// + /// + /// + void Emit(System.Reflection.Emit.OpCode opcode, float arg); + + /// + /// Puts the specified instruction and character argument onto the Microsoft intermediate language (MSIL) stream of instructions. + /// + /// + /// + void Emit(System.Reflection.Emit.OpCode opcode, sbyte arg); + + /// + /// Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the metadata token for the given method. + /// + /// + /// + void Emit(System.Reflection.Emit.OpCode opcode, IMethodSymbol meth); + + /// + /// Puts the specified instruction and a signature token onto the Microsoft intermediate language (MSIL) stream of instructions. + /// + /// + /// + void Emit(System.Reflection.Emit.OpCode opcode, ISignatureHelper signature); + + /// + /// Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream and leaves space to include a label when fixes are done. + /// + /// + /// + void Emit(System.Reflection.Emit.OpCode opcode, ILabel[] labels); + + /// + /// Puts the specified instruction and metadata token for the specified field onto the Microsoft intermediate language (MSIL) stream of instructions. + /// + /// + /// + void Emit(System.Reflection.Emit.OpCode opcode, IFieldSymbol field); + + /// + /// Puts the specified instruction and metadata token for the specified constructor onto the Microsoft intermediate language (MSIL) stream of instructions. + /// + /// + /// + void Emit(System.Reflection.Emit.OpCode opcode, IConstructorSymbol con); + + /// + /// Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions. + /// + /// + /// + void Emit(System.Reflection.Emit.OpCode opcode, long arg); + + /// + /// Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions. + /// + /// + /// + void Emit(System.Reflection.Emit.OpCode opcode, int arg); + + /// + /// Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions. + /// + /// + /// + void Emit(System.Reflection.Emit.OpCode opcode, short arg); + + /// + /// Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions. + /// + /// + /// + void Emit(System.Reflection.Emit.OpCode opcode, double arg); + + /// + /// Puts the specified instruction and character argument onto the Microsoft intermediate language (MSIL) stream of instructions. + /// + /// + /// + void Emit(System.Reflection.Emit.OpCode opcode, byte arg); + + /// + /// Puts the specified instruction onto the stream of instructions. + /// + /// + void Emit(System.Reflection.Emit.OpCode opcode); + + /// + /// Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream and leaves space to include a label when fixes are done. + /// + /// + /// + void Emit(System.Reflection.Emit.OpCode opcode, ILabel label); + + /// + /// Puts a call or callvirt instruction onto the Microsoft intermediate language (MSIL) stream to call a varargs method. + /// + /// + /// + /// + void EmitCall(System.Reflection.Emit.OpCode opcode, IMethodSymbol methodInfo, ITypeSymbol[]? optionalParameterTypes); + + /// + /// Puts a Calli instruction onto the Microsoft intermediate language (MSIL) stream, specifying an unmanaged calling convention for the indirect call. + /// + /// + /// + /// + /// + void EmitCalli(System.Reflection.Emit.OpCode opcode, System.Runtime.InteropServices.CallingConvention unmanagedCallConv, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes); + + /// + /// Puts a Calli instruction onto the Microsoft intermediate language (MSIL) stream, specifying a managed calling convention for the indirect call. + /// + /// + /// + /// + /// + /// + void EmitCalli(System.Reflection.Emit.OpCode opcode, System.Reflection.CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes, ITypeSymbol[]? optionalParameterTypes); + + /// + /// Emits the Microsoft intermediate language (MSIL) to call with a string. + /// + /// + void EmitWriteLine(string value); + + /// + /// Emits the Microsoft intermediate language (MSIL) necessary to call with the given field. + /// + /// + void EmitWriteLine(IFieldSymbol fld); + + /// + /// Emits the Microsoft intermediate language (MSIL) necessary to call with the given local variable. + /// + /// + void EmitWriteLine(ILocalBuilder localBuilder); } diff --git a/src/IKVM.CoreLib/Symbols/Emit/ILabel.cs b/src/IKVM.CoreLib/Symbols/Emit/ILabel.cs new file mode 100644 index 000000000..c36f9d801 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Emit/ILabel.cs @@ -0,0 +1,6 @@ +namespace IKVM.CoreLib.Symbols.Emit +{ + public interface ILabel + { + } +} \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/Emit/ILocalBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/ILocalBuilder.cs new file mode 100644 index 000000000..650edcb8d --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Emit/ILocalBuilder.cs @@ -0,0 +1,42 @@ +namespace IKVM.CoreLib.Symbols.Emit +{ + + /// + /// Represents a local variable within a method or constructor. + /// + interface ILocalBuilder + { + + /// + /// Gets a value indicating whether the object referred to by the local variable is pinned in memory. + /// + bool IsPinned { get; } + + /// + /// Gets the zero-based index of the local variable within the method body. + /// + int LocalIndex { get; } + + /// + /// Gets the type of the local variable. + /// + ITypeSymbol LocalType { get; } + + /// + /// Sets the name of this local variable. + /// + /// + void SetLocalSymInfo(string name); + + /// + /// Sets the name and lexical scope of this local variable. + /// + /// + /// + /// + void SetLocalSymInfo(string name, int startOffset, int endOffset); + + + } + +} \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/Emit/IMemberSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IMemberSymbolBuilder.cs new file mode 100644 index 000000000..b787c9ced --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Emit/IMemberSymbolBuilder.cs @@ -0,0 +1,11 @@ +namespace IKVM.CoreLib.Symbols.Emit +{ + + interface IMemberSymbolBuilder : ISymbolBuilder, IMemberSymbol + { + + + + } + +} \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/Emit/IMethodBaseSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IMethodBaseSymbolBuilder.cs new file mode 100644 index 000000000..894c8e9b1 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Emit/IMethodBaseSymbolBuilder.cs @@ -0,0 +1,11 @@ +namespace IKVM.CoreLib.Symbols.Emit +{ + + interface IMethodBaseSymbolBuilder : ISymbolBuilder, IMemberSymbolBuilder, IMethodBaseSymbol + { + + + + } + +} \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/Emit/IMethodSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IMethodSymbolBuilder.cs index 9e251bed2..8220de296 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/IMethodSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/IMethodSymbolBuilder.cs @@ -1,7 +1,7 @@ namespace IKVM.CoreLib.Symbols.Emit { - interface IMethodSymbolBuilder : ISymbolBuilder + interface IMethodSymbolBuilder : ISymbolBuilder, IMethodBaseSymbolBuilder, IMethodSymbol { /// diff --git a/src/IKVM.CoreLib/Symbols/Emit/IModuleSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IModuleSymbolBuilder.cs index 4ffa0fdb1..72bb9e7d7 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/IModuleSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/IModuleSymbolBuilder.cs @@ -4,7 +4,7 @@ namespace IKVM.CoreLib.Symbols.Emit { - interface IModuleSymbolBuilder : ISymbolBuilder + interface IModuleSymbolBuilder : ISymbolBuilder, IModuleSymbol { /// @@ -85,11 +85,6 @@ interface IModuleSymbolBuilder : ISymbolBuilder /// void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute); - /// - /// Finishes all types of the module, updating the associated symbols. - /// - void Complete(); - } } diff --git a/src/IKVM.CoreLib/Symbols/Emit/IParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IParameterSymbolBuilder.cs index 9ac13b384..860f872f7 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/IParameterSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/IParameterSymbolBuilder.cs @@ -1,7 +1,7 @@ namespace IKVM.CoreLib.Symbols.Emit { - interface IParameterSymbolBuilder : ISymbolBuilder + interface IParameterSymbolBuilder : ISymbolBuilder, IParameterSymbol { /// /// Sets the default value of the parameter. diff --git a/src/IKVM.CoreLib/Symbols/Emit/IPropertySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IPropertySymbolBuilder.cs index 6c2d9ade9..c1f200f2f 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/IPropertySymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/IPropertySymbolBuilder.cs @@ -1,9 +1,33 @@ namespace IKVM.CoreLib.Symbols.Emit { - interface IPropertySymbolBuilder : ISymbolBuilder + interface IPropertySymbolBuilder : ISymbolBuilder, IMemberSymbolBuilder, IPropertySymbol { + /// + /// Sets the default value of this property. + /// + /// + void SetConstant(object? defaultValue); + + /// + /// Sets the method that gets the property value. + /// + /// + void SetGetMethod(IMethodSymbolBuilder mdBuilder); + + /// + /// Sets the method that sets the property value. + /// + /// + void SetSetMethod(IMethodSymbolBuilder mdBuilder); + + /// + /// Adds one of the other methods associated with this property. + /// + /// + void AddOtherMethod(IMethodSymbolBuilder mdBuilder); + /// /// Set a custom attribute using a custom attribute builder. /// diff --git a/src/IKVM.CoreLib/Symbols/Emit/ISignatureHelper.cs b/src/IKVM.CoreLib/Symbols/Emit/ISignatureHelper.cs new file mode 100644 index 000000000..f7be27ef9 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Emit/ISignatureHelper.cs @@ -0,0 +1,6 @@ +namespace IKVM.CoreLib.Symbols.Emit +{ + public interface ISignatureHelper + { + } +} \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/Emit/ISymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/ISymbolBuilder.cs index 8b7b295fe..3e952aae9 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/ISymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/ISymbolBuilder.cs @@ -7,10 +7,7 @@ interface ISymbolBuilder { - /// - /// Gets the that is currently being built. Portions of this interface will be non-functional until the build is completed. - /// - ISymbol Symbol { get; } + } @@ -22,10 +19,7 @@ interface ISymbolBuilder : ISymbolBuilder where TSymbol : ISymbol { - /// - /// Gets the that is currently being built. Portions of this interface will be non-functional until the build is completed. - /// - new TSymbol Symbol { get; } + } diff --git a/src/IKVM.CoreLib/Symbols/Emit/ITypeSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/ITypeSymbolBuilder.cs index 7bed9beb7..6b4b44107 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/ITypeSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/ITypeSymbolBuilder.cs @@ -3,7 +3,7 @@ namespace IKVM.CoreLib.Symbols.Emit { - interface ITypeSymbolBuilder : ISymbolBuilder + interface ITypeSymbolBuilder : ISymbolBuilder, IMemberSymbolBuilder, ITypeSymbol { /// @@ -140,6 +140,13 @@ interface ITypeSymbolBuilder : ISymbolBuilder /// IMethodSymbolBuilder DefineMethod(string name, System.Reflection.MethodAttributes attributes, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes); + /// + /// Specifies a given method body that implements a given method declaration, potentially with a different name. + /// + /// + /// + void DefineMethodOverride(IMethodSymbolBuilder methodInfoBody, IMethodSymbol methodInfoDeclaration); + /// /// Defines a nested type, given its name, attributes, the type that it extends, and the interfaces that it implements. /// diff --git a/src/IKVM.CoreLib/Symbols/IAssemblySymbol.cs b/src/IKVM.CoreLib/Symbols/IAssemblySymbol.cs index a87909ae3..3d3d39975 100644 --- a/src/IKVM.CoreLib/Symbols/IAssemblySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IAssemblySymbol.cs @@ -1,6 +1,8 @@ using System.Collections.Generic; using System.Reflection; +using IKVM.CoreLib.Symbols.Emit; + namespace IKVM.CoreLib.Symbols { diff --git a/src/IKVM.CoreLib/Symbols/IEventSymbol.cs b/src/IKVM.CoreLib/Symbols/IEventSymbol.cs index 220a74891..50ee2179a 100644 --- a/src/IKVM.CoreLib/Symbols/IEventSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IEventSymbol.cs @@ -1,5 +1,7 @@ using System.Reflection; +using IKVM.CoreLib.Symbols.Emit; + namespace IKVM.CoreLib.Symbols { diff --git a/src/IKVM.CoreLib/Symbols/IFieldSymbol.cs b/src/IKVM.CoreLib/Symbols/IFieldSymbol.cs index 1eee20fe9..c927898a5 100644 --- a/src/IKVM.CoreLib/Symbols/IFieldSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IFieldSymbol.cs @@ -1,5 +1,7 @@ using System.Reflection; +using IKVM.CoreLib.Symbols.Emit; + namespace IKVM.CoreLib.Symbols { diff --git a/src/IKVM.CoreLib/Symbols/IMethodSymbol.cs b/src/IKVM.CoreLib/Symbols/IMethodSymbol.cs index c3c8d5c9e..06709a367 100644 --- a/src/IKVM.CoreLib/Symbols/IMethodSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IMethodSymbol.cs @@ -1,4 +1,6 @@ -namespace IKVM.CoreLib.Symbols +using IKVM.CoreLib.Symbols.Emit; + +namespace IKVM.CoreLib.Symbols { /// diff --git a/src/IKVM.CoreLib/Symbols/IParameterSymbol.cs b/src/IKVM.CoreLib/Symbols/IParameterSymbol.cs index 18e855157..e1008c96c 100644 --- a/src/IKVM.CoreLib/Symbols/IParameterSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IParameterSymbol.cs @@ -1,5 +1,7 @@ using System.Reflection; +using IKVM.CoreLib.Symbols.Reflection; + namespace IKVM.CoreLib.Symbols { diff --git a/src/IKVM.CoreLib/Symbols/IPropertySymbol.cs b/src/IKVM.CoreLib/Symbols/IPropertySymbol.cs index 0b73fbf86..5f47a277b 100644 --- a/src/IKVM.CoreLib/Symbols/IPropertySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IPropertySymbol.cs @@ -1,5 +1,7 @@ using System.Reflection; +using IKVM.CoreLib.Symbols.Emit; + namespace IKVM.CoreLib.Symbols { diff --git a/src/IKVM.CoreLib/Symbols/ISymbol.cs b/src/IKVM.CoreLib/Symbols/ISymbol.cs index 7fae6f73e..33f2a500d 100644 --- a/src/IKVM.CoreLib/Symbols/ISymbol.cs +++ b/src/IKVM.CoreLib/Symbols/ISymbol.cs @@ -17,6 +17,11 @@ interface ISymbol /// bool ContainsMissing { get; } + /// + /// Returns true if the symbol is complete. That is, was created with a builder and completed. + /// + bool IsComplete { get; } + } } diff --git a/src/IKVM.CoreLib/Symbols/ISymbolContext.cs b/src/IKVM.CoreLib/Symbols/ISymbolContext.cs new file mode 100644 index 000000000..81457295e --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/ISymbolContext.cs @@ -0,0 +1,48 @@ +using IKVM.CoreLib.Symbols.Emit; + +namespace IKVM.CoreLib.Symbols +{ + + interface ISymbolContext + { + + /// + /// Initializes an instance of the interface given the constructor for the custom attribute and the arguments to the constructor. + /// + /// + /// + /// + ICustomAttributeBuilder CreateCustomAttribute(IConstructorSymbol con, object?[] constructorArgs); + + /// + /// Initializes an instance of the interface given the constructor for the custom attribute, the arguments to the constructor, and a set of named field/value pairs. + /// + /// + /// + /// + /// + ICustomAttributeBuilder CreateCustomAttribute(IConstructorSymbol con, object?[] constructorArgs, IFieldSymbol[] namedFields, object?[] fieldValues); + + /// + /// Initializes an instance of the interface given the constructor for the custom attribute, the arguments to the constructor, and a set of named property or value pairs. + /// + /// + /// + /// + /// + ICustomAttributeBuilder CreateCustomAttribute(IConstructorSymbol con, object?[] constructorArgs, IPropertySymbol[] namedProperties, object?[] propertyValues); + + /// + /// Initializes an instance of the interface given the constructor for the custom attribute, the arguments to the constructor, a set of named property or value pairs, and a set of named field or value pairs. + /// + /// + /// + /// + /// + /// + /// + ICustomAttributeBuilder CreateCustomAttribute(IConstructorSymbol con, object?[] constructorArgs, IPropertySymbol[] namedProperties, object?[] propertyValues, IFieldSymbol[] namedFields, object?[] fieldValues); + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionAssemblySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionAssemblySymbolBuilder.cs deleted file mode 100644 index ccb5a77f4..000000000 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionAssemblySymbolBuilder.cs +++ /dev/null @@ -1,79 +0,0 @@ -using System; - -using IKVM.CoreLib.Symbols.Emit; -using IKVM.Reflection.Emit; - -namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit -{ - - class IkvmReflectionAssemblySymbolBuilder : IkvmReflectionSymbolBuilder, IAssemblySymbolBuilder - { - - readonly AssemblyBuilder _builder; - IkvmReflectionAssemblySymbol? _symbol; - - /// - /// Initializes a new instance. - /// - /// - /// - public IkvmReflectionAssemblySymbolBuilder(IkvmReflectionSymbolContext context, AssemblyBuilder builder) : - base(context) - { - _builder = builder ?? throw new ArgumentNullException(nameof(builder)); - } - - /// - internal sealed override IkvmReflectionAssemblySymbol ReflectionSymbol => _symbol ??= Context.GetOrCreateAssemblySymbol(_builder); - - /// - public IModuleSymbolBuilder DefineModule(string name) - { - return new IkvmReflectionModuleSymbolBuilder(Context, _builder.DefineDynamicModule(name, name + ".dll")); - } - - /// - public IModuleSymbolBuilder DefineModule(string name, string fileName) - { - return new IkvmReflectionModuleSymbolBuilder(Context, _builder.DefineDynamicModule(name, fileName)); - } - - /// - public IModuleSymbolBuilder DefineModule(string name, string fileName, bool emitSymbolInfo) - { - return new IkvmReflectionModuleSymbolBuilder(Context, _builder.DefineDynamicModule(name, fileName, emitSymbolInfo)); - } - - /// - public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) - { - _builder.SetCustomAttribute(con.Unpack(), binaryAttribute); - } - - /// - public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) - { - _builder.SetCustomAttribute(((IkvmReflectionCustomAttributeBuilder)customBuilder).ReflectionBuilder); - } - - /// - public void Complete() - { - foreach (var module in _builder.GetModules()) - { - if (module is ModuleBuilder moduleBuilder) - { - moduleBuilder.CreateGlobalFunctions(); - - foreach (var type in moduleBuilder.GetTypes()) - if (type is TypeBuilder typeBuilder) - if (typeBuilder.IsCreated() == false) - if (typeBuilder.CreateType() is { } t) - ReflectionSymbol.ResolveTypeSymbol(t).Complete(t); - } - } - } - - } - -} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionConstructorSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionConstructorSymbolBuilder.cs deleted file mode 100644 index 2d0fc2e7c..000000000 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionConstructorSymbolBuilder.cs +++ /dev/null @@ -1,74 +0,0 @@ -using System; - -using IKVM.CoreLib.Symbols.Emit; -using IKVM.Reflection; -using IKVM.Reflection.Emit; - -namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit -{ - - class IkvmReflectionConstructorSymbolBuilder : IkvmReflectionMethodBaseSymbolBuilder, IConstructorSymbolBuilder - { - - readonly ConstructorBuilder _builder; - IkvmReflectionConstructorSymbol? _symbol; - - /// - /// Initializes a new instance. - /// - /// - /// - /// - public IkvmReflectionConstructorSymbolBuilder(IkvmReflectionSymbolContext context, IkvmReflectionTypeSymbolBuilder containingTypeBuilder, ConstructorBuilder builder) : - base(context, containingTypeBuilder) - { - _builder = builder ?? throw new ArgumentNullException(nameof(builder)); - } - - /// - /// Gets the containing . - /// - protected internal new IkvmReflectionTypeSymbolBuilder ContainingTypeBuilder => base.ContainingTypeBuilder ?? throw new NullReferenceException(); - - /// - internal override IkvmReflectionConstructorSymbol ReflectionSymbol => _symbol ??= Context.GetOrCreateConstructorSymbol(_builder); - - /// - public void SetImplementationFlags(System.Reflection.MethodImplAttributes attributes) - { - _builder.SetImplementationFlags((MethodImplAttributes)attributes); - } - - /// - public IParameterSymbolBuilder DefineParameter(int iSequence, System.Reflection.ParameterAttributes attributes, string? strParamName) - { - return new IkvmReflectionParameterSymbolBuilder(Context, this, _builder, _builder.DefineParameter(iSequence, (ParameterAttributes)attributes, strParamName)); - } - - /// - public IILGenerator GetILGenerator() - { - throw new NotImplementedException(); - } - - /// - public IILGenerator GetILGenerator(int streamSize) - { - throw new NotImplementedException(); - } - - /// - public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) - { - _builder.SetCustomAttribute(((IkvmReflectionCustomAttributeBuilder)customBuilder).ReflectionBuilder); - } - - /// - public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) - { - _builder.SetCustomAttribute(con.Unpack(), binaryAttribute); - } - - } - -} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionCustomAttributeBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionCustomAttributeBuilder.cs deleted file mode 100644 index 39adf5040..000000000 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionCustomAttributeBuilder.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; - -using IKVM.CoreLib.Symbols.Emit; -using IKVM.Reflection.Emit; - -namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit -{ - - class IkvmReflectionCustomAttributeBuilder : ICustomAttributeBuilder - { - - readonly CustomAttributeBuilder _builder; - - /// - /// Initializes a new instance. - /// - public IkvmReflectionCustomAttributeBuilder(CustomAttributeBuilder builder) - { - _builder = builder ?? throw new ArgumentNullException(nameof(builder)); - } - - /// - /// Gets the underlying reflection . - /// - internal CustomAttributeBuilder ReflectionBuilder => _builder; - - } - -} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionEventSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionEventSymbolBuilder.cs deleted file mode 100644 index c1b580055..000000000 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionEventSymbolBuilder.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System; - -using IKVM.CoreLib.Symbols.Emit; -using IKVM.Reflection.Emit; - -namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit -{ - - class IkvmReflectionEventSymbolBuilder : IkvmReflectionSymbolBuilder, IEventSymbolBuilder - { - - readonly IkvmReflectionTypeSymbolBuilder _containingTypeBuilder; - readonly EventBuilder _builder; - IkvmReflectionEventSymbol? _symbol; - - /// - /// Initializes a new instance. - /// - /// - /// - /// - public IkvmReflectionEventSymbolBuilder(IkvmReflectionSymbolContext context, IkvmReflectionTypeSymbolBuilder containingTypeBuilder, EventBuilder builder) : - base(context) - { - _containingTypeBuilder = containingTypeBuilder ?? throw new ArgumentNullException(nameof(containingTypeBuilder)); - _builder = builder ?? throw new ArgumentNullException(nameof(builder)); - } - - /// - internal override IkvmReflectionEventSymbol ReflectionSymbol => _symbol ??= _containingTypeBuilder.ReflectionSymbol.ResolveEventSymbol(_builder); - - /// - public void SetAddOnMethod(IMethodSymbolBuilder mdBuilder) - { - _builder.SetAddOnMethod(((IkvmReflectionMethodSymbolBuilder)mdBuilder).ReflectionBuilder); - } - - /// - public void SetRemoveOnMethod(IMethodSymbolBuilder mdBuilder) - { - _builder.SetRemoveOnMethod(((IkvmReflectionMethodSymbolBuilder)mdBuilder).ReflectionBuilder); - } - - /// - public void SetRaiseMethod(IMethodSymbolBuilder mdBuilder) - { - _builder.SetRaiseMethod(((IkvmReflectionMethodSymbolBuilder)mdBuilder).ReflectionBuilder); - } - - /// - public void AddOtherMethod(IMethodSymbolBuilder mdBuilder) - { - _builder.AddOtherMethod(((IkvmReflectionMethodSymbolBuilder)mdBuilder).ReflectionBuilder); - } - - /// - public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) - { - _builder.SetCustomAttribute(con.Unpack(), binaryAttribute); - } - - /// - public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) - { - _builder.SetCustomAttribute(((IkvmReflectionCustomAttributeBuilder)customBuilder).ReflectionBuilder); - } - - } - -} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionFieldSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionFieldSymbolBuilder.cs deleted file mode 100644 index 75d2bc47c..000000000 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionFieldSymbolBuilder.cs +++ /dev/null @@ -1,88 +0,0 @@ -using System; - -using IKVM.CoreLib.Symbols.Emit; -using IKVM.Reflection.Emit; - -namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit -{ - - class IkvmReflectionFieldSymbolBuilder : IkvmReflectionSymbolBuilder, IFieldSymbolBuilder - { - - readonly IkvmReflectionModuleSymbolBuilder _containingModuleBuilder; - readonly IkvmReflectionTypeSymbolBuilder? _containingTypeBuilder; - readonly FieldBuilder _builder; - IkvmReflectionFieldSymbol? _symbol; - - /// - /// Initializes a new instance. - /// - /// - /// - /// - public IkvmReflectionFieldSymbolBuilder(IkvmReflectionSymbolContext context, IkvmReflectionModuleSymbolBuilder containingModuleBuilder, FieldBuilder builder) : - base(context) - { - _containingModuleBuilder = containingModuleBuilder ?? throw new ArgumentNullException(nameof(containingModuleBuilder)); - _builder = builder ?? throw new ArgumentNullException(nameof(builder)); - } - - /// - /// Initializes a new instance. - /// - /// - /// - /// - public IkvmReflectionFieldSymbolBuilder(IkvmReflectionSymbolContext context, IkvmReflectionTypeSymbolBuilder containingTypeBuilder, FieldBuilder builder) : - base(context) - { - _containingTypeBuilder = containingTypeBuilder ?? throw new ArgumentNullException(nameof(containingTypeBuilder)); - _containingModuleBuilder = containingTypeBuilder.ContainingModuleBuilder; - _builder = builder ?? throw new ArgumentNullException(nameof(builder)); - } - - /// - /// Gets the containing . - /// - internal IkvmReflectionModuleSymbolBuilder ContainingModuleBuilder => _containingModuleBuilder; - - /// - /// Gets the containing . - /// - internal IkvmReflectionTypeSymbolBuilder? ContainingTypeBuilder => _containingTypeBuilder; - - /// - /// Gets the underlying - /// - internal FieldBuilder ReflectionBuilder => _builder; - - /// - internal override IkvmReflectionFieldSymbol ReflectionSymbol => _symbol ??= Context.GetOrCreateFieldSymbol(_builder); - - /// - public void SetConstant(object? defaultValue) - { - _builder.SetConstant(defaultValue); - } - - /// - public void SetOffset(int iOffset) - { - _builder.SetOffset(iOffset); - } - - /// - public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) - { - _builder.SetCustomAttribute(con.Unpack(), binaryAttribute); - } - - /// - public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) - { - _builder.SetCustomAttribute(((IkvmReflectionCustomAttributeBuilder)customBuilder).ReflectionBuilder); - } - - } - -} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodBaseSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodBaseSymbolBuilder.cs deleted file mode 100644 index 1fe558174..000000000 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodBaseSymbolBuilder.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; - -namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit -{ - - abstract class IkvmReflectionMethodBaseSymbolBuilder : IkvmReflectionSymbolBuilder - where TSymbol : ISymbol - where TReflectionSymbol : IkvmReflectionSymbol, TSymbol - { - - readonly IkvmReflectionModuleSymbolBuilder _containingModuleBuilder; - readonly IkvmReflectionTypeSymbolBuilder? _containingTypeBuilder; - - /// - /// Initializes a new instance. - /// - /// - /// - protected IkvmReflectionMethodBaseSymbolBuilder(IkvmReflectionSymbolContext context, IkvmReflectionTypeSymbolBuilder containingTypeBuilder) : - base(context) - { - _containingTypeBuilder = containingTypeBuilder ?? throw new ArgumentNullException(nameof(containingTypeBuilder)); - _containingModuleBuilder = containingTypeBuilder.ContainingModuleBuilder; - } - - /// - /// Initializes a new instance. - /// - /// - /// - protected IkvmReflectionMethodBaseSymbolBuilder(IkvmReflectionSymbolContext context, IkvmReflectionModuleSymbolBuilder containingModuleBuilder) : - base(context) - { - _containingModuleBuilder = containingModuleBuilder ?? throw new ArgumentNullException(nameof(containingModuleBuilder)); - } - - /// - /// Gets the containing . - /// - protected internal IkvmReflectionModuleSymbolBuilder ContainingModuleBuilder => _containingModuleBuilder; - - /// - /// Gets the containing . - /// - protected internal IkvmReflectionTypeSymbolBuilder? ContainingTypeBuilder => _containingTypeBuilder; - - } - -} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodSymbolBuilder.cs deleted file mode 100644 index e01792a35..000000000 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodSymbolBuilder.cs +++ /dev/null @@ -1,107 +0,0 @@ -using System; - -using IKVM.CoreLib.Symbols.Emit; -using IKVM.Reflection; -using IKVM.Reflection.Emit; - -namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit -{ - - class IkvmReflectionMethodSymbolBuilder : IkvmReflectionMethodBaseSymbolBuilder, IMethodSymbolBuilder - { - - readonly MethodBuilder _builder; - IkvmReflectionMethodSymbol? _symbol; - - /// - /// Initializes a new instance. - /// - /// - /// - /// - public IkvmReflectionMethodSymbolBuilder(IkvmReflectionSymbolContext context, IkvmReflectionModuleSymbolBuilder containingModuleBuilder, MethodBuilder builder) : - base(context, containingModuleBuilder) - { - _builder = builder ?? throw new ArgumentNullException(nameof(builder)); - } - - /// - /// Initializes a new instance. - /// - /// - /// - /// - public IkvmReflectionMethodSymbolBuilder(IkvmReflectionSymbolContext context, IkvmReflectionTypeSymbolBuilder containingTypeBuilder, MethodBuilder builder) : - base(context, containingTypeBuilder) - { - _builder = builder ?? throw new ArgumentNullException(nameof(builder)); - } - - /// - /// Gets the that underlies this instance. - /// - internal MethodBuilder ReflectionBuilder => _builder; - - /// - internal override IkvmReflectionMethodSymbol ReflectionSymbol => _symbol ??= Context.GetOrCreateMethodSymbol(_builder); - - /// - public void SetImplementationFlags(System.Reflection.MethodImplAttributes attributes) - { - _builder.SetImplementationFlags((MethodImplAttributes)attributes); - } - - /// - public void SetParameters(params ITypeSymbol[] parameterTypes) - { - _builder.SetParameters(parameterTypes.Unpack()); - } - - /// - public void SetReturnType(ITypeSymbol? returnType) - { - _builder.SetReturnType(returnType?.Unpack()); - } - - /// - public void SetSignature(ITypeSymbol? returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers) - { - _builder.SetSignature(returnType?.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack()); - } - - public IGenericTypeParameterSymbolBuilder[] DefineGenericParameters(params string[] names) - { - throw new NotImplementedException(); - } - - /// - public IParameterSymbolBuilder DefineParameter(int position, System.Reflection.ParameterAttributes attributes, string? strParamName) - { - return new IkvmReflectionParameterSymbolBuilder(Context, this, _builder, _builder.DefineParameter(position, (ParameterAttributes)attributes, strParamName)); - } - - public IILGenerator GetILGenerator() - { - throw new NotImplementedException(); - } - - public IILGenerator GetILGenerator(int size) - { - throw new NotImplementedException(); - } - - /// - public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) - { - _builder.SetCustomAttribute(con.Unpack(), binaryAttribute); - } - - /// - public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) - { - _builder.SetCustomAttribute(((IkvmReflectionCustomAttributeBuilder)customBuilder).ReflectionBuilder); - } - - } - -} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionModuleSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionModuleSymbolBuilder.cs deleted file mode 100644 index 6064c7e88..000000000 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionModuleSymbolBuilder.cs +++ /dev/null @@ -1,98 +0,0 @@ -using System; - -using IKVM.CoreLib.Symbols.Emit; -using IKVM.Reflection; -using IKVM.Reflection.Emit; - -namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit -{ - - class IkvmReflectionModuleSymbolBuilder : IkvmReflectionSymbolBuilder, IModuleSymbolBuilder - { - - readonly ModuleBuilder _builder; - IkvmReflectionModuleSymbol? _symbol; - - /// - /// Initializes a new instance. - /// - /// - /// - public IkvmReflectionModuleSymbolBuilder(IkvmReflectionSymbolContext context, ModuleBuilder builder) : - base(context) - { - _builder = builder ?? throw new ArgumentNullException(nameof(builder)); - } - - /// - internal override IkvmReflectionModuleSymbol ReflectionSymbol => _symbol ??= Context.GetOrCreateModuleSymbol(_builder); - - /// - public ITypeSymbolBuilder DefineType(string name) - { - return new IkvmReflectionTypeSymbolBuilder(Context, this, _builder.DefineType(name)); - } - - /// - public ITypeSymbolBuilder DefineType(string name, System.Reflection.TypeAttributes attr, ITypeSymbol? parent, int typesize) - { - return new IkvmReflectionTypeSymbolBuilder(Context, this, _builder.DefineType(name, (TypeAttributes)attr, parent?.Unpack(), typesize)); - } - - /// - public ITypeSymbolBuilder DefineType(string name, System.Reflection.TypeAttributes attr, ITypeSymbol? parent) - { - return new IkvmReflectionTypeSymbolBuilder(Context, this, _builder.DefineType(name, (TypeAttributes)attr, parent?.Unpack())); - } - - /// - public ITypeSymbolBuilder DefineType(string name, System.Reflection.TypeAttributes attr) - { - return new IkvmReflectionTypeSymbolBuilder(Context, this, _builder.DefineType(name, (TypeAttributes)attr)); - } - - /// - public ITypeSymbolBuilder DefineType(string name, System.Reflection.TypeAttributes attr, ITypeSymbol? parent, System.Reflection.Emit.PackingSize packsize) - { - return new IkvmReflectionTypeSymbolBuilder(Context, this, _builder.DefineType(name, (TypeAttributes)attr, parent?.Unpack(), (PackingSize)packsize)); - } - - /// - public ITypeSymbolBuilder DefineType(string name, System.Reflection.TypeAttributes attr, ITypeSymbol? parent, System.Reflection.Emit.PackingSize packingSize, int typesize) - { - return new IkvmReflectionTypeSymbolBuilder(Context, this, _builder.DefineType(name, (TypeAttributes)attr, parent?.Unpack(), (PackingSize)packingSize, typesize)); - } - - /// - public ITypeSymbolBuilder DefineType(string name, System.Reflection.TypeAttributes attr, ITypeSymbol? parent, ITypeSymbol[]? interfaces) - { - return new IkvmReflectionTypeSymbolBuilder(Context, this, _builder.DefineType(name, (TypeAttributes)attr, parent?.Unpack(), interfaces?.Unpack())); - } - - /// - public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) - { - _builder.SetCustomAttribute(con.Unpack(), binaryAttribute); - } - - /// - public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) - { - _builder.SetCustomAttribute(((IkvmReflectionCustomAttributeBuilder)customBuilder).ReflectionBuilder); - } - - /// - public void Complete() - { - _builder.CreateGlobalFunctions(); - - foreach (var type in _builder.GetTypes()) - if (type is TypeBuilder typeBuilder) - if (typeBuilder.IsCreated() == false) - if (typeBuilder.CreateType() is { } t) - ReflectionSymbol.ResolveTypeSymbol(t).Complete(t); - } - - } - -} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterBuilderInfo.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterBuilderInfo.cs deleted file mode 100644 index 66e07f7e0..000000000 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterBuilderInfo.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System; - -using IKVM.Reflection; -using IKVM.Reflection.Emit; - -using Type = IKVM.Reflection.Type; - -namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit -{ - - /// - /// Fake implementation that wraps a , which does not extend . - /// - class IkvmReflectionParameterBuilderInfo : ParameterInfo - { - - readonly MemberInfo _member; - readonly ParameterBuilder _parameter; - - /// - /// Initialies a new instance. - /// - /// - /// - /// - public IkvmReflectionParameterBuilderInfo(MemberInfo member, ParameterBuilder parameter) - { - _member = member ?? throw new ArgumentNullException(nameof(member)); - _parameter = parameter ?? throw new ArgumentNullException(nameof(parameter)); - } - - /// - public override ParameterAttributes Attributes => (ParameterAttributes)_parameter.Attributes; - - /// - public override Module Module => _member.Module; - - /// - public override MemberInfo Member => _member; - - /// - public override string? Name => _parameter.Name; - - /// - public override int Position => _parameter.Position; - - /// - public override int MetadataToken => throw new NotImplementedException(); - - /// - public override Type ParameterType => throw new NotImplementedException(); - - /// - public override object RawDefaultValue => throw new NotImplementedException(); - - public override CustomModifiers __GetCustomModifiers() - { - throw new NotSupportedException(); - } - - public override bool __TryGetFieldMarshal(out FieldMarshal fieldMarshal) - { - throw new NotSupportedException(); - } - - } - -} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterSymbolBuilder.cs deleted file mode 100644 index 21ba94fa2..000000000 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterSymbolBuilder.cs +++ /dev/null @@ -1,106 +0,0 @@ -using System; - -using IKVM.CoreLib.Symbols.Emit; -using IKVM.Reflection; -using IKVM.Reflection.Emit; - -namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit -{ - - abstract class IkvmReflectionParameterSymbolBuilder : IkvmReflectionSymbolBuilder, IParameterSymbolBuilder - { - - readonly MemberInfo _member; - readonly ParameterBuilder _builder; - readonly IkvmReflectionParameterBuilderInfo _info; - IkvmReflectionParameterSymbol? _symbol; - - object? _constant; - - /// - /// Initializes a new instance. - /// - /// - protected IkvmReflectionParameterSymbolBuilder(IkvmReflectionSymbolContext context, MemberInfo member, ParameterBuilder builder) : - base(context) - { - _member = member ?? throw new ArgumentNullException(nameof(member)); - _builder = builder ?? throw new ArgumentNullException(nameof(builder)); - _info = new IkvmReflectionParameterBuilderInfo(_member, _builder); - } - - /// - /// Gets the wrapped . - /// - internal ParameterBuilder ReflectionBuilder => _builder; - - /// - internal override IkvmReflectionParameterSymbol ReflectionSymbol => _symbol ??= GetOrCreateSymbol(_info); - - /// - /// Gets or creates the . - /// - /// - protected internal abstract IkvmReflectionParameterSymbol GetOrCreateSymbol(IkvmReflectionParameterBuilderInfo info); - - /// - public void SetConstant(object? defaultValue) - { - _builder.SetConstant(_constant = defaultValue); - } - - /// - /// Saves the constant value so it can be retrieved as a symbol. - /// - /// - internal object? GetConstant() - { - return _constant; - } - - /// - public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) - { - _builder.SetCustomAttribute(con.Unpack(), binaryAttribute); - } - - /// - public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) - { - _builder.SetCustomAttribute(((IkvmReflectionCustomAttributeBuilder)customBuilder).ReflectionBuilder); - } - - } - - class IkvmReflectionParameterSymbolBuilder : IkvmReflectionParameterSymbolBuilder - where TContainingSymbol : IMethodBaseSymbol - where TContainingReflectionSymbol : IkvmReflectionMethodBaseSymbol, TContainingSymbol - where TContainingBuilder : IkvmReflectionMethodBaseSymbolBuilder - { - - readonly TContainingBuilder _containingMethodBuilder; - - /// - /// Initializes a new instance. - /// - /// - /// - /// - /// - public IkvmReflectionParameterSymbolBuilder(IkvmReflectionSymbolContext context, TContainingBuilder containingMethodBuilder, MemberInfo member, ParameterBuilder builder) : - base(context, member, builder) - { - _containingMethodBuilder = containingMethodBuilder ?? throw new ArgumentNullException(nameof(containingMethodBuilder)); - } - - /// - /// Gets the containing . - /// - internal TContainingBuilder ContainingMethodBuilder => _containingMethodBuilder; - - /// - protected internal override IkvmReflectionParameterSymbol GetOrCreateSymbol(IkvmReflectionParameterBuilderInfo info) => ContainingMethodBuilder.ReflectionSymbol.ResolveParameterSymbol(info); - - } - -} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs deleted file mode 100644 index 239580c9b..000000000 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs +++ /dev/null @@ -1,196 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Reflection.Metadata.Ecma335; -using System.Threading; - -using IKVM.CoreLib.Collections; -using IKVM.CoreLib.Reflection; -using IKVM.CoreLib.Threading; - -using Assembly = IKVM.Reflection.Assembly; -using Module = IKVM.Reflection.Module; -using Type = IKVM.Reflection.Type; - -namespace IKVM.CoreLib.Symbols.IkvmReflection -{ - - class IkvmReflectionAssemblySymbol : IkvmReflectionSymbol, IAssemblySymbol - { - - Assembly _assembly; - System.Reflection.AssemblyName? _assemblyName; - - IndexRangeDictionary _moduleSymbols = new(initialCapacity: 1, maxCapacity: 32); - ReaderWriterLockSlim? _moduleLock; - - /// - /// Initializes a new instance. - /// - /// - /// - public IkvmReflectionAssemblySymbol(IkvmReflectionSymbolContext context, Assembly assembly) : - base(context) - { - _assembly = assembly ?? throw new ArgumentNullException(nameof(assembly)); - } - - internal Assembly ReflectionObject => _assembly; - - /// - /// Gets or creates the cached for the module. - /// - /// - /// - /// - internal IkvmReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) - { - if (module is null) - throw new ArgumentNullException(nameof(module)); - - Debug.Assert(AssemblyNameEqualityComparer.Instance.Equals(module.Assembly.GetName().ToAssemblyName(), _assembly.GetName().ToAssemblyName())); - - // create lock on demand - if (_moduleLock == null) - Interlocked.CompareExchange(ref _moduleLock, new ReaderWriterLockSlim(), null); - - using (_moduleLock.CreateUpgradeableReadLock()) - { - var row = MetadataTokens.GetRowNumber(MetadataTokens.ModuleReferenceHandle(module.MetadataToken)); - if (_moduleSymbols[row] == null) - using (_moduleLock.CreateWriteLock()) - return _moduleSymbols[row] ??= new IkvmReflectionModuleSymbol(Context, this, module); - else - return _moduleSymbols[row] ?? throw new InvalidOperationException(); - } - } - - /// - public IEnumerable DefinedTypes => ResolveTypeSymbols(_assembly.DefinedTypes); - - /// - public IMethodSymbol? EntryPoint => _assembly.EntryPoint is { } m ? ResolveMethodSymbol(m) : null; - - /// - public IEnumerable ExportedTypes => ResolveTypeSymbols(_assembly.ExportedTypes); - - /// - public string? FullName => _assembly.FullName; - - /// - public string ImageRuntimeVersion => _assembly.ImageRuntimeVersion; - - /// - public IModuleSymbol ManifestModule => ResolveModuleSymbol(_assembly.ManifestModule); - - /// - public IEnumerable Modules => ResolveModuleSymbols(_assembly.Modules); - - /// - public ITypeSymbol[] GetExportedTypes() - { - return ResolveTypeSymbols(_assembly.GetExportedTypes()); - } - - /// - public IModuleSymbol? GetModule(string name) - { - return _assembly.GetModule(name) is Module m ? GetOrCreateModuleSymbol(m) : null; - } - - /// - public IModuleSymbol[] GetModules() - { - return ResolveModuleSymbols(_assembly.GetModules()); - } - - /// - public IModuleSymbol[] GetModules(bool getResourceModules) - { - return ResolveModuleSymbols(_assembly.GetModules(getResourceModules)); - } - - /// - public System.Reflection.AssemblyName GetName() - { - return _assemblyName ??= _assembly.GetName().ToAssemblyName(); - } - - /// - public System.Reflection.AssemblyName GetName(bool copiedName) - { - return _assembly.GetName().ToAssemblyName(); - } - - /// - public System.Reflection.AssemblyName[] GetReferencedAssemblies() - { - var l = _assembly.GetReferencedAssemblies(); - var a = new System.Reflection.AssemblyName[l.Length]; - for (int i = 0; i < l.Length; i++) - a[i] = l[i].ToAssemblyName(); - - return a; - } - - /// - public ITypeSymbol? GetType(string name, bool throwOnError) - { - return _assembly.GetType(name, throwOnError) is Type t ? Context.GetOrCreateTypeSymbol(t) : null; - } - - /// - public ITypeSymbol? GetType(string name, bool throwOnError, bool ignoreCase) - { - return _assembly.GetType(name, throwOnError, ignoreCase) is Type t ? Context.GetOrCreateTypeSymbol(t) : null; - } - - /// - public ITypeSymbol? GetType(string name) - { - return _assembly.GetType(name) is Type t ? Context.GetOrCreateTypeSymbol(t) : null; - } - - /// - public ITypeSymbol[] GetTypes() - { - return ResolveTypeSymbols(_assembly.GetTypes()); - } - - /// - public CustomAttribute[] GetCustomAttributes(bool inherit = false) - { - return ResolveCustomAttributes(_assembly.GetCustomAttributesData()); - } - - /// - public CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) - { - return ResolveCustomAttributes(_assembly.GetCustomAttributesData().Where(i => i.AttributeType == ((IkvmReflectionTypeSymbol)attributeType).ReflectionObject)); - } - - /// - public CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) - { - return GetCustomAttributes(attributeType, inherit).FirstOrDefault(); - } - - /// - public bool IsDefined(ITypeSymbol attributeType, bool inherit = false) - { - return _assembly.IsDefined(((IkvmReflectionTypeSymbol)attributeType).ReflectionObject, false); - } - - /// - /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. - /// - /// - internal void Complete(Assembly assembly) - { - Context.GetOrCreateAssemblySymbol(_assembly = assembly); - } - - } - -} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionConstructorSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionConstructorSymbol.cs deleted file mode 100644 index a991bdfa5..000000000 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionConstructorSymbol.cs +++ /dev/null @@ -1,37 +0,0 @@ -using ConstructorInfo = IKVM.Reflection.ConstructorInfo; - -namespace IKVM.CoreLib.Symbols.IkvmReflection -{ - - class IkvmReflectionConstructorSymbol : IkvmReflectionMethodBaseSymbol, IConstructorSymbol - { - - /// - /// Initializes a new instance. - /// - /// - /// - /// - public IkvmReflectionConstructorSymbol(IkvmReflectionSymbolContext context, IkvmReflectionTypeSymbol type, ConstructorInfo ctor) : - base(context, type, ctor) - { - - } - - /// - /// Gets the underlying wrapped by this symbol. - /// - internal new ConstructorInfo ReflectionObject => (ConstructorInfo)base.ReflectionObject; - - /// - /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. - /// - /// - internal void Complete(ConstructorInfo type) - { - base.Complete(type); - } - - } - -} \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionEventSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionEventSymbol.cs deleted file mode 100644 index f3e8e9546..000000000 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionEventSymbol.cs +++ /dev/null @@ -1,108 +0,0 @@ -using System; - -using EventInfo = IKVM.Reflection.EventInfo; - -namespace IKVM.CoreLib.Symbols.IkvmReflection -{ - - class IkvmReflectionEventSymbol : IkvmReflectionMemberSymbol, IEventSymbol - { - - EventInfo _event; - - /// - /// Initializes a new instance. - /// - /// - /// - /// - public IkvmReflectionEventSymbol(IkvmReflectionSymbolContext context, IkvmReflectionTypeSymbol type, EventInfo @event) : - base(context, type, @event) - { - _event = @event ?? throw new ArgumentNullException(nameof(@event)); - } - - /// - /// Gets the underlying wrapped by this symbol. - /// - internal new EventInfo ReflectionObject => _event; - - /// - public System.Reflection.EventAttributes Attributes => (System.Reflection.EventAttributes)_event.Attributes; - - /// - public ITypeSymbol? EventHandlerType => _event.EventHandlerType is { } m ? ResolveTypeSymbol(m) : null; - - /// - public bool IsSpecialName => _event.IsSpecialName; - - /// - public IMethodSymbol? AddMethod => _event.AddMethod is { } m ? ResolveMethodSymbol(m) : null; - - /// - public IMethodSymbol? RemoveMethod => _event.RemoveMethod is { } m ? ResolveMethodSymbol(m) : null; - - /// - public IMethodSymbol? RaiseMethod => _event.RaiseMethod is { } m ? ResolveMethodSymbol(m) : null; - - /// - public IMethodSymbol? GetAddMethod() - { - return _event.GetAddMethod() is { } m ? ResolveMethodSymbol(m) : null; - } - - /// - public IMethodSymbol? GetAddMethod(bool nonPublic) - { - return _event.GetAddMethod(nonPublic) is { } m ? ResolveMethodSymbol(m) : null; - } - - /// - public IMethodSymbol? GetRemoveMethod() - { - return _event.GetRemoveMethod() is { } m ? ResolveMethodSymbol(m) : null; - } - - /// - public IMethodSymbol? GetRemoveMethod(bool nonPublic) - { - return _event.GetRemoveMethod(nonPublic) is { } m ? ResolveMethodSymbol(m) : null; - } - - /// - public IMethodSymbol? GetRaiseMethod() - { - return _event.GetRaiseMethod() is { } m ? ResolveMethodSymbol(m) : null; - } - - /// - public IMethodSymbol? GetRaiseMethod(bool nonPublic) - { - return _event.GetRaiseMethod(nonPublic) is { } m ? ResolveMethodSymbol(m) : null; - } - - /// - public IMethodSymbol[] GetOtherMethods() - { - return ResolveMethodSymbols(_event.GetOtherMethods()); - } - - /// - public IMethodSymbol[] GetOtherMethods(bool nonPublic) - { - return ResolveMethodSymbols(_event.GetOtherMethods(nonPublic)); - } - - /// - /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. - /// - /// - internal void Complete(EventInfo @event) - { - ResolveEventSymbol(_event = @event); - base.Complete(_event); - } - - } - -} \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionFieldSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionFieldSymbol.cs deleted file mode 100644 index 4e9448e3e..000000000 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionFieldSymbol.cs +++ /dev/null @@ -1,116 +0,0 @@ -using System; - -using FieldInfo = IKVM.Reflection.FieldInfo; - -namespace IKVM.CoreLib.Symbols.IkvmReflection -{ - - class IkvmReflectionFieldSymbol : IkvmReflectionMemberSymbol, IFieldSymbol - { - - FieldInfo _field; - - /// - /// Initializes a new instance. - /// - /// - /// - /// - public IkvmReflectionFieldSymbol(IkvmReflectionSymbolContext context, IkvmReflectionModuleSymbol containingModule, FieldInfo field) : - base(context, containingModule, field) - { - _field = field ?? throw new ArgumentNullException(nameof(field)); - } - - /// - /// Initializes a new instance. - /// - /// - /// - /// - public IkvmReflectionFieldSymbol(IkvmReflectionSymbolContext context, IkvmReflectionTypeSymbol containingType, FieldInfo field) : - base(context, containingType, field) - { - _field = field ?? throw new ArgumentNullException(nameof(field)); - } - - /// - /// Gets the underlying wrapped by this symbol. - /// - internal new FieldInfo ReflectionObject => (FieldInfo)base.ReflectionObject; - - /// - public System.Reflection.FieldAttributes Attributes => (System.Reflection.FieldAttributes)_field.Attributes; - - /// - public ITypeSymbol FieldType => ResolveTypeSymbol(_field.FieldType); - - /// - public bool IsSpecialName => _field.IsSpecialName; - - /// - public bool IsAssembly => _field.IsAssembly; - - /// - public bool IsFamily => _field.IsFamily; - - /// - public bool IsFamilyAndAssembly => _field.IsFamilyAndAssembly; - - /// - public bool IsFamilyOrAssembly => _field.IsFamilyOrAssembly; - - /// - public bool IsInitOnly => _field.IsInitOnly; - - /// - public bool IsLiteral => _field.IsLiteral; - -#pragma warning disable SYSLIB0050 // Type or member is obsolete - /// - public bool IsNotSerialized => _field.IsNotSerialized; -#pragma warning restore SYSLIB0050 // Type or member is obsolete - - /// - public bool IsPinvokeImpl => _field.IsPinvokeImpl; - - /// - public bool IsPrivate => _field.IsPrivate; - - /// - public bool IsPublic => _field.IsPublic; - - /// - public bool IsStatic => _field.IsStatic; - - /// - public ITypeSymbol[] GetOptionalCustomModifiers() - { - return ResolveTypeSymbols(_field.GetOptionalCustomModifiers()); - } - - /// - public ITypeSymbol[] GetRequiredCustomModifiers() - { - return ResolveTypeSymbols(_field.GetRequiredCustomModifiers()); - } - - /// - public object? GetRawConstantValue() - { - return _field.GetRawConstantValue(); - } - - /// - /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. - /// - /// - internal void Complete(FieldInfo field) - { - ResolveFieldSymbol(_field = field); - base.Complete(_field); - } - - } - -} \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs deleted file mode 100644 index 654f92805..000000000 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs +++ /dev/null @@ -1,275 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -using ConstructorInfo = IKVM.Reflection.ConstructorInfo; -using EventInfo = IKVM.Reflection.EventInfo; -using FieldInfo = IKVM.Reflection.FieldInfo; -using MemberInfo = IKVM.Reflection.MemberInfo; -using MethodInfo = IKVM.Reflection.MethodInfo; -using PropertyInfo = IKVM.Reflection.PropertyInfo; -using Type = IKVM.Reflection.Type; - -namespace IKVM.CoreLib.Symbols.IkvmReflection -{ - - /// - /// Obtains information about the attributes of a member and provides access to member metadata. - /// - abstract class IkvmReflectionMemberSymbol : IkvmReflectionSymbol, IMemberSymbol - { - - /// - /// Concatinates the list of arrays. - /// - /// - /// - static T[] Concat(List? list) - { - if (list == null) - return []; - - var c = 0; - foreach (var i in list) - c += i.Length; - - if (c == 0) - return []; - - var t = 0; - var a = new T[c]; - foreach (var i in list) - { - Array.Copy(i, 0, a, t, i.Length); - t += i.Length; - } - - return a; - } - - readonly IkvmReflectionModuleSymbol _containingModule; - readonly IkvmReflectionTypeSymbol? _containingType; - MemberInfo _member; - - CustomAttribute[]? _customAttributes; - CustomAttribute[]? _inheritedCustomAttributes; - - /// - /// Initializes a new instance. - /// - /// - /// - /// - public IkvmReflectionMemberSymbol(IkvmReflectionSymbolContext context, IkvmReflectionModuleSymbol containingModule, MemberInfo member) : - base(context) - { - _containingModule = containingModule ?? throw new ArgumentNullException(nameof(containingModule)); - _member = member ?? throw new ArgumentNullException(nameof(member)); - } - - /// - /// Initializes a new instance. - /// - /// - /// - /// - public IkvmReflectionMemberSymbol(IkvmReflectionSymbolContext context, IkvmReflectionTypeSymbol containingType, MemberInfo member) : - this(context, containingType.ContainingModule, member) - { - _containingType = containingType ?? throw new ArgumentNullException(nameof(containingType)); - } - - /// - /// Resolves the symbol for the specified type. - /// - /// - /// - protected internal override IkvmReflectionTypeSymbol ResolveTypeSymbol(Type type) - { - if (_containingType != null && type == _containingType.ReflectionObject) - return _containingType; - else if (type.Module == _member.Module) - return _containingModule.GetOrCreateTypeSymbol(type); - else - return base.ResolveTypeSymbol(type); - } - - /// - /// Resolves the symbol for the specified constructor. - /// - /// - /// - protected internal override IkvmReflectionConstructorSymbol ResolveConstructorSymbol(ConstructorInfo ctor) - { - if (ctor.Module == _member.Module) - return _containingModule.GetOrCreateConstructorSymbol(ctor); - else - return base.ResolveConstructorSymbol(ctor); - } - - /// - /// Resolves the symbol for the specified method. - /// - /// - /// - protected internal override IkvmReflectionMethodSymbol ResolveMethodSymbol(MethodInfo method) - { - if (method.Module == _member.Module) - return _containingModule.GetOrCreateMethodSymbol(method); - else - return base.ResolveMethodSymbol(method); - } - - /// - /// Resolves the symbol for the specified field. - /// - /// - /// - protected internal override IkvmReflectionFieldSymbol ResolveFieldSymbol(FieldInfo field) - { - if (field.Module == _member.Module) - return _containingModule.GetOrCreateFieldSymbol(field); - else - return base.ResolveFieldSymbol(field); - } - - - /// - /// Resolves the symbol for the specified field. - /// - /// - /// - protected internal override IkvmReflectionPropertySymbol ResolvePropertySymbol(PropertyInfo property) - { - if (property.Module == _member.Module) - return _containingModule.GetOrCreatePropertySymbol(property); - else - return base.ResolvePropertySymbol(property); - } - - /// - /// Resolves the symbol for the specified event. - /// - /// - /// - protected internal override IkvmReflectionEventSymbol ResolveEventSymbol(EventInfo @event) - { - if (@event.Module == _member.Module) - return _containingModule.GetOrCreateEventSymbol(@event); - else - return base.ResolveEventSymbol(@event); - } - - /// - /// Gets the underlying wrapped by this symbol. - /// - internal MemberInfo ReflectionObject => _member; - - /// - /// Gets the which contains the metadata of this member. - /// - internal IkvmReflectionModuleSymbol ContainingModule => _containingModule; - - /// - /// Gets the which contains the metadata of this member, or null if the member is not a member of a type. - /// - internal IkvmReflectionTypeSymbol? ContainingType => _containingType; - - /// - public virtual IModuleSymbol Module => Context.GetOrCreateModuleSymbol(_member.Module); - - /// - public virtual ITypeSymbol? DeclaringType => _member.DeclaringType is { } t ? Context.GetOrCreateTypeSymbol(t) : null; - - /// - public virtual System.Reflection.MemberTypes MemberType => (System.Reflection.MemberTypes)_member.MemberType; - - /// - public virtual int MetadataToken => _member.MetadataToken; - - /// - public virtual string Name => _member.Name; - - /// - public virtual CustomAttribute[] GetCustomAttributes(bool inherit = false) - { - if (inherit) - { - // check that we've already processed this - if (_inheritedCustomAttributes != null) - return _inheritedCustomAttributes; - - var self = _member; - var list = default(List?); - for (; ; ) - { - // get attribute for current member and append to list - var attr = ResolveMemberSymbol(self).GetCustomAttributes(false); - if (attr.Length > 0) - { - list ??= []; - list.Add(attr); - } - - var type = self as Type; - if (type != null) - { - type = type.BaseType; - if (type == null) - return _inheritedCustomAttributes ??= Concat(list); - - self = type; - continue; - } - - var method = self as MethodInfo; - if (method != null) - { - var prev = self; - method = method.GetBaseDefinition(); - if (method == null || method == prev) - return _inheritedCustomAttributes ??= Concat(list); - - self = method; - continue; - } - - return _inheritedCustomAttributes ??= Concat(list); - } - } - - return _customAttributes ??= ResolveCustomAttributes(_member.GetCustomAttributesData()); - } - - /// - public virtual CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) - { - return GetCustomAttributes(inherit).Where(i => i.AttributeType == attributeType).ToArray(); - } - - /// - public virtual CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) - { - return GetCustomAttributes(attributeType, inherit).FirstOrDefault(); - } - - /// - public virtual bool IsDefined(ITypeSymbol attributeType, bool inherit = false) - { - return _member.IsDefined(((IkvmReflectionTypeSymbol)attributeType).ReflectionObject, inherit); - } - - /// - /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. - /// - /// - protected void Complete(MemberInfo member) - { - ResolveMemberSymbol(_member = member); - _customAttributes = null; - _inheritedCustomAttributes = null; - } - - } - -} \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodBaseSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodBaseSymbol.cs deleted file mode 100644 index 20f097683..000000000 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodBaseSymbol.cs +++ /dev/null @@ -1,133 +0,0 @@ -using System; - -using MethodBase = IKVM.Reflection.MethodBase; - -namespace IKVM.CoreLib.Symbols.IkvmReflection -{ - - abstract class IkvmReflectionMethodBaseSymbol : IkvmReflectionMemberSymbol, IMethodBaseSymbol - { - - MethodBase _method; - - /// - /// Initializes a new instance. - /// - /// - /// - /// - public IkvmReflectionMethodBaseSymbol(IkvmReflectionSymbolContext context, IkvmReflectionModuleSymbol module, MethodBase method) : - base(context, module, method) - { - _method = method ?? throw new ArgumentNullException(nameof(method)); - } - - /// - /// Initializes a new instance. - /// - /// - /// - /// - public IkvmReflectionMethodBaseSymbol(IkvmReflectionSymbolContext context, IkvmReflectionTypeSymbol type, MethodBase method) : - this(context, type.ContainingModule, method) - { - - } - - /// - /// Gets the underlying wrapped by this symbol. - /// - internal new MethodBase ReflectionObject => _method; - - /// - public System.Reflection.MethodAttributes Attributes => (System.Reflection.MethodAttributes)_method.Attributes; - - /// - public System.Reflection.CallingConventions CallingConvention => (System.Reflection.CallingConventions)_method.CallingConvention; - - /// - public bool ContainsGenericParameters => _method.ContainsGenericParameters; - - /// - public bool IsAbstract => _method.IsAbstract; - - /// - public bool IsAssembly => _method.IsAssembly; - - /// - public bool IsConstructor => _method.IsConstructor; - - /// - public bool IsFamily => _method.IsFamily; - - /// - public bool IsFamilyAndAssembly => _method.IsFamilyAndAssembly; - - /// - public bool IsFamilyOrAssembly => _method.IsFamilyOrAssembly; - - /// - public bool IsFinal => _method.IsFinal; - - /// - public bool IsGenericMethod => _method.IsGenericMethod; - - /// - public bool IsGenericMethodDefinition => _method.IsGenericMethodDefinition; - - /// - public bool IsHideBySig => _method.IsHideBySig; - - /// - public bool IsPrivate => _method.IsPrivate; - - /// - public bool IsPublic => _method.IsPublic; - - /// - public bool IsStatic => _method.IsStatic; - - /// - public bool IsVirtual => _method.IsVirtual; - - /// - public bool IsSpecialName => _method.IsSpecialName; - - /// - public System.Reflection.MethodImplAttributes MethodImplementationFlags => (System.Reflection.MethodImplAttributes)_method.MethodImplementationFlags; - - /// - public ITypeSymbol[] GetGenericArguments() - { - return ResolveTypeSymbols(_method.GetGenericArguments()); - } - - /// - public System.Reflection.MethodImplAttributes GetMethodImplementationFlags() - { - return (System.Reflection.MethodImplAttributes)_method.GetMethodImplementationFlags(); - } - - /// - public IParameterSymbol[] GetParameters() - { - return ResolveParameterSymbols(_method.GetParameters()); - } - - /// - /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. - /// - /// - internal void Complete(MethodBase method) - { - ResolveMethodBaseSymbol(_method = method); - base.Complete(_method); - - foreach (var i in _method.GetParameters()) - ResolveParameterSymbol(i).Complete(i); - - } - - } - -} \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodSymbol.cs deleted file mode 100644 index 472021fa7..000000000 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodSymbol.cs +++ /dev/null @@ -1,71 +0,0 @@ -using System; - -using MethodInfo = IKVM.Reflection.MethodInfo; - -namespace IKVM.CoreLib.Symbols.IkvmReflection -{ - - class IkvmReflectionMethodSymbol : IkvmReflectionMethodBaseSymbol, IMethodSymbol - { - - readonly MethodInfo _method; - - /// - /// Initializes a new instance. - /// - /// - /// - /// - public IkvmReflectionMethodSymbol(IkvmReflectionSymbolContext context, IkvmReflectionModuleSymbol module, MethodInfo method) : - base(context, module, method) - { - _method = method ?? throw new ArgumentNullException(nameof(method)); - } - - /// - /// Initializes a new instance. - /// - /// - /// - /// - public IkvmReflectionMethodSymbol(IkvmReflectionSymbolContext context, IkvmReflectionTypeSymbol type, MethodInfo method) : - this(context, type.ContainingModule, method) - { - - } - - /// - /// Gets the underlying wrapped by this symbol. - /// - internal new MethodInfo ReflectionObject => _method; - - /// - public IParameterSymbol ReturnParameter => ResolveParameterSymbol(_method.ReturnParameter); - - /// - public ITypeSymbol ReturnType => ResolveTypeSymbol(_method.ReturnType); - - /// - public ICustomAttributeProvider ReturnTypeCustomAttributes => throw new NotImplementedException(); - - /// - public IMethodSymbol GetBaseDefinition() - { - return ResolveMethodSymbol(_method.GetBaseDefinition()); - } - - /// - public IMethodSymbol GetGenericMethodDefinition() - { - return ResolveMethodSymbol(_method.GetGenericMethodDefinition()); - } - - /// - public IMethodSymbol MakeGenericMethod(params ITypeSymbol[] typeArguments) - { - return ResolveMethodSymbol(_method.MakeGenericMethod(typeArguments.Unpack())); - } - - } - -} \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs deleted file mode 100644 index e1ad04c5d..000000000 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs +++ /dev/null @@ -1,587 +0,0 @@ -using System; -using System.Diagnostics; -using System.Linq; -using System.Reflection.Metadata.Ecma335; -using System.Threading; - -using IKVM.CoreLib.Collections; -using IKVM.CoreLib.Threading; -using IKVM.Reflection; - -using Module = IKVM.Reflection.Module; -using Type = IKVM.Reflection.Type; - -namespace IKVM.CoreLib.Symbols.IkvmReflection -{ - - /// - /// Implementation of derived from System.Reflection. - /// - class IkvmReflectionModuleSymbol : IkvmReflectionSymbol, IModuleSymbol - { - - /// - /// Returns true if the given is a TypeDef. That is, not a modified or substituted or generic parameter type. - /// - /// - /// - static bool IsTypeDefinition(Type type) - { - return type.HasElementType == false && type.IsConstructedGenericType == false && type.IsGenericParameter == false; - } - - const int MAX_CAPACITY = 65536 * 2; - - const BindingFlags DefaultBindingFlags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance; - - readonly IkvmReflectionAssemblySymbol _containingAssembly; - Module _module; - - IndexRangeDictionary _typeTable = new(maxCapacity: MAX_CAPACITY); - IndexRangeDictionary _typeSymbols = new(maxCapacity: MAX_CAPACITY); - ReaderWriterLockSlim? _typeLock; - - IndexRangeDictionary _methodTable = new(maxCapacity: MAX_CAPACITY); - IndexRangeDictionary _methodSymbols = new(maxCapacity: MAX_CAPACITY); - ReaderWriterLockSlim? _methodLock; - - IndexRangeDictionary _fieldTable = new(maxCapacity: MAX_CAPACITY); - IndexRangeDictionary _fieldSymbols = new(maxCapacity: MAX_CAPACITY); - ReaderWriterLockSlim? _fieldLock; - - IndexRangeDictionary _propertyTable = new(maxCapacity: MAX_CAPACITY); - IndexRangeDictionary _propertySymbols = new(maxCapacity: MAX_CAPACITY); - ReaderWriterLockSlim? _propertyLock; - - IndexRangeDictionary _eventTable = new(maxCapacity: MAX_CAPACITY); - IndexRangeDictionary _eventSymbols = new(maxCapacity: MAX_CAPACITY); - ReaderWriterLockSlim? _eventLock; - - IndexRangeDictionary _parameterTable = new(maxCapacity: MAX_CAPACITY); - IndexRangeDictionary _parameterSymbols = new(maxCapacity: MAX_CAPACITY); - ReaderWriterLockSlim? _parameterLock; - - IndexRangeDictionary _genericParameterSymbols = new(maxCapacity: MAX_CAPACITY); - ReaderWriterLockSlim? _genericParameterLock; - - /// - /// Initializes a new instance. - /// - /// - /// - /// - /// - public IkvmReflectionModuleSymbol(IkvmReflectionSymbolContext context, IkvmReflectionAssemblySymbol containingAssembly, Module module) : - base(context) - { - _containingAssembly = containingAssembly ?? throw new ArgumentNullException(nameof(containingAssembly)); - _module = module ?? throw new ArgumentNullException(nameof(module)); - } - - /// - /// Gets the which contains the metadata of this member. - /// - internal IkvmReflectionAssemblySymbol ContainingAssembly => _containingAssembly; - - /// - /// Gets the wrapped . - /// - internal Module ReflectionObject => _module; - - /// - /// Gets or creates the cached for the module by type. - /// - /// - /// - /// - internal IkvmReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) - { - if (type is null) - throw new ArgumentNullException(nameof(type)); - - Debug.Assert(type.Module == _module); - - // type is a generic parameter (GenericParam) - if (type.IsGenericParameter) - return GetOrCreateGenericParameterSymbol(type); - - // type is not a type definition (TypeDef) - if (IsTypeDefinition(type) == false) - return GetOrCreateTypeSymbolForSpecification(type); - - // create lock on demand - if (_typeLock == null) - Interlocked.CompareExchange(ref _typeLock, new ReaderWriterLockSlim(), null); - - using (_typeLock.CreateUpgradeableReadLock()) - { - var row = MetadataTokens.GetRowNumber(MetadataTokens.TypeDefinitionHandle(type.MetadataToken)); - if (_typeTable[row] != type) - using (_typeLock.CreateWriteLock()) - _typeTable[row] = type; - - if (_typeSymbols[row] == null) - using (_typeLock.CreateWriteLock()) - return _typeSymbols[row] ??= new IkvmReflectionTypeSymbol(Context, this, type); - else - return _typeSymbols[row] ?? throw new InvalidOperationException(); - } - } - - /// - /// Gets or creates a for the specification type: array, pointer, etc. - /// - /// - /// - /// - /// - IkvmReflectionTypeSymbol GetOrCreateTypeSymbolForSpecification(Type type) - { - if (type is null) - throw new ArgumentNullException(nameof(type)); - - Debug.Assert(type.Module == _module); - - if (type.GetElementType() is { } elementType) - { - var elementTypeSymbol = ResolveTypeSymbol(elementType); - - // handles both SZ arrays and normal arrays - if (type.IsArray) - return (IkvmReflectionTypeSymbol)elementTypeSymbol.MakeArrayType(type.GetArrayRank()); - - if (type.IsPointer) - return (IkvmReflectionTypeSymbol)elementTypeSymbol.MakePointerType(); - - if (type.IsByRef) - return (IkvmReflectionTypeSymbol)elementTypeSymbol.MakeByRefType(); - - throw new InvalidOperationException(); - } - - if (type.IsGenericType) - { - var definitionTypeSymbol = ResolveTypeSymbol(type.GetGenericTypeDefinition()); - return definitionTypeSymbol.GetOrCreateGenericTypeSymbol(ResolveTypeSymbols(type.GetGenericArguments())); - } - - throw new InvalidOperationException(); - } - - /// - /// Gets or creates the cached fqor the type by method. - /// - /// - /// - internal IkvmReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method) - { - if (method is null) - throw new ArgumentNullException(nameof(method)); - - Debug.Assert(method.Module.MetadataToken == _module.MetadataToken); - - // create lock on demand - if (_methodLock == null) - Interlocked.CompareExchange(ref _methodLock, new ReaderWriterLockSlim(), null); - - using (_methodLock.CreateUpgradeableReadLock()) - { - var row = MetadataTokens.GetRowNumber(MetadataTokens.MethodDefinitionHandle(method.MetadataToken)); - if (_methodTable[row] != method) - using (_methodLock.CreateWriteLock()) - _methodTable[row] = method; - - if (_methodSymbols[row] == null) - using (_methodLock.CreateWriteLock()) - if (method is ConstructorInfo c) - return _methodSymbols[row] ??= new IkvmReflectionConstructorSymbol(Context, ResolveTypeSymbol(c.DeclaringType ?? throw new InvalidOperationException()), c); - else if (method is MethodInfo m) - if (method.DeclaringType is { } dt) - return _methodSymbols[row] ??= new IkvmReflectionMethodSymbol(Context, ResolveTypeSymbol(dt), m); - else - return _methodSymbols[row] ??= new IkvmReflectionMethodSymbol(Context, this, m); - else - throw new InvalidOperationException(); - else - return _methodSymbols[row] ?? throw new InvalidOperationException(); - } - } - - /// - /// Gets or creates the cached for the type by ctor. - /// - /// - /// - internal IkvmReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) - { - return (IkvmReflectionConstructorSymbol)GetOrCreateMethodBaseSymbol(ctor); - } - - /// - /// Gets or creates the cached for the type by method. - /// - /// - /// - internal IkvmReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) - { - return (IkvmReflectionMethodSymbol)GetOrCreateMethodBaseSymbol(method); - } - - /// - /// Gets or creates the cached for the type by field. - /// - /// - /// - /// - internal IkvmReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) - { - if (field is null) - throw new ArgumentNullException(nameof(field)); - - Debug.Assert(field.Module == _module); - - // create lock on demand - if (_fieldLock == null) - Interlocked.CompareExchange(ref _fieldLock, new ReaderWriterLockSlim(), null); - - using (_fieldLock.CreateUpgradeableReadLock()) - { - var row = MetadataTokens.GetRowNumber(MetadataTokens.FieldDefinitionHandle(field.MetadataToken)); - if (_fieldTable[row] != field) - using (_fieldLock.CreateWriteLock()) - _fieldTable[row] = field; - - if (_fieldSymbols[row] == null) - using (_fieldLock.CreateWriteLock()) - if (field.DeclaringType is { } dt) - return _fieldSymbols[row] ??= new IkvmReflectionFieldSymbol(Context, ResolveTypeSymbol(dt), field); - else - return _fieldSymbols[row] ??= new IkvmReflectionFieldSymbol(Context, this, field); - else - return _fieldSymbols[row] ?? throw new InvalidOperationException(); - } - } - - /// - /// Gets or creates the cached for the type by property. - /// - /// - /// - /// - internal IkvmReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) - { - if (property is null) - throw new ArgumentNullException(nameof(property)); - - Debug.Assert(property.Module == _module); - - // create lock on demand - if (_propertyLock == null) - Interlocked.CompareExchange(ref _propertyLock, new ReaderWriterLockSlim(), null); - - using (_propertyLock.CreateUpgradeableReadLock()) - { - var row = MetadataTokens.GetRowNumber(MetadataTokens.PropertyDefinitionHandle(property.MetadataToken)); - if (_propertyTable[row] != property) - using (_propertyLock.CreateWriteLock()) - _propertyTable[row] = property; - - if (_propertySymbols[row] == null) - using (_propertyLock.CreateWriteLock()) - return _propertySymbols[row] ??= new IkvmReflectionPropertySymbol(Context, ResolveTypeSymbol(property.DeclaringType!), property); - else - return _propertySymbols[row] ?? throw new InvalidOperationException(); - } - } - - /// - /// Gets or creates the cached for the type by event. - /// - /// - /// - /// - internal IkvmReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) - { - if (@event is null) - throw new ArgumentNullException(nameof(@event)); - - Debug.Assert(@event.Module == _module); - - // create lock on demand - if (_eventLock == null) - Interlocked.CompareExchange(ref _eventLock, new ReaderWriterLockSlim(), null); - - using (_eventLock.CreateUpgradeableReadLock()) - { - var row = MetadataTokens.GetRowNumber(MetadataTokens.EventDefinitionHandle(@event.MetadataToken)); - if (_eventTable[row] is not EventInfo i || i != @event) - using (_eventLock.CreateWriteLock()) - _eventTable[row] = @event; - - if (_eventSymbols[row] == null) - using (_eventLock.CreateWriteLock()) - return _eventSymbols[row] ??= new IkvmReflectionEventSymbol(Context, ResolveTypeSymbol(@event.DeclaringType!), @event); - else - return _eventSymbols[row] ?? throw new InvalidOperationException(); - } - } - - /// - /// Gets or creates the cached for the type by method. - /// - /// - /// - internal IkvmReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) - { - if (parameter is null) - throw new ArgumentNullException(nameof(parameter)); - - Debug.Assert(parameter.Member.Module == _module); - - // create lock on demand - if (_parameterLock == null) - Interlocked.CompareExchange(ref _parameterLock, new ReaderWriterLockSlim(), null); - - using (_parameterLock.CreateUpgradeableReadLock()) - { - var position = parameter.Position; - if (_parameterTable[position] != parameter) - using (_parameterLock.CreateWriteLock()) - _parameterTable[position] = parameter; - - if (_parameterSymbols[position] == null) - using (_parameterLock.CreateWriteLock()) - return _parameterSymbols[position] ??= new IkvmReflectionParameterSymbol(Context, ResolveMethodBaseSymbol((MethodBase)parameter.Member), parameter); - else - return _parameterSymbols[position] ?? throw new InvalidOperationException(); - } - } - - /// - /// Gets or creates the cached for the module by type. - /// - /// - /// - /// - internal IkvmReflectionTypeSymbol GetOrCreateGenericParameterSymbol(Type genericParameterType) - { - if (genericParameterType is null) - throw new ArgumentNullException(nameof(genericParameterType)); - - Debug.Assert(genericParameterType.Module == _module); - - // create lock on demand - if (_genericParameterLock == null) - Interlocked.CompareExchange(ref _genericParameterLock, new ReaderWriterLockSlim(), null); - - using (_genericParameterLock.CreateUpgradeableReadLock()) - { - var hnd = MetadataTokens.GenericParameterHandle(genericParameterType.MetadataToken); - var row = MetadataTokens.GetRowNumber(hnd); - if (_genericParameterSymbols[row] == null) - using (_genericParameterLock.CreateWriteLock()) - return _genericParameterSymbols[row] ??= new IkvmReflectionTypeSymbol(Context, this, genericParameterType); - else - return _genericParameterSymbols[row] ?? throw new InvalidOperationException(); - } - } - - /// - public IAssemblySymbol Assembly => Context.GetOrCreateAssemblySymbol(_module.Assembly); - - /// - public string FullyQualifiedName => _module.FullyQualifiedName; - - /// - public int MetadataToken => _module.MetadataToken; - - /// - public Guid ModuleVersionId => _module.ModuleVersionId; - - /// - public string Name => _module.Name; - - /// - public string ScopeName => _module.ScopeName; - - /// - public IFieldSymbol? GetField(string name) - { - return _module.GetField(name) is { } f ? ResolveFieldSymbol(f) : null; - } - - /// - public IFieldSymbol? GetField(string name, System.Reflection.BindingFlags bindingAttr) - { - return _module.GetField(name, (BindingFlags)bindingAttr) is { } f ? ResolveFieldSymbol(f) : null; - } - - /// - public IFieldSymbol[] GetFields(System.Reflection.BindingFlags bindingFlags) - { - return ResolveFieldSymbols(_module.GetFields((BindingFlags)bindingFlags)); - } - - /// - public IFieldSymbol[] GetFields() - { - return ResolveFieldSymbols(_module.GetFields()); - } - - /// - public IMethodSymbol? GetMethod(string name) - { - return _module.GetMethod(name) is { } m ? ResolveMethodSymbol(m) : null; - } - - /// - public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) - { - return _module.GetMethod(name, types.Unpack()) is { } m ? ResolveMethodSymbol(m) : null; - } - - /// - public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) - { - throw new NotImplementedException(); - } - - /// - public IMethodSymbol[] GetMethods() - { - return ResolveMethodSymbols(_module.GetMethods()); - } - - /// - public IMethodSymbol[] GetMethods(System.Reflection.BindingFlags bindingFlags) - { - return ResolveMethodSymbols(_module.GetMethods((BindingFlags)bindingFlags)); - } - - /// - public ITypeSymbol? GetType(string className) - { - return _module.GetType(className) is { } t ? ResolveTypeSymbol(t) : null; - } - - /// - public ITypeSymbol? GetType(string className, bool ignoreCase) - { - return _module.GetType(className, ignoreCase) is { } t ? ResolveTypeSymbol(t) : null; - } - - /// - public ITypeSymbol? GetType(string className, bool throwOnError, bool ignoreCase) - { - return _module.GetType(className, throwOnError, ignoreCase) is { } t ? ResolveTypeSymbol(t) : null; - } - - /// - public ITypeSymbol[] GetTypes() - { - return ResolveTypeSymbols(_module.GetTypes()); - } - - /// - public bool IsResource() - { - return _module.IsResource(); - } - - /// - public IFieldSymbol? ResolveField(int metadataToken) - { - return _module.ResolveField(metadataToken) is { } f ? ResolveFieldSymbol(f) : null; - } - - /// - public IFieldSymbol? ResolveField(int metadataToken, ITypeSymbol[]? genericTypeArguments, ITypeSymbol[]? genericMethodArguments) - { - return _module.ResolveField(metadataToken, genericTypeArguments?.Unpack(), genericMethodArguments?.Unpack()) is { } f ? ResolveFieldSymbol(f) : null; - } - - /// - public IMemberSymbol? ResolveMember(int metadataToken) - { - return _module.ResolveMember(metadataToken) is { } m ? ResolveMemberSymbol(m) : null; - } - - /// - public IMemberSymbol? ResolveMember(int metadataToken, ITypeSymbol[]? genericTypeArguments, ITypeSymbol[]? genericMethodArguments) - { - return _module.ResolveMember(metadataToken, genericTypeArguments?.Unpack(), genericMethodArguments?.Unpack()) is { } m ? ResolveMemberSymbol(m) : null; - } - - /// - public IMethodBaseSymbol? ResolveMethod(int metadataToken, ITypeSymbol[]? genericTypeArguments, ITypeSymbol[]? genericMethodArguments) - { - return _module.ResolveMethod(metadataToken, genericTypeArguments?.Unpack(), genericMethodArguments?.Unpack()) is { } m ? ResolveMethodBaseSymbol(m) : null; - } - - /// - public IMethodBaseSymbol? ResolveMethod(int metadataToken) - { - return _module.ResolveMethod(metadataToken) is { } m ? ResolveMethodBaseSymbol(m) : null; - } - - /// - public byte[] ResolveSignature(int metadataToken) - { - return _module.ResolveSignature(metadataToken); - } - - /// - public string ResolveString(int metadataToken) - { - return _module.ResolveString(metadataToken); - } - - /// - public ITypeSymbol ResolveType(int metadataToken) - { - return ResolveTypeSymbol(_module.ResolveType(metadataToken)); - } - - /// - public ITypeSymbol ResolveType(int metadataToken, ITypeSymbol[]? genericTypeArguments, ITypeSymbol[]? genericMethodArguments) - { - return ResolveTypeSymbol(_module.ResolveType(metadataToken, genericTypeArguments?.Unpack(), genericMethodArguments?.Unpack())); - } - - /// - public CustomAttribute[] GetCustomAttributes(bool inherit = false) - { - return ResolveCustomAttributes(_module.GetCustomAttributesData()); - } - - /// - public CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) - { - return ResolveCustomAttributes(_module.GetCustomAttributesData().Where(i => i.AttributeType == ((IkvmReflectionTypeSymbol)attributeType).ReflectionObject)); - } - - /// - public CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) - { - return GetCustomAttributes(attributeType, inherit).FirstOrDefault(); - } - - /// - public bool IsDefined(ITypeSymbol attributeType, bool inherit = false) - { - return _module.IsDefined(((IkvmReflectionTypeSymbol)attributeType).ReflectionObject, false); - } - - /// - /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. - /// - /// - internal void Complete(Module module) - { - ResolveModuleSymbol(_module = module); - ContainingAssembly.Complete(_module.Assembly); - } - - } - -} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterSymbol.cs deleted file mode 100644 index a0dca4626..000000000 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterSymbol.cs +++ /dev/null @@ -1,119 +0,0 @@ -using System; -using System.Linq; - -using ParameterInfo = IKVM.Reflection.ParameterInfo; - -namespace IKVM.CoreLib.Symbols.IkvmReflection -{ - - class IkvmReflectionParameterSymbol : IkvmReflectionSymbol, IParameterSymbol - { - - readonly IkvmReflectionMethodBaseSymbol _containingMethod; - ParameterInfo _parameter; - - CustomAttribute[]? _customAttributes; - - /// - /// Initializes a new instance. - /// - /// - /// - /// - public IkvmReflectionParameterSymbol(IkvmReflectionSymbolContext context, IkvmReflectionMethodBaseSymbol containingMethod, ParameterInfo parameter) : - base(context) - { - _containingMethod = containingMethod ?? throw new ArgumentNullException(nameof(containingMethod)); - _parameter = parameter ?? throw new ArgumentNullException(nameof(parameter)); - } - - internal IkvmReflectionMethodBaseSymbol ContainingMethod => _containingMethod; - - /// - public System.Reflection.ParameterAttributes Attributes =>(System.Reflection.ParameterAttributes)_parameter.Attributes; - - /// - public object? DefaultValue => _parameter.RawDefaultValue; - - /// - public bool HasDefaultValue => _parameter.HasDefaultValue; - - /// - public bool IsIn => _parameter.IsIn; - - /// - public bool IsLcid => _parameter.IsLcid; - - /// - public bool IsOptional => _parameter.IsOptional; - - /// - public bool IsOut => _parameter.IsOut; - - /// - public bool IsRetval => _parameter.IsRetval; - - /// - public IMemberSymbol Member => ResolveMemberSymbol(_parameter.Member); - - /// - public int MetadataToken => _parameter.MetadataToken; - - /// - public string? Name => _parameter.Name; - - /// - public ITypeSymbol ParameterType => ResolveTypeSymbol(_parameter.ParameterType); - - /// - public int Position => _parameter.Position; - - /// - public CustomAttribute[] GetCustomAttributes(bool inherit = false) - { - return _customAttributes ??= ResolveCustomAttributes(_parameter.GetCustomAttributesData()); - } - - /// - public virtual CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) - { - return GetCustomAttributes(inherit).Where(i => i.AttributeType == attributeType).ToArray(); - } - - /// - public virtual CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) - { - return GetCustomAttributes(attributeType, inherit).FirstOrDefault(); - } - - /// - public virtual bool IsDefined(ITypeSymbol attributeType, bool inherit = false) - { - return _parameter.IsDefined(((IkvmReflectionTypeSymbol)attributeType).ReflectionObject, inherit); - } - - /// - public ITypeSymbol[] GetOptionalCustomModifiers() - { - return ResolveTypeSymbols(_parameter.GetOptionalCustomModifiers()); - } - - /// - public ITypeSymbol[] GetRequiredCustomModifiers() - { - return ResolveTypeSymbols(_parameter.GetRequiredCustomModifiers()); - } - - /// - /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. - /// - /// - internal void Complete(ParameterInfo parameter) - { - ResolveParameterSymbol(_parameter = parameter); - _customAttributes = null; - } - - } - -} \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionPropertySymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionPropertySymbol.cs deleted file mode 100644 index a257b0015..000000000 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionPropertySymbol.cs +++ /dev/null @@ -1,131 +0,0 @@ -using System; - -using IKVM.Reflection; - -using PropertyInfo = IKVM.Reflection.PropertyInfo; - -namespace IKVM.CoreLib.Symbols.IkvmReflection -{ - - class IkvmReflectionPropertySymbol : IkvmReflectionMemberSymbol, IPropertySymbol - { - - PropertyInfo _property; - - /// - /// Initializes a new instance. - /// - /// - /// - /// - public IkvmReflectionPropertySymbol(IkvmReflectionSymbolContext context, IkvmReflectionTypeSymbol type, PropertyInfo property) : - base(context, type, property) - { - _property = property ?? throw new ArgumentNullException(nameof(property)); - } - - /// - /// Gets the underlying wrapped by this symbol. - /// - internal new PropertyInfo ReflectionObject => _property; - - /// - public System.Reflection.PropertyAttributes Attributes => (System.Reflection.PropertyAttributes)_property.Attributes; - - /// - public bool CanRead => _property.CanRead; - - /// - public bool CanWrite => _property.CanWrite; - - /// - public bool IsSpecialName => _property.IsSpecialName; - - /// - public ITypeSymbol PropertyType => ResolveTypeSymbol(_property.PropertyType); - - /// - public IMethodSymbol? GetMethod => _property.GetMethod is { } m ? ResolveMethodSymbol(m) : null; - - /// - public IMethodSymbol? SetMethod => _property.SetMethod is { } m ? ResolveMethodSymbol(m) : null; - - /// - public object? GetRawConstantValue() - { - return _property.GetRawConstantValue(); - } - - /// - public IMethodSymbol[] GetAccessors() - { - return ResolveMethodSymbols(_property.GetAccessors()); - } - - /// - public IMethodSymbol[] GetAccessors(bool nonPublic) - { - return ResolveMethodSymbols(_property.GetAccessors(nonPublic)); - } - - /// - public IParameterSymbol[] GetIndexParameters() - { - return ResolveParameterSymbols(_property.GetIndexParameters()); - } - - /// - public IMethodSymbol? GetGetMethod() - { - return _property.GetGetMethod() is MethodInfo m ? ResolveMethodSymbol(m) : null; - } - - /// - public IMethodSymbol? GetGetMethod(bool nonPublic) - { - return _property.GetGetMethod(nonPublic) is MethodInfo m ? ResolveMethodSymbol(m) : null; - } - - /// - public IMethodSymbol? GetSetMethod() - { - return _property.GetSetMethod() is MethodInfo m ? ResolveMethodSymbol(m) : null; - } - - /// - public IMethodSymbol? GetSetMethod(bool nonPublic) - { - return _property.GetSetMethod(nonPublic) is MethodInfo m ? ResolveMethodSymbol(m) : null; - } - - /// - public ITypeSymbol GetModifiedPropertyType() - { - throw new NotImplementedException(); - } - - /// - public ITypeSymbol[] GetOptionalCustomModifiers() - { - return ResolveTypeSymbols(_property.GetOptionalCustomModifiers()); - } - - /// - public ITypeSymbol[] GetRequiredCustomModifiers() - { - return ResolveTypeSymbols(_property.GetRequiredCustomModifiers()); - } - - /// - /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. - /// - /// - internal void Complete(PropertyInfo property) - { - ResolvePropertySymbol(_property = property); - base.Complete(_property); - } - - } - -} \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs deleted file mode 100644 index a469bb946..000000000 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs +++ /dev/null @@ -1,417 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Immutable; - -using IKVM.Reflection; - -using ConstructorInfo = IKVM.Reflection.ConstructorInfo; -using EventInfo = IKVM.Reflection.EventInfo; -using FieldInfo = IKVM.Reflection.FieldInfo; -using MemberInfo = IKVM.Reflection.MemberInfo; -using MethodBase = IKVM.Reflection.MethodBase; -using MethodInfo = IKVM.Reflection.MethodInfo; -using Module = IKVM.Reflection.Module; -using ParameterInfo = IKVM.Reflection.ParameterInfo; -using PropertyInfo = IKVM.Reflection.PropertyInfo; -using Type = IKVM.Reflection.Type; - -namespace IKVM.CoreLib.Symbols.IkvmReflection -{ - - /// - /// Base class for managed symbols. - /// - abstract class IkvmReflectionSymbol : ISymbol - { - - readonly IkvmReflectionSymbolContext _context; - - /// - /// Initializes a new instance. - /// - /// - public IkvmReflectionSymbol(IkvmReflectionSymbolContext context) - { - _context = context ?? throw new ArgumentNullException(nameof(context)); - } - - /// - /// Gets the associated . - /// - protected IkvmReflectionSymbolContext Context => _context; - - /// - public bool IsMissing => false; - - /// - public bool ContainsMissing => false; - - /// - /// Resolves the symbol for the specified type. - /// - /// - /// - protected virtual internal IkvmReflectionModuleSymbol ResolveModuleSymbol(Module module) - { - return _context.GetOrCreateModuleSymbol(module); - } - - /// - /// Resolves the symbols for the specified modules. - /// - /// - /// - protected internal IkvmReflectionModuleSymbol[] ResolveModuleSymbols(Module[] modules) - { - var a = new IkvmReflectionModuleSymbol[modules.Length]; - for (int i = 0; i < modules.Length; i++) - a[i] = ResolveModuleSymbol(modules[i]); - - return a; - } - - /// - /// Resolves the symbols for the specified modules. - /// - /// - /// - protected internal IEnumerable ResolveModuleSymbols(IEnumerable modules) - { - foreach (var module in modules) - yield return ResolveModuleSymbol(module); - } - - /// - /// Resolves the symbol for the specified type. - /// - /// - /// - protected virtual IkvmReflectionMemberSymbol ResolveMemberSymbol(MemberInfo member) - { - return member.MemberType switch - { - MemberTypes.Constructor => ResolveConstructorSymbol((ConstructorInfo)member), - MemberTypes.Event => ResolveEventSymbol((EventInfo)member), - MemberTypes.Field => ResolveFieldSymbol((FieldInfo)member), - MemberTypes.Method => ResolveMethodSymbol((MethodInfo)member), - MemberTypes.Property => ResolvePropertySymbol((PropertyInfo)member), - MemberTypes.TypeInfo => ResolveTypeSymbol((Type)member), - MemberTypes.NestedType => ResolveTypeSymbol((Type)member), - MemberTypes.Custom => throw new NotImplementedException(), - MemberTypes.All => throw new NotImplementedException(), - _ => throw new InvalidOperationException(), - }; - } - - /// - /// Resolves the symbols for the specified types. - /// - /// - /// - protected internal IkvmReflectionMemberSymbol[] ResolveMemberSymbols(MemberInfo[] types) - { - var a = new IkvmReflectionMemberSymbol[types.Length]; - for (int i = 0; i < types.Length; i++) - a[i] = ResolveMemberSymbol(types[i]); - - return a; - } - - /// - /// Resolves the symbol for the specified type. - /// - /// - /// - protected virtual internal IkvmReflectionTypeSymbol ResolveTypeSymbol(Type type) - { - return _context.GetOrCreateTypeSymbol(type); - } - - /// - /// Resolves the symbols for the specified types. - /// - /// - /// - protected internal IkvmReflectionTypeSymbol[] ResolveTypeSymbols(Type[] types) - { - var a = new IkvmReflectionTypeSymbol[types.Length]; - for (int i = 0; i < types.Length; i++) - a[i] = ResolveTypeSymbol(types[i]); - - return a; - } - - /// - /// Resolves the symbols for the specified types. - /// - /// - /// - protected internal IEnumerable ResolveTypeSymbols(IEnumerable types) - { - foreach (var type in types) - yield return ResolveTypeSymbol(type); - } - - /// - /// Resolves the symbol for the specified method. - /// - /// - /// - protected virtual internal IkvmReflectionMethodBaseSymbol ResolveMethodBaseSymbol(MethodBase method) - { - if (method.IsConstructor) - return ResolveConstructorSymbol((ConstructorInfo)method); - else - return ResolveMethodSymbol((MethodInfo)method); - } - - /// - /// Resolves the symbol for the specified constructor. - /// - /// - /// - protected virtual internal IkvmReflectionConstructorSymbol ResolveConstructorSymbol(ConstructorInfo ctor) - { - return _context.GetOrCreateConstructorSymbol(ctor); - } - - /// - /// Resolves the symbols for the specified constructors. - /// - /// - /// - protected internal IkvmReflectionConstructorSymbol[] ResolveConstructorSymbols(ConstructorInfo[] ctors) - { - var a = new IkvmReflectionConstructorSymbol[ctors.Length]; - for (int i = 0; i < ctors.Length; i++) - a[i] = ResolveConstructorSymbol(ctors[i]); - - return a; - } - - /// - /// Resolves the symbol for the specified method. - /// - /// - /// - protected virtual internal IkvmReflectionMethodSymbol ResolveMethodSymbol(MethodInfo method) - { - return _context.GetOrCreateMethodSymbol(method); - } - - /// - /// Resolves the symbols for the specified methods. - /// - /// - /// - protected internal IkvmReflectionMethodSymbol[] ResolveMethodSymbols(MethodInfo[] methods) - { - var a = new IkvmReflectionMethodSymbol[methods.Length]; - for (int i = 0; i < methods.Length; i++) - a[i] = ResolveMethodSymbol(methods[i]); - - return a; - } - - /// - /// Resolves the symbol for the specified field. - /// - /// - /// - protected virtual internal IkvmReflectionFieldSymbol ResolveFieldSymbol(FieldInfo field) - { - return _context.GetOrCreateFieldSymbol(field); - } - - /// - /// Resolves the symbols for the specified fields. - /// - /// - /// - protected internal IkvmReflectionFieldSymbol[] ResolveFieldSymbols(FieldInfo[] fields) - { - var a = new IkvmReflectionFieldSymbol[fields.Length]; - for (int i = 0; i < fields.Length; i++) - a[i] = ResolveFieldSymbol(fields[i]); - - return a; - } - - /// - /// Resolves the symbol for the specified field. - /// - /// - /// - protected virtual internal IkvmReflectionPropertySymbol ResolvePropertySymbol(PropertyInfo property) - { - return _context.GetOrCreatePropertySymbol(property); - } - - /// - /// Resolves the symbols for the specified properties. - /// - /// - /// - protected internal IkvmReflectionPropertySymbol[] ResolvePropertySymbols(PropertyInfo[] properties) - { - var a = new IkvmReflectionPropertySymbol[properties.Length]; - for (int i = 0; i < properties.Length; i++) - a[i] = ResolvePropertySymbol(properties[i]); - - return a; - } - - /// - /// Resolves the symbol for the specified event. - /// - /// - /// - protected virtual internal IkvmReflectionEventSymbol ResolveEventSymbol(EventInfo @event) - { - return _context.GetOrCreateEventSymbol(@event); - } - - /// - /// Resolves the symbols for the specified events. - /// - /// - /// - protected internal IkvmReflectionEventSymbol[] ResolveEventSymbols(EventInfo[] events) - { - var a = new IkvmReflectionEventSymbol[events.Length]; - for (int i = 0; i < events.Length; i++) - a[i] = ResolveEventSymbol(events[i]); - - return a; - } - - /// - /// Resolves the symbol for the specified parameter. - /// - /// - /// - protected virtual internal IkvmReflectionParameterSymbol ResolveParameterSymbol(ParameterInfo parameter) - { - return _context.GetOrCreateParameterSymbol(parameter); - } - - /// - /// Resolves the symbols for the specified parameters. - /// - /// - /// - protected internal IkvmReflectionParameterSymbol[] ResolveParameterSymbols(ParameterInfo[] parameters) - { - var a = new IkvmReflectionParameterSymbol[parameters.Length]; - for (int i = 0; i < parameters.Length; i++) - a[i] = ResolveParameterSymbol(parameters[i]); - - return a; - } - - /// - /// Transforms a custom set of custom attribute data records to a symbol record. - /// - /// - /// - protected internal CustomAttribute[] ResolveCustomAttributes(IList attributes) - { - var a = new CustomAttribute[attributes.Count]; - for (int i = 0; i < attributes.Count; i++) - a[i] = ResolveCustomAttribute(attributes[i]); - - return a; - } - - /// - /// Transforms a custom set of custom attribute data records to a symbol record. - /// - /// - /// - protected internal CustomAttribute[] ResolveCustomAttributes(IEnumerable attributes) - { - var a = new List(); - foreach (var i in attributes) - a.Add(ResolveCustomAttribute(i)); - - return a.ToArray(); - } - - /// - /// Transforms a custom attribute data record to a symbol record. - /// - /// - /// - protected internal CustomAttribute ResolveCustomAttribute(CustomAttributeData customAttributeData) - { - return new CustomAttribute( - ResolveTypeSymbol(customAttributeData.AttributeType), - ResolveConstructorSymbol(customAttributeData.Constructor), - ResolveCustomAttributeTypedArguments(customAttributeData.ConstructorArguments), - ResolveCustomAttributeNamedArguments(customAttributeData.NamedArguments)); - } - - /// - /// Transforms a list of values into symbols. - /// - /// - /// - ImmutableArray ResolveCustomAttributeTypedArguments(IList args) - { - var a = new CustomAttributeTypedArgument[args.Count]; - for (int i = 0; i < args.Count; i++) - a[i] = ResolveCustomAttributeTypedArgument(args[i]); - - return a.ToImmutableArray(); - } - - /// - /// Transforms a values into a symbol. - /// - /// - /// - CustomAttributeTypedArgument ResolveCustomAttributeTypedArgument(IKVM.Reflection.CustomAttributeTypedArgument arg) - { - return new CustomAttributeTypedArgument(ResolveTypeSymbol(arg.ArgumentType), ResolveCustomAttributeTypedValue(arg.Value)); - } - - /// - /// Transforms the type as appropriate. - /// - /// - /// - object? ResolveCustomAttributeTypedValue(object? value) - { - if (value is Type v) - return ResolveTypeSymbol(v); - - return value; - } - - /// - /// Transforms a list of values into symbols. - /// - /// - /// - ImmutableArray ResolveCustomAttributeNamedArguments(IList args) - { - var a = new CustomAttributeNamedArgument[args.Count]; - for (int i = 0; i < args.Count; i++) - a[i] = ResolveCustomAttributeNamedArgument(args[i]); - - return ImmutableArray.Create(a); - } - - /// - /// Transforms a values into a symbol. - /// - /// - /// - CustomAttributeNamedArgument ResolveCustomAttributeNamedArgument(IKVM.Reflection.CustomAttributeNamedArgument arg) - { - return new CustomAttributeNamedArgument(arg.IsField, ResolveMemberSymbol(arg.MemberInfo), arg.MemberName, ResolveCustomAttributeTypedArgument(arg.TypedValue)); - } - - } - -} \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolContext.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolContext.cs deleted file mode 100644 index 53ce1511f..000000000 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolContext.cs +++ /dev/null @@ -1,180 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Runtime.CompilerServices; - -using IKVM.CoreLib.Reflection; -using IKVM.CoreLib.Symbols.IkvmReflection.Emit; -using IKVM.Reflection.Emit; - -using Assembly = IKVM.Reflection.Assembly; -using ConstructorInfo = IKVM.Reflection.ConstructorInfo; -using EventInfo = IKVM.Reflection.EventInfo; -using FieldInfo = IKVM.Reflection.FieldInfo; -using MethodBase = IKVM.Reflection.MethodBase; -using MethodInfo = IKVM.Reflection.MethodInfo; -using Module = IKVM.Reflection.Module; -using ParameterInfo = IKVM.Reflection.ParameterInfo; -using PropertyInfo = IKVM.Reflection.PropertyInfo; -using Type = IKVM.Reflection.Type; - -namespace IKVM.CoreLib.Symbols.IkvmReflection -{ - - /// - /// Holds references to symbols derived from System.Reflection. - /// - class IkvmReflectionSymbolContext - { - - readonly ConcurrentDictionary> _symbolByName = new(AssemblyNameEqualityComparer.Instance); - readonly ConditionalWeakTable _symbolByAssembly = new(); - - /// - /// Initializes a new instance. - /// - public IkvmReflectionSymbolContext() - { - - } - - /// - /// Gets or creates a indexed based on the assembly's name. - /// - /// - /// - IkvmReflectionAssemblySymbol GetOrCreateAssemblySymbolByName(Assembly assembly) - { - var r = _symbolByName.GetOrAdd(assembly.GetName().ToAssemblyName(), _ => new WeakReference(new IkvmReflectionAssemblySymbol(this, assembly))); - - // reference has valid symbol - if (r.TryGetTarget(out var s)) - return s; - - // no valid symbol, must have been released, lock to restore - lock (r) - { - // still gone, recreate - if (r.TryGetTarget(out s) == false) - r.SetTarget(s = new IkvmReflectionAssemblySymbol(this, assembly)); - - return s; - } - } - - /// - /// Gets or creates a for the specified . - /// - /// - /// - public IkvmReflectionAssemblySymbol GetOrCreateAssemblySymbol(Assembly assembly) - { - return _symbolByAssembly.GetValue(assembly, GetOrCreateAssemblySymbolByName); - } - - /// - /// Gets or creates a for the specified . - /// - /// - /// - public IkvmReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) - { - return GetOrCreateAssemblySymbol(module.Assembly).GetOrCreateModuleSymbol(module); - } - - /// - /// Gets or creates a for the specified . - /// - /// - /// - public IkvmReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) - { - return GetOrCreateModuleSymbol(type.Module).GetOrCreateTypeSymbol(type); - } - - /// - /// Gets or creates a for the specified . - /// - /// - /// - public IkvmReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method) - { - if (method is ConstructorInfo ctor) - return GetOrCreateConstructorSymbol(ctor); - else - return GetOrCreateMethodSymbol((MethodInfo)method); - } - - /// - /// Gets or creates a for the specified . - /// - /// - /// - public IkvmReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) - { - return GetOrCreateModuleSymbol(ctor.Module).GetOrCreateConstructorSymbol(ctor); - } - - /// - /// Gets or creates a for the specified . - /// - /// - /// - public IkvmReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) - { - return GetOrCreateModuleSymbol(method.Module).GetOrCreateMethodSymbol(method); - } - - /// - /// Gets or creates a for the specified . - /// - /// - /// - public IkvmReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) - { - return GetOrCreateModuleSymbol(parameter.Member.Module).GetOrCreateParameterSymbol(parameter); - } - - /// - /// Gets or creates a for the specified . - /// - /// - /// - public IkvmReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) - { - return GetOrCreateModuleSymbol(field.Module).GetOrCreateFieldSymbol(field); - } - - /// - /// Gets or creates a for the specified . - /// - /// - /// - public IkvmReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) - { - return GetOrCreateModuleSymbol(property.Module).GetOrCreatePropertySymbol(property); - } - - /// - /// Gets or creates a for the specified . - /// - /// - /// - public IkvmReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) - { - return GetOrCreateModuleSymbol(@event.Module).GetOrCreateEventSymbol(@event); - } - - /// - /// Gets or creates a for the specified . - /// - /// - /// - /// - public IkvmReflectionParameterSymbol GetOrCreateParameterSymbol(MethodBuilder method, ParameterBuilder parameter) - { - return GetOrCreateParameterSymbol(new IkvmReflectionParameterBuilderInfo(method, parameter)); - } - - } - -} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs deleted file mode 100644 index a3d3ef7c5..000000000 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs +++ /dev/null @@ -1,669 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Threading; - -using IKVM.CoreLib.Symbols.Reflection; -using IKVM.Reflection; - -using ConstructorInfo = IKVM.Reflection.ConstructorInfo; -using FieldInfo = IKVM.Reflection.FieldInfo; -using MethodInfo = IKVM.Reflection.MethodInfo; -using Type = IKVM.Reflection.Type; - -namespace IKVM.CoreLib.Symbols.IkvmReflection -{ - - class IkvmReflectionTypeSymbol : IkvmReflectionMemberSymbol, ITypeSymbol - { - - const int MAX_CAPACITY = 65536 * 2; - - const BindingFlags DefaultBindingFlags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance; - - Type _type; - - IkvmReflectionTypeSymbol?[]? _asArray; - IkvmReflectionTypeSymbol? _asSZArray; - IkvmReflectionTypeSymbol? _asPointer; - IkvmReflectionTypeSymbol? _asByRef; - ConcurrentDictionary? _genericTypeSymbols; - - /// - /// Initializes a new instance. - /// - /// - /// - /// - public IkvmReflectionTypeSymbol(IkvmReflectionSymbolContext context, IkvmReflectionModuleSymbol module, Type type) : - base(context, module, type) - { - Debug.Assert(module.ReflectionObject == type.Module); - _type = type ?? throw new ArgumentNullException(nameof(type)); - } - - /// - /// Gets or creates the cached for the generic parameter type. - /// - /// - /// - internal IkvmReflectionTypeSymbol GetOrCreateGenericTypeSymbol(ITypeSymbol[] genericTypeArguments) - { - if (genericTypeArguments is null) - throw new ArgumentNullException(nameof(genericTypeArguments)); - - if (_type.IsGenericTypeDefinition == false) - throw new InvalidOperationException(); - - if (_genericTypeSymbols == null) - Interlocked.CompareExchange(ref _genericTypeSymbols, new ConcurrentDictionary(TypeSymbolListEqualityComparer.Instance), null); - - return _genericTypeSymbols.GetOrAdd( - genericTypeArguments, - _ => new IkvmReflectionTypeSymbol(Context, ContainingModule, _type.MakeGenericType(genericTypeArguments.Unpack()))); - } - - /// - /// Resolves the symbol for the specified type. - /// - /// - /// - protected internal override IkvmReflectionTypeSymbol ResolveTypeSymbol(Type type) - { - if (type == _type) - return this; - else - return base.ResolveTypeSymbol(type); - } - - /// - /// Gets the wrapped . - /// - internal new Type ReflectionObject => _type; - - /// - public IAssemblySymbol Assembly => Context.GetOrCreateAssemblySymbol(_type.Assembly); - - /// - public string? AssemblyQualifiedName => _type.AssemblyQualifiedName; - - /// - public System.Reflection.TypeAttributes Attributes => (System.Reflection.TypeAttributes)_type.Attributes; - - /// - public ITypeSymbol? BaseType => _type.BaseType != null ? ResolveTypeSymbol(_type.BaseType) : null; - - /// - public bool ContainsGenericParameters => _type.ContainsGenericParameters; - - /// - public IMethodBaseSymbol? DeclaringMethod => _type.DeclaringMethod is MethodInfo m ? ResolveMethodSymbol(m) : null; - - /// - public string? FullName => _type.FullName; - - /// - public string? Namespace => _type.Namespace; - - /// - public System.Reflection.GenericParameterAttributes GenericParameterAttributes => (System.Reflection.GenericParameterAttributes)_type.GenericParameterAttributes; - - /// - public int GenericParameterPosition => _type.GenericParameterPosition; - - /// - public ITypeSymbol[] GenericTypeArguments => ResolveTypeSymbols(_type.GenericTypeArguments); - - /// - public bool HasElementType => _type.HasElementType; - - /// - public TypeCode TypeCode => Type.GetTypeCode(_type); - - /// - public bool IsAbstract => _type.IsAbstract; - -#if NETFRAMEWORK - - /// - /// - /// There's no API to distinguish an array of rank 1 from a vector, - /// so we check if the type name ends in [], which indicates it's a vector - /// (non-vectors will have [*] or [,]). - /// - public bool IsSZArray => _type.IsArray && _type.Name.EndsWith("[]"); - -#else - - /// - public bool IsSZArray => _type.IsSZArray; - -#endif - - /// - public bool IsArray => _type.IsArray; - - /// - public bool IsAutoLayout => _type.IsAutoLayout; - - /// - public bool IsExplicitLayout => _type.IsExplicitLayout; - - /// - public bool IsByRef => _type.IsByRef; - - /// - public bool IsClass => _type.IsClass; - - /// - public bool IsEnum => _type.IsEnum; - - /// - public bool IsInterface => _type.IsInterface; - - /// - public bool IsConstructedGenericType => _type.IsConstructedGenericType; - - /// - public bool IsGenericParameter => _type.IsGenericParameter; - - /// - public bool IsGenericType => _type.IsGenericType; - - /// - public bool IsGenericTypeDefinition => _type.IsGenericTypeDefinition; - - /// - public bool IsLayoutSequential => _type.IsLayoutSequential; - - /// - public bool IsNested => _type.IsNested; - - /// - public bool IsNestedAssembly => _type.IsNestedAssembly; - - /// - public bool IsNestedFamANDAssem => _type.IsNestedFamANDAssem; - - /// - public bool IsNestedFamORAssem => _type.IsNestedFamORAssem; - - /// - public bool IsNestedFamily => _type.IsNestedFamily; - - /// - public bool IsNestedPrivate => _type.IsNestedPrivate; - - /// - public bool IsNestedPublic => _type.IsNestedPublic; - - /// - public bool IsNotPublic => _type.IsNotPublic; - - /// - public bool IsPointer => _type.IsPointer; - -#if NET8_0_OR_GREATER - - /// - public bool IsFunctionPointer => _type.IsFunctionPointer; - - /// - public bool IsUnmanagedFunctionPointer => _type.IsUnmanagedFunctionPointer; - -#else - - /// - public bool IsFunctionPointer => throw new NotImplementedException(); - - /// - public bool IsUnmanagedFunctionPointer => throw new NotImplementedException(); - -#endif - - /// - public bool IsPrimitive => _type.IsPrimitive; - - /// - public bool IsPublic => _type.IsPublic; - - /// - public bool IsSealed => _type.IsSealed; - - /// - public bool IsSerializable => _type.IsSerializable; - - /// - public bool IsValueType => _type.IsValueType; - - /// - public bool IsVisible => _type.IsVisible; - - /// - public bool IsSignatureType => throw new NotImplementedException(); - - /// - public bool IsSpecialName => _type.IsSpecialName; - - /// - public IConstructorSymbol? TypeInitializer => _type.TypeInitializer is ConstructorInfo ctor ? ResolveConstructorSymbol(ctor) : null; - - /// - public int GetArrayRank() - { - return _type.GetArrayRank(); - } - - /// - public IConstructorSymbol? GetConstructor(System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) - { - return _type.GetConstructor((BindingFlags)bindingAttr, binder: null, types.Unpack(), modifiers: null) is ConstructorInfo ctor ? ResolveConstructorSymbol(ctor) : null; - } - - /// - public IConstructorSymbol? GetConstructor(ITypeSymbol[] types) - { - return _type.GetConstructor(types.Unpack()) is ConstructorInfo ctor ? ResolveConstructorSymbol(ctor) : null; - } - - /// - public IConstructorSymbol[] GetConstructors() - { - return ResolveConstructorSymbols(_type.GetConstructors()); - } - - /// - public IConstructorSymbol[] GetConstructors(System.Reflection.BindingFlags bindingAttr) - { - return ResolveConstructorSymbols(_type.GetConstructors((BindingFlags)bindingAttr)); - } - - /// - public IMemberSymbol[] GetDefaultMembers() - { - return ResolveMemberSymbols(_type.GetDefaultMembers()); - } - - /// - public ITypeSymbol? GetElementType() - { - return _type.GetElementType() is Type t ? ResolveTypeSymbol(t) : null; - } - - /// - public string? GetEnumName(object value) - { - return _type.GetEnumName(value); - } - - /// - public string[] GetEnumNames() - { - return _type.GetEnumNames(); - } - - /// - public ITypeSymbol GetEnumUnderlyingType() - { - return ResolveTypeSymbol(_type.GetEnumUnderlyingType()); - } - - /// - public Array GetEnumValues() - { - return _type.GetEnumValues(); - } - - /// - public IEventSymbol? GetEvent(string name, System.Reflection.BindingFlags bindingAttr) - { - throw new NotImplementedException(); - } - - /// - public IEventSymbol? GetEvent(string name) - { - return _type.GetEvent(name) is { } f ? ResolveEventSymbol(f) : null; - } - - /// - public IEventSymbol[] GetEvents() - { - return ResolveEventSymbols(_type.GetEvents()); - } - - /// - public IEventSymbol[] GetEvents(System.Reflection.BindingFlags bindingAttr) - { - return ResolveEventSymbols(_type.GetEvents((BindingFlags)bindingAttr)); - } - - /// - public IFieldSymbol? GetField(string name) - { - return _type.GetField(name) is FieldInfo f ? ResolveFieldSymbol(f) : null; - } - - /// - public IFieldSymbol? GetField(string name, System.Reflection.BindingFlags bindingAttr) - { - return _type.GetField(name, (BindingFlags)bindingAttr) is FieldInfo f ? ResolveFieldSymbol(f) : null; - } - - /// - public IFieldSymbol[] GetFields() - { - return ResolveFieldSymbols(_type.GetFields()); - } - - /// - public IFieldSymbol[] GetFields(System.Reflection.BindingFlags bindingAttr) - { - return ResolveFieldSymbols(_type.GetFields((BindingFlags)bindingAttr)); - } - - /// - public ITypeSymbol[] GetGenericArguments() - { - return ResolveTypeSymbols(_type.GetGenericArguments()); - } - - /// - public ITypeSymbol[] GetGenericParameterConstraints() - { - return ResolveTypeSymbols(_type.GetGenericParameterConstraints()); - } - - /// - public ITypeSymbol GetGenericTypeDefinition() - { - return ResolveTypeSymbol(_type.GetGenericTypeDefinition()); - } - - /// - public ITypeSymbol? GetInterface(string name) - { - return _type.GetInterface(name) is { } i ? ResolveTypeSymbol(i) : null; - } - - /// - public ITypeSymbol? GetInterface(string name, bool ignoreCase) - { - return _type.GetInterface(name, ignoreCase) is { } i ? ResolveTypeSymbol(i) : null; - } - - /// - public InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) - { - throw new NotImplementedException(); - } - - /// - public ITypeSymbol[] GetInterfaces(bool inherit = true) - { - if (inherit) - return ResolveTypeSymbols(_type.GetInterfaces()); - else - throw new NotImplementedException(); - } - - /// - public IMemberSymbol[] GetMember(string name) - { - return ResolveMemberSymbols(_type.GetMember(name)); - } - - /// - public IMemberSymbol[] GetMember(string name, System.Reflection.BindingFlags bindingAttr) - { - return ResolveMemberSymbols(_type.GetMember(name, (BindingFlags)bindingAttr)); - } - - /// - public IMemberSymbol[] GetMember(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) - { - return ResolveMemberSymbols(_type.GetMember(name, (MemberTypes)type, (BindingFlags)bindingAttr)); - } - - /// - public IMemberSymbol[] GetMembers(System.Reflection.BindingFlags bindingAttr) - { - return ResolveMemberSymbols(_type.GetMembers((BindingFlags)bindingAttr)); - } - - /// - public IMemberSymbol[] GetMembers() - { - return ResolveMemberSymbols(_type.GetMembers()); - } - - /// - public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr) - { - return _type.GetMethod(name, (BindingFlags)bindingAttr) is { } m ? ResolveMethodSymbol(m) : null; - } - - /// - public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) - { - return _type.GetMethod(name, types.Unpack()) is { } m ? ResolveMethodSymbol(m) : null; - } - - /// - public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) - { - return _type.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), null) is { } m ? ResolveMethodSymbol(m) : null; - } - - /// - public IMethodSymbol? GetMethod(string name) - { - return _type.GetMethod(name) is { } m ? ResolveMethodSymbol(m) : null; - } - - /// - public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) - { - return _type.GetMethod(name, (BindingFlags)bindingAttr, null, (CallingConventions)callConvention, types.Unpack(), modifiers?.Unpack()) is { } m ? ResolveMethodSymbol(m) : null; - } - - /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) - { - throw new NotImplementedException(); - } - - /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) - { - throw new NotImplementedException(); - } - - /// - public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) - { - return _type.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), modifiers?.Unpack()) is { } m ? ResolveMethodSymbol(m) : null; - } - - /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) - { - throw new NotImplementedException(); - } - - /// - public IMethodSymbol[] GetMethods(System.Reflection.BindingFlags bindingAttr) - { - return ResolveMethodSymbols(_type.GetMethods((BindingFlags)bindingAttr)); - } - - /// - public IMethodSymbol[] GetMethods() - { - return ResolveMethodSymbols(_type.GetMethods()); - } - - /// - public ITypeSymbol? GetNestedType(string name) - { - return _type.GetNestedType(name) is Type t ? ResolveTypeSymbol(t) : null; - } - - /// - public ITypeSymbol? GetNestedType(string name, System.Reflection.BindingFlags bindingAttr) - { - return _type.GetNestedType(name, (BindingFlags)bindingAttr) is Type t ? ResolveTypeSymbol(t) : null; - } - - /// - public ITypeSymbol[] GetNestedTypes() - { - return ResolveTypeSymbols(_type.GetNestedTypes()); - } - - /// - public ITypeSymbol[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr) - { - return ResolveTypeSymbols(_type.GetNestedTypes((BindingFlags)bindingAttr)); - } - - /// - public IPropertySymbol[] GetProperties() - { - return ResolvePropertySymbols(_type.GetProperties()); - } - - /// - public IPropertySymbol[] GetProperties(System.Reflection.BindingFlags bindingAttr) - { - return ResolvePropertySymbols(_type.GetProperties((BindingFlags)bindingAttr)); - } - - /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol[] types) - { - return _type.GetProperty(name, types.Unpack()) is { } p ? ResolvePropertySymbol(p) : null; - } - - /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types) - { - return _type.GetProperty(name, returnType?.Unpack(), types.Unpack()) is { } p ? ResolvePropertySymbol(p) : null; - } - - /// - public IPropertySymbol? GetProperty(string name, System.Reflection.BindingFlags bindingAttr) - { - return _type.GetProperty(name, (BindingFlags)bindingAttr) is { } p ? ResolvePropertySymbol(p) : null; - } - - /// - public IPropertySymbol? GetProperty(string name) - { - return _type.GetProperty(name) is { } p ? ResolvePropertySymbol(p) : null; - } - - /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) - { - return _type.GetProperty(name, returnType?.Unpack()) is { } p ? ResolvePropertySymbol(p) : null; - } - - /// - public bool IsAssignableFrom(ITypeSymbol? c) - { - return _type.IsAssignableFrom(c?.Unpack()); - } - - /// - public bool IsEnumDefined(object value) - { - return _type.IsEnumDefined(value); - } - - /// - public bool IsSubclassOf(ITypeSymbol c) - { - return _type.IsSubclassOf(c.Unpack()); - } - - /// - public ITypeSymbol MakeArrayType() - { - if (_asSZArray == null) - Interlocked.CompareExchange(ref _asSZArray, new IkvmReflectionTypeSymbol(Context, ContainingModule, _type.MakeArrayType()), null); - - return _asSZArray; - } - - /// - public ITypeSymbol MakeArrayType(int rank) - { - if (rank == 1) - return MakeArrayType(); - - if (_asArray == null) - Interlocked.CompareExchange(ref _asArray, new IkvmReflectionTypeSymbol?[32], null); - - ref var asArray = ref _asArray[rank]; - if (asArray == null) - Interlocked.CompareExchange(ref asArray, new IkvmReflectionTypeSymbol(Context, ContainingModule, _type.MakeArrayType(rank)), null); - - return asArray; - } - - /// - public ITypeSymbol MakeByRefType() - { - if (_asByRef == null) - Interlocked.CompareExchange(ref _asByRef, new IkvmReflectionTypeSymbol(Context, ContainingModule, _type.MakeByRefType()), null); - - return _asByRef; - } - - /// - public ITypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments) - { - throw new NotImplementedException(); - } - - /// - public ITypeSymbol MakePointerType() - { - if (_asPointer == null) - Interlocked.CompareExchange(ref _asPointer, new IkvmReflectionTypeSymbol(Context, ContainingModule, _type.MakePointerType()), null); - - return _asPointer; - } - - /// - /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. - /// - /// - internal void Complete(Type type) - { - ResolveTypeSymbol(_type = type); - base.Complete(_type); - - ContainingModule.Complete(_type.Module); - - foreach (var i in _type.GetConstructors(DefaultBindingFlags)) - ResolveConstructorSymbol(i).Complete(i); - - foreach (var i in _type.GetMethods(DefaultBindingFlags)) - ResolveMethodSymbol(i).Complete(i); - - foreach (var i in _type.GetFields(DefaultBindingFlags)) - ResolveFieldSymbol(i).Complete(i); - - foreach (var i in _type.GetProperties(DefaultBindingFlags)) - ResolvePropertySymbol(i).Complete(i); - - foreach (var i in _type.GetEvents(DefaultBindingFlags)) - ResolveEventSymbol(i).Complete(i); - } - } - -} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionUtil.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionUtil.cs deleted file mode 100644 index d00e0ff60..000000000 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionUtil.cs +++ /dev/null @@ -1,195 +0,0 @@ -using System; - -using IKVM.Reflection; - -using ConstructorInfo = IKVM.Reflection.ConstructorInfo; -using MethodInfo = IKVM.Reflection.MethodInfo; -using Type = IKVM.Reflection.Type; - -namespace IKVM.CoreLib.Symbols.IkvmReflection -{ - - static class IkvmReflectionUtil - { - - /// - /// Converts the to a . - /// - /// - /// - public static System.Reflection.AssemblyName ToAssemblyName(this AssemblyName src) - { -#pragma warning disable SYSLIB0037 // Type or member is obsolete - return new System.Reflection.AssemblyName() - { - Name = src.Name, - Version = src.Version, - CultureName = src.CultureName, - HashAlgorithm = (System.Configuration.Assemblies.AssemblyHashAlgorithm)src.HashAlgorithm, - Flags = (System.Reflection.AssemblyNameFlags)src.Flags, - ContentType = (System.Reflection.AssemblyContentType)src.ContentType, - }; -#pragma warning restore SYSLIB0037 // Type or member is obsolete - } - - /// - /// Unpacks the symbol into their original type. - /// - /// - /// - public static Module Unpack(this IModuleSymbol module) - { - return ((IkvmReflectionModuleSymbol)module).ReflectionObject; - } - - /// - /// Unpacks the symbols into their original type. - /// - /// - /// - public static Module[] Unpack(this IModuleSymbol[] modules) - { - var a = new Module[modules.Length]; - for (int i = 0; i < modules.Length; i++) - a[i] = modules[i].Unpack(); - - return a; - } - - /// - /// Unpacks the symbol into their original type. - /// - /// - /// - public static Type Unpack(this ITypeSymbol type) - { - return ((IkvmReflectionTypeSymbol)type).ReflectionObject; - } - - /// - /// Unpacks the symbols into their original type. - /// - /// - /// - public static Type[] Unpack(this ITypeSymbol[] types) - { - var a = new Type[types.Length]; - for (int i = 0; i < types.Length; i++) - a[i] = types[i].Unpack(); - - return a; - } - - /// - /// Unpacks the symbols into their original type. - /// - /// - /// - public static Type[][] Unpack(this ITypeSymbol[][] types) - { - var a = new Type[types.Length][]; - for (int i = 0; i < types.Length; i++) - a[i] = types[i].Unpack(); - - return a; - } - - /// - /// Unpacks the symbol into their original type. - /// - /// - /// - public static MemberInfo Unpack(this IMemberSymbol member) - { - return ((IkvmReflectionMemberSymbol)member).ReflectionObject; - } - - /// - /// Unpacks the symbols into their original type. - /// - /// - /// - public static MemberInfo[] Unpack(this IMemberSymbol[] members) - { - var a = new MemberInfo[members.Length]; - for (int i = 0; i < members.Length; i++) - a[i] = members[i].Unpack(); - - return a; - } - - /// - /// Unpacks the symbol into their original type. - /// - /// - /// - public static ConstructorInfo Unpack(this IConstructorSymbol ctor) - { - return ((IkvmReflectionConstructorSymbol)ctor).ReflectionObject; - } - - /// - /// Unpacks the symbols into their original type. - /// - /// - /// - public static ConstructorInfo[] Unpack(this IConstructorSymbol[] ctor) - { - var a = new ConstructorInfo[ctor.Length]; - for (int i = 0; i < ctor.Length; i++) - a[i] = ctor[i].Unpack(); - - return a; - } - - /// - /// Unpacks the symbol into their original type. - /// - /// - /// - public static MethodInfo Unpack(this IMethodSymbol ctor) - { - return ((IkvmReflectionMethodSymbol)ctor).ReflectionObject; - } - - /// - /// Unpacks the symbols into their original type. - /// - /// - /// - public static MethodInfo[] Unpack(this IMethodSymbol[] ctor) - { - var a = new MethodInfo[ctor.Length]; - for (int i = 0; i < ctor.Length; i++) - a[i] = ctor[i].Unpack(); - - return a; - } - - /// - /// Unpacks the modifier into their original type. - /// - /// - /// - public static ParameterModifier Unpack(this System.Reflection.ParameterModifier modifier) - { - throw new NotImplementedException(); - } - - /// - /// Unpacks the modifiers into their original types. - /// - /// - /// - public static ParameterModifier[] Unpack(this System.Reflection.ParameterModifier[] ctor) - { - var a = new ParameterModifier[ctor.Length]; - for (int i = 0; i < ctor.Length; i++) - a[i] = ctor[i].Unpack(); - - return a; - } - - } - -} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionAssemblySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionAssemblySymbolBuilder.cs new file mode 100644 index 000000000..6652e1af1 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionAssemblySymbolBuilder.cs @@ -0,0 +1,18 @@ +using System.Reflection.Emit; + +using IKVM.CoreLib.Symbols.Emit; + +namespace IKVM.CoreLib.Symbols.Reflection.Emit +{ + + interface IReflectionAssemblySymbolBuilder : IReflectionSymbolBuilder, IAssemblySymbolBuilder, IReflectionAssemblySymbol + { + + /// + /// Gets the underlying . + /// + AssemblyBuilder UnderlyingAssemblyBuilder { get; } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionConstructorSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionConstructorSymbolBuilder.cs new file mode 100644 index 000000000..0572b3bdf --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionConstructorSymbolBuilder.cs @@ -0,0 +1,15 @@ +using System.Reflection.Emit; + +using IKVM.CoreLib.Symbols.Emit; + +namespace IKVM.CoreLib.Symbols.Reflection.Emit +{ + + interface IReflectionConstructorSymbolBuilder : IReflectionSymbolBuilder, IReflectionMethodBaseSymbolBuilder, IConstructorSymbolBuilder, IReflectionConstructorSymbol + { + + ConstructorBuilder UnderlyingConstructorBuilder { get; } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionEventSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionEventSymbolBuilder.cs new file mode 100644 index 000000000..f9c48d0be --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionEventSymbolBuilder.cs @@ -0,0 +1,15 @@ +using System.Reflection.Emit; + +using IKVM.CoreLib.Symbols.Emit; + +namespace IKVM.CoreLib.Symbols.Reflection.Emit +{ + + interface IReflectionEventSymbolBuilder : IReflectionSymbolBuilder, IReflectionMemberSymbolBuilder, IEventSymbolBuilder, IReflectionEventSymbol + { + + EventBuilder UnderlyingEventBuilder { get; } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionFieldSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionFieldSymbolBuilder.cs new file mode 100644 index 000000000..ecd263c1b --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionFieldSymbolBuilder.cs @@ -0,0 +1,15 @@ +using System.Reflection.Emit; + +using IKVM.CoreLib.Symbols.Emit; + +namespace IKVM.CoreLib.Symbols.Reflection.Emit +{ + + interface IReflectionFieldSymbolBuilder : IReflectionSymbolBuilder, IReflectionMemberSymbolBuilder, IFieldSymbolBuilder, IReflectionFieldSymbol + { + + FieldBuilder UnderlyingFieldBuilder { get; } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionGenericTypeParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionGenericTypeParameterSymbolBuilder.cs new file mode 100644 index 000000000..20917942a --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionGenericTypeParameterSymbolBuilder.cs @@ -0,0 +1,24 @@ +using System.Reflection.Emit; + +using IKVM.CoreLib.Symbols.Reflection; +using IKVM.CoreLib.Symbols.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.Emit +{ + + interface IReflectionGenericTypeParameterSymbolBuilder : IReflectionSymbolBuilder, IGenericTypeParameterSymbolBuilder, IReflectionTypeSymbol + { + + /// + /// Gets the underlying . + /// + GenericTypeParameterBuilder UnderlyingGenericTypeParameterBuilder { get; } + + /// + /// Invoked when the type containing this generic type parameter is completed. + /// + void OnComplete(); + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionMemberSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionMemberSymbolBuilder.cs new file mode 100644 index 000000000..4eb323b30 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionMemberSymbolBuilder.cs @@ -0,0 +1,17 @@ +using IKVM.CoreLib.Symbols.Emit; + +namespace IKVM.CoreLib.Symbols.Reflection.Emit +{ + + interface IReflectionMemberSymbolBuilder : IReflectionSymbolBuilder, IMemberSymbolBuilder, IReflectionMemberSymbol + { + + /// + /// Invoked when the type responsible for this builder is completed. Implementations should update their + /// underlying type, and optionally dispatch the OnComplete invocation to downstream elements. + /// + void OnComplete(); + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionMethodBaseSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionMethodBaseSymbolBuilder.cs new file mode 100644 index 000000000..0d757111d --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionMethodBaseSymbolBuilder.cs @@ -0,0 +1,13 @@ +using IKVM.CoreLib.Symbols.Emit; + +namespace IKVM.CoreLib.Symbols.Reflection.Emit +{ + + interface IReflectionMethodBaseSymbolBuilder : IReflectionSymbolBuilder, IReflectionMemberSymbolBuilder, IMethodBaseSymbolBuilder, IReflectionMethodBaseSymbol + { + + + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionMethodSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionMethodSymbolBuilder.cs new file mode 100644 index 000000000..cc19efa3d --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionMethodSymbolBuilder.cs @@ -0,0 +1,18 @@ +using System.Reflection.Emit; + +using IKVM.CoreLib.Symbols.Emit; + +namespace IKVM.CoreLib.Symbols.Reflection.Emit +{ + + interface IReflectionMethodSymbolBuilder : IReflectionSymbolBuilder, IReflectionMethodBaseSymbolBuilder, IMethodSymbolBuilder, IReflectionMethodSymbol + { + + /// + /// Gets the underlying . + /// + MethodBuilder UnderlyingMethodBuilder { get; } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionModuleSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionModuleSymbolBuilder.cs new file mode 100644 index 000000000..9fbd1c7c1 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionModuleSymbolBuilder.cs @@ -0,0 +1,18 @@ +using System.Reflection.Emit; + +using IKVM.CoreLib.Symbols.Emit; + +namespace IKVM.CoreLib.Symbols.Reflection.Emit +{ + + interface IReflectionModuleSymbolBuilder : IReflectionSymbolBuilder, IModuleSymbolBuilder, IReflectionModuleSymbol + { + + /// + /// Gets the underlying . + /// + ModuleBuilder UnderlyingModuleBuilder { get; } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionParameterSymbolBuilder.cs new file mode 100644 index 000000000..679ac8429 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionParameterSymbolBuilder.cs @@ -0,0 +1,23 @@ +using System.Reflection.Emit; + +using IKVM.CoreLib.Symbols.Emit; + +namespace IKVM.CoreLib.Symbols.Reflection.Emit +{ + + interface IReflectionParameterSymbolBuilder : IReflectionSymbolBuilder, IParameterSymbolBuilder, IReflectionParameterSymbol + { + + /// + /// Gets the underlying . + /// + ParameterBuilder UnderlyingParameterBuilder { get; } + + /// + /// Invoked when the owning method of this parameter is completed. + /// + void OnComplete(); + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionPropertySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionPropertySymbolBuilder.cs new file mode 100644 index 000000000..1a10c8c6c --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionPropertySymbolBuilder.cs @@ -0,0 +1,15 @@ +using System.Reflection.Emit; + +using IKVM.CoreLib.Symbols.Emit; + +namespace IKVM.CoreLib.Symbols.Reflection.Emit +{ + + interface IReflectionPropertySymbolBuilder : IReflectionSymbolBuilder, IReflectionMemberSymbolBuilder, IPropertySymbolBuilder, IReflectionPropertySymbol + { + + PropertyBuilder UnderlyingPropertyBuilder { get; } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionSymbolBuilder.cs new file mode 100644 index 000000000..45123999f --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionSymbolBuilder.cs @@ -0,0 +1,19 @@ +using IKVM.CoreLib.Symbols.Emit; + +namespace IKVM.CoreLib.Symbols.Reflection.Emit +{ + + interface IReflectionSymbolBuilder : ISymbolBuilder + { + + } + + interface IReflectionSymbolBuilder : IReflectionSymbolBuilder, ISymbolBuilder + where TSymbol : IReflectionSymbol + { + + + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionTypeSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionTypeSymbolBuilder.cs new file mode 100644 index 000000000..ee86b9734 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionTypeSymbolBuilder.cs @@ -0,0 +1,18 @@ +using System.Reflection.Emit; + +using IKVM.CoreLib.Symbols.Emit; + +namespace IKVM.CoreLib.Symbols.Reflection.Emit +{ + + interface IReflectionTypeSymbolBuilder : IReflectionSymbolBuilder, IReflectionMemberSymbolBuilder, ITypeSymbolBuilder, IReflectionTypeSymbol + { + + /// + /// Gets the underlying . + /// + TypeBuilder UnderlyingTypeBuilder { get; } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs index ee05a37ce..2d3e9e071 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs @@ -1,4 +1,7 @@ using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; using System.Reflection.Emit; using IKVM.CoreLib.Symbols.Emit; @@ -6,11 +9,11 @@ namespace IKVM.CoreLib.Symbols.Reflection.Emit { - class ReflectionAssemblySymbolBuilder : ReflectionSymbolBuilder, IAssemblySymbolBuilder + class ReflectionAssemblySymbolBuilder : ReflectionSymbolBuilder, IReflectionAssemblySymbolBuilder { readonly AssemblyBuilder _builder; - ReflectionAssemblySymbol? _symbol; + ReflectionAssemblyMetadata _metadata; /// /// Initializes a new instance. @@ -21,24 +24,30 @@ public ReflectionAssemblySymbolBuilder(ReflectionSymbolContext context, Assembly base(context) { _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + _metadata = new ReflectionAssemblyMetadata(this); } /// - internal sealed override ReflectionAssemblySymbol ReflectionSymbol => _symbol ??= Context.GetOrCreateAssemblySymbol(_builder); + public Assembly UnderlyingAssembly => UnderlyingAssemblyBuilder; + + /// + public AssemblyBuilder UnderlyingAssemblyBuilder => _builder; + + #region IAssemblySymbolBuilder /// public IModuleSymbolBuilder DefineModule(string name) { - return new ReflectionModuleSymbolBuilder(Context, _builder.DefineDynamicModule(name)); + return GetOrCreateModuleSymbol(UnderlyingAssemblyBuilder.DefineDynamicModule(name)); } /// public IModuleSymbolBuilder DefineModule(string name, string fileName) { #if NETFRAMEWORK - return new ReflectionModuleSymbolBuilder(Context, _builder.DefineDynamicModule(name, fileName)); + return GetOrCreateModuleSymbol(UnderlyingAssemblyBuilder.DefineDynamicModule(name, fileName)); #else - return new ReflectionModuleSymbolBuilder(Context, _builder.DefineDynamicModule(name)); + return GetOrCreateModuleSymbol(UnderlyingAssemblyBuilder.DefineDynamicModule(name)); #endif } @@ -46,9 +55,9 @@ public IModuleSymbolBuilder DefineModule(string name, string fileName) public IModuleSymbolBuilder DefineModule(string name, string fileName, bool emitSymbolInfo) { #if NETFRAMEWORK - return new ReflectionModuleSymbolBuilder(Context, _builder.DefineDynamicModule(name, fileName, emitSymbolInfo)); + return GetOrCreateModuleSymbol(UnderlyingAssemblyBuilder.DefineDynamicModule(name, fileName, emitSymbolInfo)); #else - return new ReflectionModuleSymbolBuilder(Context, _builder.DefineDynamicModule(name)); + return GetOrCreateModuleSymbol(UnderlyingAssemblyBuilder.DefineDynamicModule(name)); #endif } @@ -61,25 +70,140 @@ public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) /// public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) { - _builder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).ReflectionBuilder); + _builder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); } + #endregion + + #region IAssemblySymbol + + /// + public IEnumerable DefinedTypes => ResolveTypeSymbols(UnderlyingAssembly.DefinedTypes); + + /// + public IMethodSymbol? EntryPoint => ResolveMethodSymbol(UnderlyingAssembly.EntryPoint); + + /// + public IEnumerable ExportedTypes => ResolveTypeSymbols(UnderlyingAssembly.ExportedTypes); + /// - public void Complete() + public string? FullName => UnderlyingAssembly.FullName; + + /// + public string ImageRuntimeVersion => UnderlyingAssembly.ImageRuntimeVersion; + + /// + public IModuleSymbol ManifestModule => ResolveModuleSymbol(UnderlyingAssembly.ManifestModule); + + /// + public IEnumerable Modules => ResolveModuleSymbols(UnderlyingAssembly.Modules); + + /// + public override bool IsComplete => _builder == null; + + /// + public ITypeSymbol[] GetExportedTypes() { - foreach (var module in _builder.GetModules()) - { - if (module is ModuleBuilder moduleBuilder) - { - moduleBuilder.CreateGlobalFunctions(); + return ResolveTypeSymbols(UnderlyingAssembly.GetExportedTypes()); + } - foreach (var type in moduleBuilder.GetTypes()) - if (type is TypeBuilder typeBuilder) - if (typeBuilder.IsCreated() == false) - if (typeBuilder.CreateType() is { } t) - ReflectionSymbol.ResolveTypeSymbol(t).Complete(t); - } - } + /// + public IModuleSymbol? GetModule(string name) + { + return ResolveModuleSymbol(UnderlyingAssembly.GetModule(name)); + } + + /// + public IModuleSymbol[] GetModules() + { + return ResolveModuleSymbols(UnderlyingAssembly.GetModules()); + } + + /// + public IModuleSymbol[] GetModules(bool getResourceModules) + { + return ResolveModuleSymbols(UnderlyingAssembly.GetModules(getResourceModules)); + } + + /// + public AssemblyName GetName() + { + return UnderlyingAssembly.GetName(); + } + + /// + public AssemblyName GetName(bool copiedName) + { + return UnderlyingAssembly.GetName(copiedName); + } + + /// + public AssemblyName[] GetReferencedAssemblies() + { + return UnderlyingAssembly.GetReferencedAssemblies(); + } + + /// + public ITypeSymbol? GetType(string name, bool throwOnError) + { + return ResolveTypeSymbol(UnderlyingAssembly.GetType(name, throwOnError)); + } + + /// + public ITypeSymbol? GetType(string name, bool throwOnError, bool ignoreCase) + { + return ResolveTypeSymbol(UnderlyingAssembly.GetType(name, throwOnError, ignoreCase)); + } + + /// + public ITypeSymbol? GetType(string name) + { + return ResolveTypeSymbol(UnderlyingAssembly.GetType(name)); + } + + /// + public ITypeSymbol[] GetTypes() + { + return ResolveTypeSymbols(UnderlyingAssembly.GetTypes()); + } + + /// + public CustomAttribute[] GetCustomAttributes(bool inherit = false) + { + return ResolveCustomAttributes(UnderlyingAssembly.GetCustomAttributesData()); + } + + /// + public CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) + { + var _attributeType = attributeType.Unpack(); + return ResolveCustomAttributes(UnderlyingAssembly.GetCustomAttributesData().Where(i => i.AttributeType == _attributeType).ToArray()); + } + + /// + public CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) + { + return GetCustomAttributes(attributeType, inherit).FirstOrDefault(); + } + + /// + public bool IsDefined(ITypeSymbol attributeType, bool inherit = false) + { + return UnderlyingAssembly.IsDefined(attributeType.Unpack(), inherit); + } + + #endregion + + /// + public IReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) + { + return _metadata.GetOrCreateModuleSymbol(module); + } + + /// + public IReflectionModuleSymbolBuilder GetOrCreateModuleSymbol(ModuleBuilder module) + { + return (IReflectionModuleSymbolBuilder)_metadata.GetOrCreateModuleSymbol(module); } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionConstructorSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionConstructorSymbolBuilder.cs index 80c895b09..2dbde97d2 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionConstructorSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionConstructorSymbolBuilder.cs @@ -7,42 +7,48 @@ namespace IKVM.CoreLib.Symbols.Reflection.Emit { - class ReflectionConstructorSymbolBuilder : ReflectionMethodBaseSymbolBuilder, IConstructorSymbolBuilder + class ReflectionConstructorSymbolBuilder : ReflectionMethodBaseSymbolBuilder, IReflectionConstructorSymbolBuilder { - readonly ConstructorBuilder _builder; - ReflectionConstructorSymbol? _symbol; + ConstructorBuilder? _builder; + ConstructorInfo _ctor; /// /// Initializes a new instance. /// /// - /// + /// + /// /// - public ReflectionConstructorSymbolBuilder(ReflectionSymbolContext context, ReflectionTypeSymbolBuilder containingTypeBuilder, ConstructorBuilder builder) : - base(context, containingTypeBuilder) + /// + public ReflectionConstructorSymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol resolvingType, ConstructorBuilder builder) : + base(context, resolvingModule, resolvingType) { _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + _ctor = _builder; } - /// - /// Gets the containing . - /// - protected internal new ReflectionTypeSymbolBuilder ContainingTypeBuilder => base.ContainingTypeBuilder ?? throw new NullReferenceException(); + /// + public ConstructorInfo UnderlyingConstructor => _ctor; + + /// + public override MethodBase UnderlyingMethodBase => UnderlyingConstructor; /// - internal override ReflectionConstructorSymbol ReflectionSymbol => _symbol ??= Context.GetOrCreateConstructorSymbol(_builder); + public ConstructorBuilder UnderlyingConstructorBuilder => _builder ?? throw new InvalidOperationException(); + + #region IConstructorSymbolBuilder /// public void SetImplementationFlags(MethodImplAttributes attributes) { - _builder.SetImplementationFlags(attributes); + UnderlyingConstructorBuilder.SetImplementationFlags(attributes); } /// public IParameterSymbolBuilder DefineParameter(int iSequence, ParameterAttributes attributes, string? strParamName) { - return new ReflectionParameterSymbolBuilder(Context, this, _builder.DefineParameter(iSequence, attributes, strParamName)); + return new ReflectionParameterSymbolBuilder(Context, ResolvingModule, this, UnderlyingConstructorBuilder.DefineParameter(iSequence, attributes, strParamName)); } /// @@ -60,13 +66,30 @@ public IILGenerator GetILGenerator(int streamSize) /// public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) { - _builder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).ReflectionBuilder); + UnderlyingConstructorBuilder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); } /// public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) { - _builder.SetCustomAttribute(con.Unpack(), binaryAttribute); + UnderlyingConstructorBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); + } + + #endregion + + #region IConstructorSymbol + + /// + public override bool IsComplete => _builder == null; + + #endregion + + /// + public override void OnComplete() + { + _ctor = (ConstructorInfo?)ResolvingModule.UnderlyingModule.ResolveMethod(MetadataToken) ?? throw new InvalidOperationException(); + _builder = null; + base.OnComplete(); } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionCustomAttributeBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionCustomAttributeBuilder.cs index bb1978ec3..eed10e2cb 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionCustomAttributeBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionCustomAttributeBuilder.cs @@ -22,7 +22,7 @@ public ReflectionCustomAttributeBuilder(CustomAttributeBuilder builder) /// /// Gets the underlying reflection . /// - internal CustomAttributeBuilder ReflectionBuilder => _builder; + internal CustomAttributeBuilder UnderlyingBuilder => _builder; } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionEventBuilderInfo.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionEventBuilderInfo.cs index 771ff9757..7a87c506d 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionEventBuilderInfo.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionEventBuilderInfo.cs @@ -1,6 +1,7 @@ using System; using System.Reflection; using System.Reflection.Emit; +using IKVM.CoreLib.Reflection; namespace IKVM.CoreLib.Symbols.Reflection.Emit { diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionEventSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionEventSymbolBuilder.cs index fbc7ea865..d583458d9 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionEventSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionEventSymbolBuilder.cs @@ -1,4 +1,5 @@ using System; +using System.Reflection; using System.Reflection.Emit; using IKVM.CoreLib.Symbols.Emit; @@ -6,65 +7,155 @@ namespace IKVM.CoreLib.Symbols.Reflection.Emit { - class ReflectionEventSymbolBuilder : ReflectionSymbolBuilder, IEventSymbolBuilder + class ReflectionEventSymbolBuilder : ReflectionMemberSymbolBuilder, IReflectionEventSymbolBuilder { - readonly ReflectionTypeSymbolBuilder _containingTypeBuilder; - readonly EventBuilder _builder; - readonly ReflectionEventBuilderInfo _info; - ReflectionEventSymbol? _symbol; + EventBuilder? _builder; + EventInfo _event; /// /// Initializes a new instance. /// /// - /// + /// + /// /// - public ReflectionEventSymbolBuilder(ReflectionSymbolContext context, ReflectionTypeSymbolBuilder containingTypeBuilder, EventBuilder builder) : - base(context) + /// + public ReflectionEventSymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol resolvingType, EventBuilder builder) : + base(context, resolvingModule, resolvingType) { - _containingTypeBuilder = containingTypeBuilder ?? throw new ArgumentNullException(nameof(containingTypeBuilder)); _builder = builder ?? throw new ArgumentNullException(nameof(builder)); - _info = new ReflectionEventBuilderInfo(_builder); + _event = new ReflectionEventBuilderInfo(_builder); } /// - internal override ReflectionEventSymbol ReflectionSymbol => _symbol ??= _containingTypeBuilder.ReflectionSymbol.ResolveEventSymbol(_info); + public EventInfo UnderlyingEvent => _event; + + /// + public EventBuilder UnderlyingEventBuilder => _builder ?? throw new NotImplementedException(); + + /// + public override MemberInfo UnderlyingMember => UnderlyingEvent; + + #region IEventSymbolBuilder /// public void SetAddOnMethod(IMethodSymbolBuilder mdBuilder) { - _builder.SetAddOnMethod(((ReflectionMethodSymbolBuilder)mdBuilder).ReflectionBuilder); + UnderlyingEventBuilder.SetAddOnMethod(((IReflectionMethodSymbolBuilder)mdBuilder).UnderlyingMethodBuilder); } /// public void SetRemoveOnMethod(IMethodSymbolBuilder mdBuilder) { - _builder.SetRemoveOnMethod(((ReflectionMethodSymbolBuilder)mdBuilder).ReflectionBuilder); + UnderlyingEventBuilder.SetRemoveOnMethod(((IReflectionMethodSymbolBuilder)mdBuilder).UnderlyingMethodBuilder); } /// public void SetRaiseMethod(IMethodSymbolBuilder mdBuilder) { - _builder.SetRaiseMethod(((ReflectionMethodSymbolBuilder)mdBuilder).ReflectionBuilder); + UnderlyingEventBuilder.SetRaiseMethod(((IReflectionMethodSymbolBuilder)mdBuilder).UnderlyingMethodBuilder); } /// public void AddOtherMethod(IMethodSymbolBuilder mdBuilder) { - _builder.AddOtherMethod(((ReflectionMethodSymbolBuilder)mdBuilder).ReflectionBuilder); + UnderlyingEventBuilder.AddOtherMethod(((IReflectionMethodSymbolBuilder)mdBuilder).UnderlyingMethodBuilder); } /// public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) { - _builder.SetCustomAttribute(con.Unpack(), binaryAttribute); + UnderlyingEventBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); } /// public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) { - _builder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).ReflectionBuilder); + UnderlyingEventBuilder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); + } + + #endregion + + #region IEventSymbol + + /// + public EventAttributes Attributes => UnderlyingEvent.Attributes; + + /// + public ITypeSymbol? EventHandlerType => ResolveTypeSymbol(UnderlyingEvent.EventHandlerType); + + /// + public bool IsSpecialName => UnderlyingEvent.IsSpecialName; + + /// + public IMethodSymbol? AddMethod => ResolveMethodSymbol(UnderlyingEvent.AddMethod); + + /// + public IMethodSymbol? RemoveMethod => ResolveMethodSymbol(UnderlyingEvent.RemoveMethod); + + /// + public IMethodSymbol? RaiseMethod => ResolveMethodSymbol(UnderlyingEvent.RaiseMethod); + + /// + public override bool IsComplete => _builder == null; + + /// + public IMethodSymbol? GetAddMethod() + { + return ResolveMethodSymbol(UnderlyingEvent.GetAddMethod()); + } + + /// + public IMethodSymbol? GetAddMethod(bool nonPublic) + { + return ResolveMethodSymbol(UnderlyingEvent.GetAddMethod(nonPublic)); + } + + /// + public IMethodSymbol? GetRemoveMethod() + { + return ResolveMethodSymbol(UnderlyingEvent.GetRemoveMethod()); + } + + /// + public IMethodSymbol? GetRemoveMethod(bool nonPublic) + { + return ResolveMethodSymbol(UnderlyingEvent.GetRemoveMethod(nonPublic)); + } + + /// + public IMethodSymbol? GetRaiseMethod() + { + return ResolveMethodSymbol(UnderlyingEvent.GetRaiseMethod()); + } + + /// + public IMethodSymbol? GetRaiseMethod(bool nonPublic) + { + return ResolveMethodSymbol(UnderlyingEvent.GetRaiseMethod(nonPublic)); + } + + /// + public IMethodSymbol[] GetOtherMethods() + { + return ResolveMethodSymbols(UnderlyingEvent.GetOtherMethods()); + } + + /// + public IMethodSymbol[] GetOtherMethods(bool nonPublic) + { + return ResolveMethodSymbols(UnderlyingEvent.GetOtherMethods(nonPublic)); + } + + #endregion + + /// + public override void OnComplete() + { + _event = (EventInfo?)ResolvingModule.UnderlyingModule.ResolveMember(MetadataToken) ?? throw new InvalidOperationException(); + _builder = null; + base.OnComplete(); } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionFieldSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionFieldSymbolBuilder.cs index 241fbf8ed..5aa337c85 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionFieldSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionFieldSymbolBuilder.cs @@ -1,4 +1,5 @@ using System; +using System.Reflection; using System.Reflection.Emit; using IKVM.CoreLib.Symbols.Emit; @@ -6,81 +7,139 @@ namespace IKVM.CoreLib.Symbols.Reflection.Emit { - class ReflectionFieldSymbolBuilder : ReflectionSymbolBuilder, IFieldSymbolBuilder + class ReflectionFieldSymbolBuilder : ReflectionMemberSymbolBuilder, IReflectionFieldSymbolBuilder { - readonly ReflectionModuleSymbolBuilder _containingModuleBuilder; - readonly ReflectionTypeSymbolBuilder? _containingTypeBuilder; - readonly FieldBuilder _builder; - ReflectionFieldSymbol? _symbol; + FieldBuilder? _builder; + FieldInfo _field; /// /// Initializes a new instance. /// /// - /// + /// + /// /// - public ReflectionFieldSymbolBuilder(ReflectionSymbolContext context, ReflectionModuleSymbolBuilder containingModuleBuilder, FieldBuilder builder) : - base(context) + /// + public ReflectionFieldSymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol? resolvingType, FieldBuilder builder) : + base(context, resolvingModule, resolvingType) { - _containingModuleBuilder = containingModuleBuilder ?? throw new ArgumentNullException(nameof(containingModuleBuilder)); _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + _field = _builder; } - /// - /// Initializes a new instance. - /// - /// - /// - /// - public ReflectionFieldSymbolBuilder(ReflectionSymbolContext context, ReflectionTypeSymbolBuilder containingTypeBuilder, FieldBuilder builder) : - base(context) - { - _containingTypeBuilder = containingTypeBuilder ?? throw new ArgumentNullException(nameof(containingTypeBuilder)); - _containingModuleBuilder = containingTypeBuilder.ContainingModuleBuilder; - _builder = builder ?? throw new ArgumentNullException(nameof(builder)); - } - - /// - /// Gets the containing . - /// - internal ReflectionModuleSymbolBuilder ContainingModuleBuilder => _containingModuleBuilder; - - /// - /// Gets the containing . - /// - internal ReflectionTypeSymbolBuilder? ContainingTypeBuilder => _containingTypeBuilder; + /// + public FieldInfo UnderlyingField => _field; - /// - /// Gets the underlying - /// - internal FieldBuilder ReflectionBuilder => _builder; + /// + public override MemberInfo UnderlyingMember => UnderlyingField; /// - internal override ReflectionFieldSymbol ReflectionSymbol => _symbol ??= Context.GetOrCreateFieldSymbol(_builder); + public FieldBuilder UnderlyingFieldBuilder => _builder ?? throw new InvalidOperationException(); + + #region IFieldSymbolBuilder /// public void SetConstant(object? defaultValue) { - _builder.SetConstant(defaultValue); + UnderlyingFieldBuilder.SetConstant(defaultValue); } /// public void SetOffset(int iOffset) { - _builder.SetOffset(iOffset); + UnderlyingFieldBuilder.SetOffset(iOffset); } /// public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) { - _builder.SetCustomAttribute(con.Unpack(), binaryAttribute); + UnderlyingFieldBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); } /// public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) { - _builder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).ReflectionBuilder); + UnderlyingFieldBuilder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); + } + + #endregion + + #region IFieldSymbol + + /// + public FieldAttributes Attributes => UnderlyingField.Attributes; + + /// + public ITypeSymbol FieldType => ResolveTypeSymbol(UnderlyingField.FieldType); + + /// + public bool IsSpecialName => UnderlyingField.IsSpecialName; + + /// + public bool IsAssembly => UnderlyingField.IsAssembly; + + /// + public bool IsFamily => UnderlyingField.IsFamily; + + /// + public bool IsFamilyAndAssembly => UnderlyingField.IsFamilyAndAssembly; + + /// + public bool IsFamilyOrAssembly => UnderlyingField.IsFamilyOrAssembly; + + /// + public bool IsInitOnly => UnderlyingField.IsInitOnly; + + /// + public bool IsLiteral => UnderlyingField.IsLiteral; + +#pragma warning disable SYSLIB0050 // Type or member is obsolete + /// + public bool IsNotSerialized => UnderlyingField.IsNotSerialized; +#pragma warning restore SYSLIB0050 // Type or member is obsolete + + /// + public bool IsPinvokeImpl => UnderlyingField.IsPinvokeImpl; + + /// + public bool IsPrivate => UnderlyingField.IsPrivate; + + /// + public bool IsPublic => UnderlyingField.IsPublic; + + /// + public bool IsStatic => UnderlyingField.IsStatic; + + /// + public override bool IsComplete => _builder == null; + + /// + public ITypeSymbol[] GetOptionalCustomModifiers() + { + return ResolveTypeSymbols(UnderlyingField.GetOptionalCustomModifiers()); + } + + /// + public ITypeSymbol[] GetRequiredCustomModifiers() + { + return ResolveTypeSymbols(UnderlyingField.GetRequiredCustomModifiers()); + } + + /// + public object? GetRawConstantValue() + { + return UnderlyingField.GetRawConstantValue(); + } + + #endregion + + /// + public override void OnComplete() + { + _field = ResolvingModule.UnderlyingModule.ResolveField(MetadataToken) ?? throw new InvalidOperationException(); + _builder = null; + base.OnComplete(); } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionGenericTypeParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionGenericTypeParameterSymbolBuilder.cs new file mode 100644 index 000000000..2ea570755 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionGenericTypeParameterSymbolBuilder.cs @@ -0,0 +1,583 @@ +using System; +using System.Reflection; +using System.Reflection.Emit; + +using IKVM.CoreLib.Symbols.Emit; + +namespace IKVM.CoreLib.Symbols.Reflection.Emit +{ + + class ReflectionGenericTypeParameterSymbolBuilder : ReflectionMemberSymbolBuilder, IReflectionGenericTypeParameterSymbolBuilder + { + + readonly IReflectionMethodSymbol? _resolvingMethod; + + GenericTypeParameterBuilder? _builder; + Type _type; + ReflectionTypeImpl _impl; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + /// + /// + public ReflectionGenericTypeParameterSymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol? resolvingType, IReflectionMethodSymbol? resolvingMethod, GenericTypeParameterBuilder builder) : + base(context, resolvingModule, resolvingType) + { + _resolvingMethod = resolvingMethod; + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + _type = _builder; + _impl = new ReflectionTypeImpl(this); + } + + /// + public Type UnderlyingType => _type; + + /// + public override MemberInfo UnderlyingMember => UnderlyingType; + + /// + public GenericTypeParameterBuilder UnderlyingGenericTypeParameterBuilder => _builder ?? throw new InvalidOperationException(); + + #region ITypeSymbolBuilder + + /// + public void SetBaseTypeConstraint(ITypeSymbol? baseTypeConstraint) + { + UnderlyingGenericTypeParameterBuilder.SetBaseTypeConstraint(baseTypeConstraint?.Unpack()); + } + + /// + public void SetGenericParameterAttributes(GenericParameterAttributes genericParameterAttributes) + { + UnderlyingGenericTypeParameterBuilder.SetGenericParameterAttributes(genericParameterAttributes); + } + + /// + public void SetInterfaceConstraints(params ITypeSymbol[]? interfaceConstraints) + { + UnderlyingGenericTypeParameterBuilder.SetInterfaceConstraints(interfaceConstraints?.Unpack()); + } + + #endregion + + #region ITypeSymbol + + /// + public TypeAttributes Attributes => _impl.Attributes; + + /// + public IAssemblySymbol Assembly => _impl.Assembly; + + /// + public IMethodBaseSymbol? DeclaringMethod => _impl.DeclaringMethod; + + /// + public string? AssemblyQualifiedName => _impl.AssemblyQualifiedName; + + /// + public string? FullName => _impl.FullName; + + /// + public string? Namespace => _impl.Namespace; + + /// + public TypeCode TypeCode => _impl.TypeCode; + + /// + public ITypeSymbol? BaseType => _impl.BaseType; + + /// + public bool ContainsGenericParameters => _impl.ContainsGenericParameters; + + /// + public GenericParameterAttributes GenericParameterAttributes => _impl.GenericParameterAttributes; + + /// + public int GenericParameterPosition => _impl.GenericParameterPosition; + + /// + public ITypeSymbol[] GenericTypeArguments => _impl.GenericTypeArguments; + + /// + public bool IsConstructedGenericType => _impl.IsConstructedGenericType; + + /// + public bool IsGenericType => _impl.IsGenericType; + + /// + public bool IsGenericTypeDefinition => _impl.IsGenericTypeDefinition; + + /// + public bool IsGenericParameter => _impl.IsGenericParameter; + + /// + public bool IsAutoLayout => _impl.IsAutoLayout; + + /// + public bool IsExplicitLayout => _impl.IsExplicitLayout; + + /// + public bool IsLayoutSequential => _impl.IsLayoutSequential; + + /// + public bool HasElementType => _impl.HasElementType; + + /// + public bool IsClass => _impl.IsClass; + + /// + public bool IsValueType => _impl.IsValueType; + + /// + public bool IsInterface => _impl.IsInterface; + + /// + public bool IsPrimitive => _impl.IsPrimitive; + + /// + public bool IsSZArray => _impl.IsSZArray; + + /// + public bool IsArray => _impl.IsArray; + + /// + public bool IsEnum => _impl.IsEnum; + + /// + public bool IsPointer => _impl.IsPointer; + + /// + public bool IsFunctionPointer => _impl.IsFunctionPointer; + + /// + public bool IsUnmanagedFunctionPointer => _impl.IsUnmanagedFunctionPointer; + + /// + public bool IsByRef => _impl.IsByRef; + + /// + public bool IsAbstract => _impl.IsAbstract; + + /// + public bool IsSealed => _impl.IsSealed; + + /// + public bool IsVisible => _impl.IsVisible; + + /// + public bool IsPublic => _impl.IsPublic; + + /// + public bool IsNotPublic => _impl.IsNotPublic; + + /// + public bool IsNested => _impl.IsNested; + + /// + public bool IsNestedAssembly => _impl.IsNestedAssembly; + + /// + public bool IsNestedFamANDAssem => _impl.IsNestedFamANDAssem; + + /// + public bool IsNestedFamily => _impl.IsNestedFamily; + + /// + public bool IsNestedFamORAssem => _impl.IsNestedFamORAssem; + + /// + public bool IsNestedPrivate => _impl.IsNestedPrivate; + + /// + public bool IsNestedPublic => _impl.IsNestedPublic; + + /// + public bool IsSerializable => _impl.IsSerializable; + + /// + public bool IsSignatureType => _impl.IsSignatureType; + + /// + public bool IsSpecialName => _impl.IsSpecialName; + + /// + public IConstructorSymbol? TypeInitializer => _impl.TypeInitializer; + + /// + public override bool IsComplete => _builder == null; + + /// + public int GetArrayRank() + { + return _impl.GetArrayRank(); + } + + /// + public IMemberSymbol[] GetDefaultMembers() + { + return _impl.GetDefaultMembers(); + } + + /// + public ITypeSymbol? GetElementType() + { + return _impl.GetElementType(); + } + + /// + public string? GetEnumName(object value) + { + return _impl.GetEnumName(value); + } + + /// + public string[] GetEnumNames() + { + return _impl.GetEnumNames(); + } + + /// + public ITypeSymbol GetEnumUnderlyingType() + { + return _impl.GetEnumUnderlyingType(); + } + + /// + public ITypeSymbol[] GetGenericArguments() + { + return _impl.GetGenericArguments(); + } + + /// + public ITypeSymbol[] GetGenericParameterConstraints() + { + return _impl.GetGenericParameterConstraints(); + } + + /// + public ITypeSymbol GetGenericTypeDefinition() + { + return _impl.GetGenericTypeDefinition(); + } + + /// + public ITypeSymbol? GetInterface(string name) + { + return _impl.GetInterface(name); + } + + /// + public ITypeSymbol? GetInterface(string name, bool ignoreCase) + { + return _impl.GetInterface(name, ignoreCase); + } + + /// + public ITypeSymbol[] GetInterfaces(bool inherit = true) + { + return _impl.GetInterfaces(inherit); + } + + /// + public InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) + { + return _impl.GetInterfaceMap(interfaceType); + } + + /// + public IMemberSymbol[] GetMember(string name) + { + return _impl.GetMember(name); + } + + /// + public IMemberSymbol[] GetMember(string name, BindingFlags bindingAttr) + { + return _impl.GetMember(name, bindingAttr); + } + + /// + public IMemberSymbol[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) + { + return _impl.GetMember(name, type, bindingAttr); + } + + /// + public IMemberSymbol[] GetMembers() + { + return _impl.GetMembers(); + } + + /// + public IMemberSymbol[] GetMembers(BindingFlags bindingAttr) + { + return _impl.GetMembers(bindingAttr); + } + + public IConstructorSymbol? GetConstructor(ITypeSymbol[] types) + { + return _impl.GetConstructor(types); + } + + /// + public IConstructorSymbol? GetConstructor(BindingFlags bindingAttr, ITypeSymbol[] types) + { + return _impl.GetConstructor(bindingAttr, types); + } + + /// + public IConstructorSymbol[] GetConstructors() + { + return _impl.GetConstructors(); + } + + /// + public IConstructorSymbol[] GetConstructors(BindingFlags bindingAttr) + { + return _impl.GetConstructors(bindingAttr); + } + + /// + public IFieldSymbol? GetField(string name) + { + return _impl.GetField(name); + } + + /// + public IFieldSymbol? GetField(string name, BindingFlags bindingAttr) + { + return _impl.GetField(name, bindingAttr); + } + + /// + public IFieldSymbol[] GetFields() + { + return _impl.GetFields(); + } + + /// + public IFieldSymbol[] GetFields(BindingFlags bindingAttr) + { + return _impl.GetFields(bindingAttr); + } + + /// + public IMethodSymbol? GetMethod(string name) + { + return _impl.GetMethod(name); + } + + /// + public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) + { + return _impl.GetMethod(name, types); + } + + /// + public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr) + { + return _impl.GetMethod(name, bindingAttr); + } + + /// + public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types) + { + return _impl.GetMethod(name, bindingAttr, types); + } + + /// + public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers) + { + return _impl.GetMethod(name, bindingAttr, callConvention, types, modifiers); + } + + /// + public IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers) + { + return _impl.GetMethod(name, genericParameterCount, bindingAttr, callConvention, types, modifiers); + } + + /// + public IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, ITypeSymbol[] types, ParameterModifier[]? modifiers) + { + return _impl.GetMethod(name, genericParameterCount, bindingAttr, types, modifiers); + } + + /// + public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types, ParameterModifier[]? modifiers) + { + return _impl.GetMethod(name, bindingAttr, types, modifiers); + } + + /// + public IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, ParameterModifier[]? modifiers) + { + return _impl.GetMethod(name, genericParameterCount, types, modifiers); + } + + /// + public IMethodSymbol[] GetMethods() + { + return _impl.GetMethods(); + } + + /// + public IMethodSymbol[] GetMethods(BindingFlags bindingAttr) + { + return _impl.GetMethods(bindingAttr); + } + + /// + public IPropertySymbol? GetProperty(string name) + { + return _impl.GetProperty(name); + } + + /// + public IPropertySymbol? GetProperty(string name, BindingFlags bindingAttr) + { + return _impl.GetProperty(name, bindingAttr); + } + + /// + public IPropertySymbol? GetProperty(string name, ITypeSymbol[] types) + { + return _impl.GetProperty(name, types); + } + + /// + public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types) + { + return _impl.GetProperty(name, returnType, types); + } + + /// + public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) + { + return _impl.GetProperty(name, returnType); + } + + /// + public IPropertySymbol[] GetProperties() + { + return _impl.GetProperties(); + } + + /// + public IPropertySymbol[] GetProperties(BindingFlags bindingAttr) + { + return _impl.GetProperties(bindingAttr); + } + + /// + public IEventSymbol? GetEvent(string name) + { + return _impl.GetEvent(name); + } + + /// + public IEventSymbol? GetEvent(string name, BindingFlags bindingAttr) + { + return _impl.GetEvent(name, bindingAttr); + } + + /// + public IEventSymbol[] GetEvents() + { + return _impl.GetEvents(); + } + + /// + public IEventSymbol[] GetEvents(BindingFlags bindingAttr) + { + return _impl.GetEvents(bindingAttr); + } + + /// + public ITypeSymbol? GetNestedType(string name) + { + return _impl.GetNestedType(name); + } + + /// + public ITypeSymbol? GetNestedType(string name, BindingFlags bindingAttr) + { + return _impl.GetNestedType(name, bindingAttr); + } + + /// + public ITypeSymbol[] GetNestedTypes() + { + return _impl.GetNestedTypes(); + } + + /// + public ITypeSymbol[] GetNestedTypes(BindingFlags bindingAttr) + { + return _impl.GetNestedTypes(); + } + + /// + public bool IsAssignableFrom(ITypeSymbol? c) + { + return _impl.IsAssignableFrom(c); + } + + /// + public bool IsSubclassOf(ITypeSymbol c) + { + return _impl.IsSubclassOf(c); + } + + /// + public bool IsEnumDefined(object value) + { + return _impl.IsEnumDefined(value); + } + + /// + public ITypeSymbol MakeArrayType() + { + return _impl.MakeArrayType(); + } + + /// + public ITypeSymbol MakeArrayType(int rank) + { + return _impl.MakeArrayType(rank); + } + + /// + public ITypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments) + { + return _impl.MakeGenericType(typeArguments); + } + + /// + public ITypeSymbol MakePointerType() + { + return _impl.MakePointerType(); + } + + /// + public ITypeSymbol MakeByRefType() + { + return _impl.MakeByRefType(); + } + + #endregion + + /// + public override void OnComplete() + { + throw new NotImplementedException(); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMemberSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMemberSymbolBuilder.cs new file mode 100644 index 000000000..872761376 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMemberSymbolBuilder.cs @@ -0,0 +1,392 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Reflection; +using System.Reflection.Emit; + +using IKVM.CoreLib.Reflection; + +namespace IKVM.CoreLib.Symbols.Reflection.Emit +{ + + abstract class ReflectionMemberSymbolBuilder : ReflectionSymbolBuilder, IReflectionMemberSymbolBuilder + { + + /// + /// Concatinates the list of arrays. + /// + /// + /// + static T[] Concat(List? list) + { + if (list == null) + return []; + + var c = 0; + foreach (var i in list) + c += i.Length; + + if (c == 0) + return []; + + var t = 0; + var a = new T[c]; + foreach (var i in list) + { + Array.Copy(i, 0, a, t, i.Length); + t += i.Length; + } + + return a; + } + + readonly IReflectionModuleSymbol _resolvingModule; + readonly IReflectionTypeSymbol? _resolvingType; + + CustomAttribute[]? _customAttributes; + CustomAttribute[]? _inheritedCustomAttributes; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + public ReflectionMemberSymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol? resolvingType) : + base(context) + { + _resolvingModule = resolvingModule ?? throw new ArgumentNullException(nameof(resolvingModule)); + _resolvingType = resolvingType; + } + + #region IMemberSymbol + + /// + public abstract MemberInfo UnderlyingMember { get; } + + /// + public IReflectionModuleSymbol ResolvingModule => _resolvingModule; + + /// + public IReflectionTypeSymbol? ResolvingType => ResolvingType; + + /// + public virtual IModuleSymbol Module => ResolveModuleSymbol(UnderlyingMember.Module)!; + + /// + public virtual ITypeSymbol? DeclaringType => ResolveTypeSymbol(UnderlyingMember.DeclaringType)!; + + /// + public virtual MemberTypes MemberType => UnderlyingMember.MemberType; + + /// + public virtual int MetadataToken => UnderlyingMember.GetMetadataTokenSafe(); + + /// + public virtual string Name => UnderlyingMember.Name; + + /// + public virtual CustomAttribute[] GetCustomAttributes(bool inherit = false) + { + if (inherit) + { + // check that we've already processed this + if (_inheritedCustomAttributes != null) + return _inheritedCustomAttributes; + + var self = UnderlyingMember; + var list = default(List?); + for (; ; ) + { + if (self == null) + throw new InvalidOperationException(); + + // get attribute for current member and append to list + var attr = ResolveMemberSymbol(self)!.GetCustomAttributes(false); + if (attr.Length > 0) + { + list ??= []; + list.Add(attr); + } + + var type = self as Type; + if (type != null) + { + type = type.BaseType; + if (type == null) + return _inheritedCustomAttributes ??= Concat(list); + + self = type; + continue; + } + + var method = self as MethodInfo; + if (method != null) + { + var prev = self; + method = method.GetBaseDefinition(); + if (method == null || method == prev) + return _inheritedCustomAttributes ??= Concat(list); + + self = method; + continue; + } + + return _inheritedCustomAttributes ??= Concat(list); + } + } + + return _customAttributes ??= ResolveCustomAttributes(UnderlyingMember.GetCustomAttributesData())!; + } + + /// + public virtual CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) + { + return GetCustomAttributes(inherit).Where(i => i.AttributeType == attributeType).ToArray(); + } + + /// + public virtual CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) + { + return GetCustomAttributes(attributeType, inherit).FirstOrDefault(); + } + + /// + public virtual bool IsDefined(ITypeSymbol attributeType, bool inherit = false) + { + return UnderlyingMember.IsDefined(attributeType.Unpack(), inherit); + } + + #endregion + + /// + [return: NotNullIfNotNull(nameof(type))] + public override IReflectionTypeSymbol? ResolveTypeSymbol(Type? type) + { + if (type is null) + return null; + + if (UnderlyingMember == type) + return (IReflectionTypeSymbol)this; + + if (_resolvingType != null && type == _resolvingType.UnderlyingType) + return _resolvingType; + + if (type.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateTypeSymbol(type); + + return base.ResolveTypeSymbol(type); + } + + /// + [return: NotNullIfNotNull("type")] + public override IReflectionTypeSymbolBuilder ResolveTypeSymbol(TypeBuilder type) + { + if (type is null) + throw new ArgumentNullException(nameof(type)); + + if (UnderlyingMember == type) + return (IReflectionTypeSymbolBuilder)this; + + if (_resolvingType != null && type == _resolvingType.UnderlyingType) + return (IReflectionTypeSymbolBuilder)_resolvingType; + + if (type.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateTypeSymbol(type); + + return base.ResolveTypeSymbol(type); + } + + /// + [return: NotNullIfNotNull(nameof(ctor))] + public override IReflectionConstructorSymbol? ResolveConstructorSymbol(ConstructorInfo? ctor) + { + if (ctor is null) + return null; + + if (UnderlyingMember == ctor) + return (IReflectionConstructorSymbol)this; + + if (ctor.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateConstructorSymbol(ctor); + + return base.ResolveConstructorSymbol(ctor); + } + + /// + [return: NotNullIfNotNull(nameof(ctor))] + public override IReflectionConstructorSymbolBuilder ResolveConstructorSymbol(ConstructorBuilder ctor) + { + if (ctor is null) + throw new ArgumentNullException(nameof(ctor)); + + if (UnderlyingMember == ctor) + return (IReflectionConstructorSymbolBuilder)this; + + if (ctor.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateConstructorSymbol(ctor); + + return base.ResolveConstructorSymbol(ctor); + } + + /// + [return: NotNullIfNotNull(nameof(method))] + public override IReflectionMethodSymbol? ResolveMethodSymbol(MethodInfo? method) + { + if (method is null) + return null; + + if (UnderlyingMember == method) + return (IReflectionMethodSymbol)this; + + if (method.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateMethodSymbol(method); + + return base.ResolveMethodSymbol(method); + } + + /// + [return: NotNullIfNotNull(nameof(method))] + public override IReflectionMethodSymbolBuilder ResolveMethodSymbol(MethodBuilder method) + { + if (method is null) + throw new ArgumentNullException(nameof(method)); + + if (UnderlyingMember == method) + return (IReflectionMethodSymbolBuilder)this; + + if (method.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateMethodSymbol(method); + + return base.ResolveMethodSymbol(method); + } + + /// + [return: NotNullIfNotNull(nameof(field))] + public override IReflectionFieldSymbol? ResolveFieldSymbol(FieldInfo? field) + { + if (field is null) + return null; + + if (UnderlyingMember == field) + return (IReflectionFieldSymbol)this; + + if (field.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateFieldSymbol(field); + + return base.ResolveFieldSymbol(field); + } + + /// + [return: NotNullIfNotNull(nameof(field))] + public override IReflectionFieldSymbolBuilder ResolveFieldSymbol(FieldBuilder field) + { + if (field is null) + throw new ArgumentNullException(nameof(field)); + + if (UnderlyingMember == field) + return (IReflectionFieldSymbolBuilder)this; + + if (field.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateFieldSymbol(field); + + return base.ResolveFieldSymbol(field); + } + + /// + [return: NotNullIfNotNull(nameof(property))] + public override IReflectionPropertySymbol? ResolvePropertySymbol(PropertyInfo? property) + { + if (property is null) + return null; + + if (UnderlyingMember == property) + return (IReflectionPropertySymbol)this; + + if (property.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreatePropertySymbol(property); + + return base.ResolvePropertySymbol(property); + } + + /// + [return: NotNullIfNotNull(nameof(property))] + public override IReflectionPropertySymbolBuilder ResolvePropertySymbol(PropertyBuilder property) + { + if (property is null) + throw new ArgumentNullException(nameof(property)); + + if (UnderlyingMember == property) + return (IReflectionPropertySymbolBuilder)this; + + if (property.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreatePropertySymbol(property); + + return base.ResolvePropertySymbol(property); + } + + /// + [return: NotNullIfNotNull(nameof(@event))] + public override IReflectionEventSymbol? ResolveEventSymbol(EventInfo? @event) + { + if (@event is null) + return null; + + if (UnderlyingMember == @event) + return (IReflectionEventSymbol)this; + + if (@event.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateEventSymbol(@event); + + return base.ResolveEventSymbol(@event); + } + + /// + [return: NotNullIfNotNull(nameof(@event))] + public override IReflectionEventSymbolBuilder ResolveEventSymbol(EventBuilder @event) + { + if (@event is null) + throw new ArgumentNullException(nameof(@event)); + + if (@event.GetModuleBuilder() == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateEventSymbol(@event); + + return base.ResolveEventSymbol(@event); + } + + /// + [return: NotNullIfNotNull(nameof(parameter))] + public override IReflectionParameterSymbol? ResolveParameterSymbol(ParameterInfo? parameter) + { + if (parameter is null) + throw new ArgumentNullException(nameof(parameter)); + + if (parameter.Member.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateParameterSymbol(parameter); + + return base.ResolveParameterSymbol(parameter); + } + + /// + [return: NotNullIfNotNull(nameof(parameter))] + public override IReflectionParameterSymbolBuilder ResolveParameterSymbol(ParameterBuilder parameter) + { + if (parameter is null) + throw new ArgumentNullException(nameof(parameter)); + + if (parameter.GetModuleBuilder() == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateParameterSymbol(parameter); + + return base.ResolveParameterSymbol(parameter); + } + + /// + public virtual void OnComplete() + { + + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodBaseSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodBaseSymbolBuilder.cs index f260f6819..b662e1a59 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodBaseSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodBaseSymbolBuilder.cs @@ -1,48 +1,123 @@ -using System; +using System.Reflection; + +using IKVM.CoreLib.Symbols.Emit; namespace IKVM.CoreLib.Symbols.Reflection.Emit { - abstract class ReflectionMethodBaseSymbolBuilder : ReflectionSymbolBuilder - where TSymbol : ISymbol - where TReflectionSymbol : ReflectionSymbol, TSymbol + abstract class ReflectionMethodBaseSymbolBuilder : ReflectionMemberSymbolBuilder, IReflectionMethodBaseSymbolBuilder { - readonly ReflectionModuleSymbolBuilder _containingModuleBuilder; - readonly ReflectionTypeSymbolBuilder? _containingTypeBuilder; - /// /// Initializes a new instance. /// /// - /// - protected ReflectionMethodBaseSymbolBuilder(ReflectionSymbolContext context, ReflectionTypeSymbolBuilder containingTypeBuilder) : - base(context) + /// + /// + public ReflectionMethodBaseSymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol? resolvingType) : + base(context, resolvingModule, resolvingType) { - _containingTypeBuilder = containingTypeBuilder ?? throw new ArgumentNullException(nameof(containingTypeBuilder)); - _containingModuleBuilder = containingTypeBuilder.ContainingModuleBuilder; + } - /// - /// Initializes a new instance. - /// - /// - /// - protected ReflectionMethodBaseSymbolBuilder(ReflectionSymbolContext context, ReflectionModuleSymbolBuilder containingModuleBuilder) : - base(context) + /// + public abstract MethodBase UnderlyingMethodBase { get; } + + /// + public override MemberInfo UnderlyingMember => UnderlyingMethodBase; + + #region IMethodBaseSymbol + + /// + public MethodAttributes Attributes => UnderlyingMethodBase.Attributes; + + /// + public CallingConventions CallingConvention => UnderlyingMethodBase.CallingConvention; + + /// + public bool ContainsGenericParameters => UnderlyingMethodBase.ContainsGenericParameters; + + /// + public bool IsAbstract => UnderlyingMethodBase.IsAbstract; + + /// + public bool IsAssembly => UnderlyingMethodBase.IsAssembly; + + /// + public bool IsConstructor => UnderlyingMethodBase.IsConstructor; + + /// + public bool IsFamily => UnderlyingMethodBase.IsFamily; + + /// + public bool IsFamilyAndAssembly => UnderlyingMethodBase.IsFamilyAndAssembly; + + /// + public bool IsFamilyOrAssembly => UnderlyingMethodBase.IsFamilyOrAssembly; + + /// + public bool IsFinal => UnderlyingMethodBase.IsFinal; + + /// + public bool IsGenericMethod => UnderlyingMethodBase.IsGenericMethod; + + /// + public bool IsGenericMethodDefinition => UnderlyingMethodBase.IsGenericMethodDefinition; + + /// + public bool IsHideBySig => UnderlyingMethodBase.IsHideBySig; + + /// + public bool IsPrivate => UnderlyingMethodBase.IsPrivate; + + /// + public bool IsPublic => UnderlyingMethodBase.IsPublic; + + /// + public bool IsStatic => UnderlyingMethodBase.IsStatic; + + /// + public bool IsVirtual => UnderlyingMethodBase.IsVirtual; + + /// + public bool IsSpecialName => UnderlyingMethodBase.IsSpecialName; + + /// + public MethodImplAttributes MethodImplementationFlags => UnderlyingMethodBase.MethodImplementationFlags; + + /// + public ITypeSymbol[] GetGenericArguments() { - _containingModuleBuilder = containingModuleBuilder ?? throw new ArgumentNullException(nameof(containingModuleBuilder)); + return ResolveTypeSymbols(UnderlyingMethodBase.GetGenericArguments()); } - /// - /// Gets the containing . - /// - protected internal ReflectionModuleSymbolBuilder ContainingModuleBuilder => _containingModuleBuilder; + /// + public MethodImplAttributes GetMethodImplementationFlags() + { + return UnderlyingMethodBase.GetMethodImplementationFlags(); + } - /// - /// Gets the containing . - /// - protected internal ReflectionTypeSymbolBuilder? ContainingTypeBuilder => _containingTypeBuilder; + /// + public IParameterSymbol[] GetParameters() + { + return ResolveParameterSymbols(UnderlyingMethodBase.GetParameters()); + } + + #endregion + + /// + public override void OnComplete() + { + foreach (var i in GetGenericArguments()) + if (i is IReflectionGenericTypeParameterSymbolBuilder b) + b.OnComplete(); + + foreach (var i in GetParameters()) + if (i is IReflectionParameterSymbolBuilder b) + b.OnComplete(); + + base.OnComplete(); + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs index ce4b91294..e0c2fb3e8 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs @@ -7,77 +7,76 @@ namespace IKVM.CoreLib.Symbols.Reflection.Emit { - class ReflectionMethodSymbolBuilder : ReflectionMethodBaseSymbolBuilder, IMethodSymbolBuilder + class ReflectionMethodSymbolBuilder : ReflectionMethodBaseSymbolBuilder, IReflectionMethodSymbolBuilder { - readonly MethodBuilder _builder; - ReflectionMethodSymbol? _symbol; + MethodBuilder? _builder; + MethodInfo _method; /// /// Initializes a new instance. /// /// - /// + /// + /// /// - public ReflectionMethodSymbolBuilder(ReflectionSymbolContext context, ReflectionModuleSymbolBuilder containingModuleBuilder, MethodBuilder builder) : - base(context, containingModuleBuilder) + /// + public ReflectionMethodSymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol? resolvingType, MethodBuilder builder) : + base(context, resolvingModule, resolvingType) { _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + _method = _builder; } - /// - /// Initializes a new instance. - /// - /// - /// - /// - public ReflectionMethodSymbolBuilder(ReflectionSymbolContext context, ReflectionTypeSymbolBuilder containingTypeBuilder, MethodBuilder builder) : - base(context, containingTypeBuilder) - { - _builder = builder ?? throw new ArgumentNullException(nameof(builder)); - } + /// + public MethodInfo UnderlyingMethod => _method; - /// - /// Gets the that underlies this instance. - /// - internal MethodBuilder ReflectionBuilder => _builder; + /// + public override MethodBase UnderlyingMethodBase => UnderlyingMethod; /// - internal override ReflectionMethodSymbol ReflectionSymbol => _symbol ??= Context.GetOrCreateMethodSymbol(_builder); + public MethodBuilder UnderlyingMethodBuilder => _builder ?? throw new InvalidOperationException(); + + #region IMethodSymbolBuilder /// public void SetImplementationFlags(MethodImplAttributes attributes) { - _builder.SetImplementationFlags(attributes); + UnderlyingMethodBuilder.SetImplementationFlags(attributes); } /// public void SetParameters(params ITypeSymbol[] parameterTypes) { - _builder.SetParameters(parameterTypes.Unpack()); + UnderlyingMethodBuilder.SetParameters(parameterTypes.Unpack()); } /// public void SetReturnType(ITypeSymbol? returnType) { - _builder.SetReturnType(returnType?.Unpack()); + UnderlyingMethodBuilder.SetReturnType(returnType?.Unpack()); } /// public void SetSignature(ITypeSymbol? returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers) { - _builder.SetSignature(returnType?.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack()); + UnderlyingMethodBuilder.SetSignature(returnType?.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack()); } public IGenericTypeParameterSymbolBuilder[] DefineGenericParameters(params string[] names) { - throw new NotImplementedException(); + var l = UnderlyingMethodBuilder.DefineGenericParameters(names); + var a = new IGenericTypeParameterSymbolBuilder[l.Length]; + for (int i = 0; i < l.Length; i++) + a[i] = new ReflectionGenericTypeParameterSymbolBuilder(Context, ResolvingModule, ResolvingType, this, l[i]); + + return a; } /// public IParameterSymbolBuilder DefineParameter(int position, ParameterAttributes attributes, string? strParamName) { - return new ReflectionParameterSymbolBuilder(Context, this, _builder.DefineParameter(position, attributes, strParamName)); + return new ReflectionParameterSymbolBuilder(Context, ResolvingModule, this, UnderlyingMethodBuilder.DefineParameter(position, attributes, strParamName)); } public IILGenerator GetILGenerator() @@ -93,13 +92,57 @@ public IILGenerator GetILGenerator(int size) /// public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) { - _builder.SetCustomAttribute(con.Unpack(), binaryAttribute); + UnderlyingMethodBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); } /// public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) { - _builder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).ReflectionBuilder); + UnderlyingMethodBuilder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); + } + + #endregion + + #region IMethodSymbol + + /// + public IParameterSymbol ReturnParameter => ResolveParameterSymbol(UnderlyingMethod.ReturnParameter); + + /// + public ITypeSymbol ReturnType => ResolveTypeSymbol(UnderlyingMethod.ReturnType); + + /// + public ICustomAttributeProvider ReturnTypeCustomAttributes => throw new NotImplementedException(); + + /// + public override bool IsComplete => _builder == null; + + /// + public IMethodSymbol GetBaseDefinition() + { + return ResolveMethodSymbol(UnderlyingMethod.GetBaseDefinition()); + } + + /// + public IMethodSymbol GetGenericMethodDefinition() + { + return ResolveMethodSymbol(UnderlyingMethod.GetGenericMethodDefinition()); + } + + /// + public IMethodSymbol MakeGenericMethod(params ITypeSymbol[] typeArguments) + { + return ResolveMethodSymbol(UnderlyingMethod.MakeGenericMethod(typeArguments.Unpack())); + } + + #endregion + + /// + public override void OnComplete() + { + _method = (MethodInfo?)ResolvingModule.UnderlyingModule.ResolveMethod(MetadataToken) ?? throw new InvalidOperationException(); + _builder = null; + base.OnComplete(); } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionModuleSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionModuleSymbolBuilder.cs index 0861c2c9e..3a64b5df3 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionModuleSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionModuleSymbolBuilder.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using System.Reflection; using System.Reflection.Emit; @@ -7,90 +8,372 @@ namespace IKVM.CoreLib.Symbols.Reflection.Emit { - class ReflectionModuleSymbolBuilder : ReflectionSymbolBuilder, IModuleSymbolBuilder + class ReflectionModuleSymbolBuilder : ReflectionSymbolBuilder, IReflectionModuleSymbolBuilder { + readonly IReflectionAssemblySymbol _resolvingAssembly; + readonly ModuleBuilder _builder; - ReflectionModuleSymbol? _symbol; + ReflectionModuleMetadata _metadata; /// /// Initializes a new instance. /// /// + /// /// - public ReflectionModuleSymbolBuilder(ReflectionSymbolContext context, ModuleBuilder builder) : + /// + public ReflectionModuleSymbolBuilder(ReflectionSymbolContext context, IReflectionAssemblySymbol resolvingAssembly, ModuleBuilder builder) : base(context) { + _resolvingAssembly = resolvingAssembly ?? throw new ArgumentNullException(nameof(resolvingAssembly)); _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + _metadata = new ReflectionModuleMetadata(this); } /// - internal override ReflectionModuleSymbol ReflectionSymbol => _symbol ??= Context.GetOrCreateModuleSymbol(_builder); + public Module UnderlyingModule => UnderlyingModuleBuilder; + + /// + public ModuleBuilder UnderlyingModuleBuilder => _builder; + + /// + public IReflectionAssemblySymbol ResolvingAssembly => _resolvingAssembly; + + #region IModuleSymbolBuilder /// public ITypeSymbolBuilder DefineType(string name) { - return new ReflectionTypeSymbolBuilder(Context, this, _builder.DefineType(name)); + return (ITypeSymbolBuilder)ResolveTypeSymbol(UnderlyingModuleBuilder.DefineType(name)); } /// public ITypeSymbolBuilder DefineType(string name, TypeAttributes attr, ITypeSymbol? parent, int typesize) { - return new ReflectionTypeSymbolBuilder(Context, this, _builder.DefineType(name, attr, parent?.Unpack(), typesize)); + return (ITypeSymbolBuilder)ResolveTypeSymbol(UnderlyingModuleBuilder.DefineType(name, attr, parent?.Unpack(), typesize)); } /// public ITypeSymbolBuilder DefineType(string name, TypeAttributes attr, ITypeSymbol? parent) { - return new ReflectionTypeSymbolBuilder(Context, this, _builder.DefineType(name, attr, parent?.Unpack())); + return (ITypeSymbolBuilder)ResolveTypeSymbol(UnderlyingModuleBuilder.DefineType(name, attr, parent?.Unpack())); } /// public ITypeSymbolBuilder DefineType(string name, TypeAttributes attr) { - return new ReflectionTypeSymbolBuilder(Context, this, _builder.DefineType(name, attr)); + return (ITypeSymbolBuilder)ResolveTypeSymbol(UnderlyingModuleBuilder.DefineType(name, attr)); } /// public ITypeSymbolBuilder DefineType(string name, TypeAttributes attr, ITypeSymbol? parent, PackingSize packsize) { - return new ReflectionTypeSymbolBuilder(Context, this, _builder.DefineType(name, attr, parent?.Unpack(), packsize)); + return (ITypeSymbolBuilder)ResolveTypeSymbol(UnderlyingModuleBuilder.DefineType(name, attr, parent?.Unpack(), packsize)); } /// public ITypeSymbolBuilder DefineType(string name, TypeAttributes attr, ITypeSymbol? parent, PackingSize packingSize, int typesize) { - return new ReflectionTypeSymbolBuilder(Context, this, _builder.DefineType(name, attr, parent?.Unpack(), packingSize, typesize)); + return (ITypeSymbolBuilder)ResolveTypeSymbol(UnderlyingModuleBuilder.DefineType(name, attr, parent?.Unpack(), packingSize, typesize)); } /// public ITypeSymbolBuilder DefineType(string name, TypeAttributes attr, ITypeSymbol? parent, ITypeSymbol[]? interfaces) { - return new ReflectionTypeSymbolBuilder(Context, this, _builder.DefineType(name, attr, parent?.Unpack(), interfaces?.Unpack())); + return (ITypeSymbolBuilder)ResolveTypeSymbol(UnderlyingModuleBuilder.DefineType(name, attr, parent?.Unpack(), interfaces?.Unpack())); } /// public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) { - _builder.SetCustomAttribute(con.Unpack(), binaryAttribute); + UnderlyingModuleBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); } /// public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) { - _builder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).ReflectionBuilder); + UnderlyingModuleBuilder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); + } + + #endregion + + #region IModuleSymbol + + /// + public IAssemblySymbol Assembly => ResolveAssemblySymbol(UnderlyingModule.Assembly); + + /// + public string FullyQualifiedName => UnderlyingModule.FullyQualifiedName; + + /// + public int MetadataToken => UnderlyingModule.MetadataToken; + + /// + public Guid ModuleVersionId => UnderlyingModule.ModuleVersionId; + + /// + public string Name => UnderlyingModule.Name; + + /// + public string ScopeName => UnderlyingModule.ScopeName; + + /// + public override bool IsComplete => _builder == null; + + /// + public IFieldSymbol? GetField(string name) + { + return ResolveFieldSymbol(UnderlyingModule.GetField(name)); + } + + /// + public IFieldSymbol? GetField(string name, BindingFlags bindingAttr) + { + return ResolveFieldSymbol(UnderlyingModule.GetField(name, bindingAttr)); + } + + /// + public IFieldSymbol[] GetFields(BindingFlags bindingFlags) + { + return ResolveFieldSymbols(UnderlyingModule.GetFields(bindingFlags))!; + } + + /// + public IFieldSymbol[] GetFields() + { + return ResolveFieldSymbols(UnderlyingModule.GetFields())!; + } + + /// + public IMethodSymbol? GetMethod(string name) + { + return ResolveMethodSymbol(UnderlyingModule.GetMethod(name)); + } + + /// + public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) + { + return ResolveMethodSymbol(UnderlyingModule.GetMethod(name, types.Unpack())); + } + + /// + public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers) + { + return ResolveMethodSymbol(UnderlyingModule.GetMethod(name, bindingAttr, null, callConvention, types.Unpack(), modifiers)); + } + + /// + public IMethodSymbol[] GetMethods() + { + return ResolveMethodSymbols(UnderlyingModule.GetMethods())!; + } + + /// + public IMethodSymbol[] GetMethods(BindingFlags bindingFlags) + { + return ResolveMethodSymbols(UnderlyingModule.GetMethods(bindingFlags))!; + } + + /// + public ITypeSymbol? GetType(string className) + { + return ResolveTypeSymbol(UnderlyingModule.GetType(className)); + } + + /// + public ITypeSymbol? GetType(string className, bool ignoreCase) + { + return ResolveTypeSymbol(UnderlyingModule.GetType(className, ignoreCase)); + } + + /// + public ITypeSymbol? GetType(string className, bool throwOnError, bool ignoreCase) + { + return ResolveTypeSymbol(UnderlyingModule.GetType(className, throwOnError, ignoreCase)); + } + + /// + public ITypeSymbol[] GetTypes() + { + return ResolveTypeSymbols(UnderlyingModule.GetTypes())!; + } + + /// + public bool IsResource() + { + return UnderlyingModule.IsResource(); + } + + /// + public IFieldSymbol? ResolveField(int metadataToken) + { + return ResolveFieldSymbol(UnderlyingModule.ResolveField(metadataToken)); + } + + /// + public IFieldSymbol? ResolveField(int metadataToken, ITypeSymbol[]? genericTypeArguments, ITypeSymbol[]? genericMethodArguments) + { + return ResolveFieldSymbol(UnderlyingModule.ResolveField(metadataToken, genericTypeArguments?.Unpack(), genericMethodArguments?.Unpack())); + } + + /// + public IMemberSymbol? ResolveMember(int metadataToken) + { + return ResolveMemberSymbol(UnderlyingModule.ResolveMember(metadataToken)); + } + + /// + public IMemberSymbol? ResolveMember(int metadataToken, ITypeSymbol[]? genericTypeArguments, ITypeSymbol[]? genericMethodArguments) + { + return ResolveMemberSymbol(UnderlyingModule.ResolveMember(metadataToken, genericTypeArguments?.Unpack(), genericMethodArguments?.Unpack())); + } + + /// + public IMethodBaseSymbol? ResolveMethod(int metadataToken, ITypeSymbol[]? genericTypeArguments, ITypeSymbol[]? genericMethodArguments) + { + return ResolveMethodBaseSymbol(UnderlyingModule.ResolveMethod(metadataToken, genericTypeArguments?.Unpack(), genericMethodArguments?.Unpack())); + } + + /// + public IMethodBaseSymbol? ResolveMethod(int metadataToken) + { + return ResolveMethodBaseSymbol(UnderlyingModule.ResolveMethod(metadataToken)); + } + + /// + public byte[] ResolveSignature(int metadataToken) + { + return UnderlyingModule.ResolveSignature(metadataToken); + } + + /// + public string ResolveString(int metadataToken) + { + return UnderlyingModule.ResolveString(metadataToken); + } + + /// + public ITypeSymbol ResolveType(int metadataToken) + { + return ResolveTypeSymbol(UnderlyingModule.ResolveType(metadataToken)); } /// - public void Complete() + public ITypeSymbol ResolveType(int metadataToken, ITypeSymbol[]? genericTypeArguments, ITypeSymbol[]? genericMethodArguments) { - _builder.CreateGlobalFunctions(); + return ResolveTypeSymbol(UnderlyingModule.ResolveType(metadataToken, genericTypeArguments?.Unpack(), genericMethodArguments?.Unpack())); + } + + /// + public CustomAttribute[] GetCustomAttributes(bool inherit = false) + { + return ResolveCustomAttributes(UnderlyingModule.GetCustomAttributesData()); + } + + /// + public CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) + { + var _attributeType = attributeType.Unpack(); + return ResolveCustomAttributes(UnderlyingModule.GetCustomAttributesData().Where(i => i.AttributeType == _attributeType).ToArray()); + } + + /// + public CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) + { + return GetCustomAttributes(attributeType, inherit).FirstOrDefault(); + } + + /// + public bool IsDefined(ITypeSymbol attributeType, bool inherit = false) + { + return UnderlyingModule.IsDefined(attributeType.Unpack(), false); + } + + #endregion + + /// + public IReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) + { + return _metadata.GetOrCreateTypeSymbol(type); + } + + /// + public IReflectionTypeSymbolBuilder GetOrCreateTypeSymbol(TypeBuilder type) + { + return _metadata.GetOrCreateTypeSymbol(type); + } - foreach (var type in _builder.GetTypes()) - if (type is TypeBuilder typeBuilder) - if (typeBuilder.IsCreated() == false) - if (typeBuilder.CreateType() is { } t) - ReflectionSymbol.ResolveTypeSymbol(t).Complete(t); + /// + public IReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) + { + return _metadata.GetOrCreateConstructorSymbol(ctor); + } + + /// + public IReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor) + { + return _metadata.GetOrCreateConstructorSymbol(ctor); + } + + /// + public IReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) + { + return _metadata.GetOrCreateMethodSymbol(method); + } + + /// + public IReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method) + { + return _metadata.GetOrCreateMethodSymbol(method); + } + + /// + public IReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) + { + return _metadata.GetOrCreateFieldSymbol(field); + } + + /// + public IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field) + { + return _metadata.GetOrCreateFieldSymbol(field); + } + + /// + public IReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) + { + return _metadata.GetOrCreatePropertySymbol(property); + } + + /// + public IReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property) + { + return _metadata.GetOrCreatePropertySymbol(property); + } + + /// + public IReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) + { + return _metadata.GetOrCreateEventSymbol(@event); + } + + /// + public IReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event) + { + return _metadata.GetOrCreateEventSymbol(@event); + } + + /// + public IReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) + { + return _metadata.GetOrCreateParameterSymbol(parameter); + } + + /// + public IReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter) + { + return _metadata.GetOrCreateParameterSymbol(parameter); } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionParameterBuilderInfo.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionParameterBuilderInfo.cs index bb28d0082..816de787d 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionParameterBuilderInfo.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionParameterBuilderInfo.cs @@ -1,6 +1,7 @@ using System; using System.Reflection; using System.Reflection.Emit; +using IKVM.CoreLib.Reflection; namespace IKVM.CoreLib.Symbols.Reflection.Emit { @@ -12,15 +13,18 @@ class ReflectionParameterBuilderInfo : ParameterInfo { readonly ParameterBuilder _builder; + readonly Func _getDefaultValue; /// /// Initialies a new instance. /// /// + /// /// - public ReflectionParameterBuilderInfo(ParameterBuilder builder) + public ReflectionParameterBuilderInfo(ParameterBuilder builder, Func getDefaultValue) { _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + _getDefaultValue = getDefaultValue ?? throw new ArgumentNullException(nameof(getDefaultValue)); } /// @@ -38,6 +42,9 @@ public ReflectionParameterBuilderInfo(ParameterBuilder builder) /// public override int MetadataToken => _builder.GetMetadataToken(); + /// + public override object? DefaultValue => _getDefaultValue(); + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionParameterSymbolBuilder.cs index fa908dac8..5495e484b 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionParameterSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionParameterSymbolBuilder.cs @@ -1,4 +1,6 @@ using System; +using System.Linq; +using System.Reflection; using System.Reflection.Emit; using IKVM.CoreLib.Symbols.Emit; @@ -6,12 +8,14 @@ namespace IKVM.CoreLib.Symbols.Reflection.Emit { - abstract class ReflectionParameterSymbolBuilder : ReflectionSymbolBuilder, IParameterSymbolBuilder + class ReflectionParameterSymbolBuilder : ReflectionSymbolBuilder, IReflectionParameterSymbolBuilder { - - readonly ParameterBuilder _builder; - readonly ReflectionParameterBuilderInfo _info; - ReflectionParameterSymbol? _symbol; + + readonly IReflectionModuleSymbol _resolvingModule; + readonly IReflectionMethodBaseSymbol _resolvingMethod; + + ParameterBuilder? _builder; + ParameterInfo _parameter; object? _constant; @@ -19,83 +23,141 @@ abstract class ReflectionParameterSymbolBuilder : ReflectionSymbolBuilder /// - protected ReflectionParameterSymbolBuilder(ReflectionSymbolContext context, ParameterBuilder builder) : + /// + /// + /// + public ReflectionParameterSymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionMethodBaseSymbol resolvingMethod, ParameterBuilder builder) : base(context) { + _resolvingModule = resolvingModule ?? throw new ArgumentNullException(nameof(resolvingModule)); + _resolvingMethod = resolvingMethod ?? throw new ArgumentNullException(nameof(resolvingMethod)); _builder = builder ?? throw new ArgumentNullException(nameof(builder)); - _info = new ReflectionParameterBuilderInfo(_builder); + _parameter = new ReflectionParameterBuilderInfo(_builder, () => _constant); } - /// - /// Gets the wrapped . - /// - internal ParameterBuilder ReflectionBuilder => _builder; + /// + public IReflectionModuleSymbol ResolvingModule => _resolvingMethod.ResolvingModule; /// - internal override ReflectionParameterSymbol ReflectionSymbol => _symbol ??= GetOrCreateSymbol(_info); + public IReflectionMethodBaseSymbol ResolvingMethod => _resolvingMethod; - /// - /// Gets or creates the . - /// - /// - protected internal abstract ReflectionParameterSymbol GetOrCreateSymbol(ReflectionParameterBuilderInfo info); + /// + public ParameterInfo UnderlyingParameter => _parameter; + + /// + public ParameterBuilder UnderlyingParameterBuilder => _builder ?? throw new InvalidOperationException(); + + #region IParameterSymbolBuilder /// public void SetConstant(object? defaultValue) { - _builder.SetConstant(_constant = defaultValue); + UnderlyingParameterBuilder.SetConstant(_constant = defaultValue); } - /// - /// Saves the constant value so it can be retrieved as a symbol. - /// - /// - internal object? GetConstant() + /// + public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) { - return _constant; + UnderlyingParameterBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); } /// - public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) + public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) { - _builder.SetCustomAttribute(con.Unpack(), binaryAttribute); + UnderlyingParameterBuilder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); } + #endregion + + #region IParameterSymbol + /// - public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) + public ParameterAttributes Attributes => UnderlyingParameter.Attributes; + + /// + public object? DefaultValue => UnderlyingParameter.DefaultValue; + + /// + public bool HasDefaultValue => UnderlyingParameter.HasDefaultValue; + + /// + public bool IsIn => UnderlyingParameter.IsIn; + + /// + public bool IsLcid => UnderlyingParameter.IsLcid; + + /// + public bool IsOptional => UnderlyingParameter.IsOptional; + + /// + public bool IsOut => UnderlyingParameter.IsOut; + + /// + public bool IsRetval => UnderlyingParameter.IsRetval; + + /// + public IMemberSymbol Member => ResolveMemberSymbol(UnderlyingParameter.Member); + + /// + public int MetadataToken => UnderlyingParameter.MetadataToken; + + /// + public string? Name => UnderlyingParameter.Name; + + /// + public ITypeSymbol ParameterType => ResolveTypeSymbol(UnderlyingParameter.ParameterType); + + /// + public int Position => UnderlyingParameter.Position; + + /// + public override bool IsComplete => _builder == null; + + /// + public CustomAttribute[] GetCustomAttributes(bool inherit = false) { - _builder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).ReflectionBuilder); + return ResolveCustomAttributes(UnderlyingParameter.GetCustomAttributesData()); } - } + /// + public virtual CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) + { + return GetCustomAttributes(inherit).Where(i => i.AttributeType == attributeType).ToArray(); + } - class ReflectionParameterSymbolBuilder : ReflectionParameterSymbolBuilder - where TContainingSymbol : IMethodBaseSymbol - where TContainingReflectionSymbol : ReflectionMethodBaseSymbol, TContainingSymbol - where TContainingBuilder : ReflectionMethodBaseSymbolBuilder - { + /// + public virtual CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) + { + return GetCustomAttributes(attributeType, inherit).FirstOrDefault(); + } - readonly TContainingBuilder _containingMethodBuilder; + /// + public virtual bool IsDefined(ITypeSymbol attributeType, bool inherit = false) + { + return UnderlyingParameter.IsDefined(attributeType.Unpack(), inherit); + } - /// - /// Initializes a new instance. - /// - /// - /// - /// - public ReflectionParameterSymbolBuilder(ReflectionSymbolContext context, TContainingBuilder containingMethodBuilder, ParameterBuilder builder) : - base(context, builder) + /// + public ITypeSymbol[] GetOptionalCustomModifiers() { - _containingMethodBuilder = containingMethodBuilder ?? throw new ArgumentNullException(nameof(containingMethodBuilder)); + return ResolveTypeSymbols(UnderlyingParameter.GetOptionalCustomModifiers()); } - /// - /// Gets the containing . - /// - internal TContainingBuilder ContainingMethodBuilder => _containingMethodBuilder; + /// + public ITypeSymbol[] GetRequiredCustomModifiers() + { + return ResolveTypeSymbols(UnderlyingParameter.GetRequiredCustomModifiers()); + } + + #endregion /// - protected internal override ReflectionParameterSymbol GetOrCreateSymbol(ReflectionParameterBuilderInfo info) => ContainingMethodBuilder.ReflectionSymbol.ResolveParameterSymbol(info); + public void OnComplete() + { + var p = ResolvingMethod.UnderlyingMethodBase.GetParameters(); + _parameter = p[Position]; + _builder = null; + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionPropertySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionPropertySymbolBuilder.cs index 1d9a57c4b..de0c8ac1c 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionPropertySymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionPropertySymbolBuilder.cs @@ -1,4 +1,5 @@ using System; +using System.Reflection; using System.Reflection.Emit; using IKVM.CoreLib.Symbols.Emit; @@ -6,40 +7,176 @@ namespace IKVM.CoreLib.Symbols.Reflection.Emit { - class ReflectionPropertySymbolBuilder : ReflectionSymbolBuilder, IPropertySymbolBuilder + class ReflectionPropertySymbolBuilder : ReflectionMemberSymbolBuilder, IReflectionPropertySymbolBuilder { - readonly ReflectionTypeSymbolBuilder _containingTypeBuilder; - readonly PropertyBuilder _builder; - ReflectionPropertySymbol? _symbol; + PropertyBuilder? _builder; + PropertyInfo _property; /// /// Initializes a new instance. /// /// - /// + /// + /// /// - public ReflectionPropertySymbolBuilder(ReflectionSymbolContext context, ReflectionTypeSymbolBuilder containingTypeBuilder, PropertyBuilder builder) : - base(context) + /// + public ReflectionPropertySymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol resolvingType, PropertyBuilder builder) : + base(context, resolvingModule, resolvingType) { - _containingTypeBuilder = containingTypeBuilder ?? throw new ArgumentNullException(nameof(containingTypeBuilder)); _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + _property = _builder; } - internal PropertyBuilder ReflectionBuilder => _builder; + /// + public PropertyInfo UnderlyingProperty => _property; + + /// + public PropertyBuilder UnderlyingPropertyBuilder => _builder ?? throw new InvalidOperationException(); + + /// + public override MemberInfo UnderlyingMember => UnderlyingProperty; + + #region IPropertySymbol + + /// + public void SetConstant(object? defaultValue) + { + UnderlyingPropertyBuilder.SetConstant(defaultValue); + } + + /// + public void SetGetMethod(IMethodSymbolBuilder mdBuilder) + { + UnderlyingPropertyBuilder.SetGetMethod(((IReflectionMethodSymbolBuilder)mdBuilder).UnderlyingMethodBuilder); + } - internal override ReflectionPropertySymbol ReflectionSymbol => _symbol ??= _containingTypeBuilder.ReflectionSymbol.ResolvePropertySymbol(_builder); + /// + public void SetSetMethod(IMethodSymbolBuilder mdBuilder) + { + UnderlyingPropertyBuilder.SetSetMethod(((IReflectionMethodSymbolBuilder)mdBuilder).UnderlyingMethodBuilder); + } + + /// + public void AddOtherMethod(IMethodSymbolBuilder mdBuilder) + { + UnderlyingPropertyBuilder.AddOtherMethod(((IReflectionMethodSymbolBuilder)mdBuilder).UnderlyingMethodBuilder); + } /// public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) { - _builder.SetCustomAttribute(con.Unpack(), binaryAttribute); + UnderlyingPropertyBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); } /// public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) { - _builder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).ReflectionBuilder); + UnderlyingPropertyBuilder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); + } + + #endregion + + #region IPropertySymbol + + /// + public PropertyAttributes Attributes => UnderlyingProperty.Attributes; + + /// + public bool CanRead => UnderlyingProperty.CanRead; + + /// + public bool CanWrite => UnderlyingProperty.CanWrite; + + /// + public bool IsSpecialName => UnderlyingProperty.IsSpecialName; + + /// + public ITypeSymbol PropertyType => ResolveTypeSymbol(UnderlyingProperty.PropertyType); + + /// + public IMethodSymbol? GetMethod => ResolveMethodSymbol(UnderlyingProperty.GetMethod); + + /// + public IMethodSymbol? SetMethod => ResolveMethodSymbol(UnderlyingProperty.SetMethod); + + /// + public override bool IsComplete => _builder == null; + + /// + public object? GetRawConstantValue() + { + return UnderlyingProperty.GetRawConstantValue(); + } + + /// + public IMethodSymbol[] GetAccessors() + { + return ResolveMethodSymbols(UnderlyingProperty.GetAccessors()); + } + + /// + public IMethodSymbol[] GetAccessors(bool nonPublic) + { + return ResolveMethodSymbols(UnderlyingProperty.GetAccessors(nonPublic)); + } + + /// + public IParameterSymbol[] GetIndexParameters() + { + return ResolveParameterSymbols(UnderlyingProperty.GetIndexParameters()); + } + + /// + public IMethodSymbol? GetGetMethod() + { + return ResolveMethodSymbol(UnderlyingProperty.GetGetMethod()); + } + + /// + public IMethodSymbol? GetGetMethod(bool nonPublic) + { + return ResolveMethodSymbol(UnderlyingProperty.GetGetMethod(nonPublic)); + } + + /// + public IMethodSymbol? GetSetMethod() + { + return ResolveMethodSymbol(UnderlyingProperty.GetSetMethod()); + } + + /// + public IMethodSymbol? GetSetMethod(bool nonPublic) + { + return ResolveMethodSymbol(UnderlyingProperty.GetSetMethod(nonPublic)); + } + + /// + public ITypeSymbol GetModifiedPropertyType() + { + throw new NotImplementedException(); + } + + /// + public ITypeSymbol[] GetOptionalCustomModifiers() + { + return ResolveTypeSymbols(UnderlyingProperty.GetOptionalCustomModifiers()); + } + + /// + public ITypeSymbol[] GetRequiredCustomModifiers() + { + return ResolveTypeSymbols(UnderlyingProperty.GetRequiredCustomModifiers()); + } + +#endregion + + /// + public override void OnComplete() + { + _property = (PropertyInfo?)ResolvingModule.UnderlyingModule.ResolveMember(MetadataToken) ?? throw new InvalidOperationException(); + _builder = null; + base.OnComplete(); } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionSymbolBuilder.cs index 3ff29a8b2..aff7f0300 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionSymbolBuilder.cs @@ -1,6 +1,4 @@ -using System; - -using IKVM.CoreLib.Symbols.Emit; +using IKVM.CoreLib.Symbols.Emit; namespace IKVM.CoreLib.Symbols.Reflection.Emit { @@ -8,41 +6,7 @@ namespace IKVM.CoreLib.Symbols.Reflection.Emit /// /// Reflection-specific implementation of . /// - abstract class ReflectionSymbolBuilder : ISymbolBuilder - { - - readonly ReflectionSymbolContext _context; - - /// - /// Initializes a new instance. - /// - /// - protected ReflectionSymbolBuilder(ReflectionSymbolContext context) - { - _context = context ?? throw new ArgumentNullException(nameof(context)); - } - - /// - /// Gets the associated . - /// - public ReflectionSymbolContext Context => _context; - - /// - public ISymbol Symbol => GetSymbol(); - - /// - /// Implement to get the symbol. - /// - /// - protected abstract ISymbol GetSymbol(); - - } - - /// - /// Reflection-specific implementation of . - /// - abstract class ReflectionSymbolBuilder : ReflectionSymbolBuilder, ISymbolBuilder - where TSymbol : ISymbol + abstract class ReflectionSymbolBuilder : ReflectionSymbol, IReflectionSymbolBuilder { /// @@ -55,40 +19,6 @@ protected ReflectionSymbolBuilder(ReflectionSymbolContext context) : } - /// - public abstract new TSymbol Symbol { get; } - - /// - protected sealed override ISymbol GetSymbol() => Symbol; - - } - - /// - /// Base implementation for reflection symbol builders. - /// - abstract class ReflectionSymbolBuilder : ReflectionSymbolBuilder - where TSymbol : ISymbol - where TReflectionSymbol : ReflectionSymbol, TSymbol - { - - /// - /// Initializes a new instance. - /// - /// - protected ReflectionSymbolBuilder(ReflectionSymbolContext context) : - base(context) - { - - } - - /// - public sealed override TSymbol Symbol => ReflectionSymbol; - - /// - /// Gets the that is currently being built. Portions of this interface will be non-functional until the build is completed. - /// - internal abstract TReflectionSymbol ReflectionSymbol { get; } - } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs index 586138398..27eb44852 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs @@ -8,241 +8,793 @@ namespace IKVM.CoreLib.Symbols.Reflection.Emit { - class ReflectionTypeSymbolBuilder : ReflectionSymbolBuilder, ITypeSymbolBuilder + class ReflectionTypeSymbolBuilder : ReflectionMemberSymbolBuilder, IReflectionTypeSymbolBuilder { - readonly ReflectionModuleSymbolBuilder _containingModuleBuilder; - readonly TypeBuilder _builder; - ReflectionTypeSymbol? _symbol; + TypeBuilder? _builder; + Type _type; + ReflectionTypeImpl _impl; /// /// Initializes a new instance. /// /// - /// + /// /// - public ReflectionTypeSymbolBuilder(ReflectionSymbolContext context, ReflectionModuleSymbolBuilder containingModuleBuilder, TypeBuilder builder) : - base(context) + public ReflectionTypeSymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, TypeBuilder builder) : + base(context, resolvingModule, null) { - _containingModuleBuilder = containingModuleBuilder ?? throw new ArgumentNullException(nameof(containingModuleBuilder)); _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + _type = _builder; + _impl = new ReflectionTypeImpl(this); } - /// - /// Gets the containing . - /// - internal ReflectionModuleSymbolBuilder ContainingModuleBuilder => _containingModuleBuilder; + /// + public Type UnderlyingType => _type; - /// - /// Gets the underlying . - /// - internal TypeBuilder ReflectionBuilder => _builder; + /// + public override MemberInfo UnderlyingMember => UnderlyingType; /// - internal override ReflectionTypeSymbol ReflectionSymbol => _symbol ??= Context.GetOrCreateTypeSymbol(_builder); + public TypeBuilder UnderlyingTypeBuilder => _builder ?? throw new InvalidOperationException(); + + #region ITypeSymbolBuilder /// public void SetParent(ITypeSymbol? parent) { - _builder.SetParent(parent?.Unpack()); + UnderlyingTypeBuilder.SetParent(parent?.Unpack()); } /// public IGenericTypeParameterSymbolBuilder[] DefineGenericParameters(params string[] names) { - throw new NotImplementedException(); + var l = UnderlyingTypeBuilder.DefineGenericParameters(names); + var a = new IGenericTypeParameterSymbolBuilder[l.Length]; + for (int i = 0; i < l.Length; i++) + a[i] = new ReflectionGenericTypeParameterSymbolBuilder(Context, ResolvingModule, this, null, l[i]); + + return a; } /// public void AddInterfaceImplementation(ITypeSymbol interfaceType) { - _builder.AddInterfaceImplementation(interfaceType.Unpack()); + UnderlyingTypeBuilder.AddInterfaceImplementation(interfaceType.Unpack()); } /// public IConstructorSymbolBuilder DefineConstructor(MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol[]? parameterTypes) { - return new ReflectionConstructorSymbolBuilder(Context, this, _builder.DefineConstructor(attributes, callingConvention, parameterTypes?.Unpack())); + return (IConstructorSymbolBuilder)ResolveConstructorSymbol(UnderlyingTypeBuilder.DefineConstructor(attributes, callingConvention, parameterTypes?.Unpack())); } /// public IConstructorSymbolBuilder DefineConstructor(MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? requiredCustomModifiers, ITypeSymbol[][]? optionalCustomModifiers) { - return new ReflectionConstructorSymbolBuilder(Context, this, _builder.DefineConstructor(attributes, callingConvention, parameterTypes?.Unpack(), requiredCustomModifiers?.Unpack(), optionalCustomModifiers?.Unpack())); + return (IConstructorSymbolBuilder)ResolveConstructorSymbol(UnderlyingTypeBuilder.DefineConstructor(attributes, callingConvention, parameterTypes?.Unpack(), requiredCustomModifiers?.Unpack(), optionalCustomModifiers?.Unpack())); } /// public IConstructorSymbolBuilder DefineDefaultConstructor(MethodAttributes attributes) { - return new ReflectionConstructorSymbolBuilder(Context, this, _builder.DefineDefaultConstructor(attributes)); + return (IConstructorSymbolBuilder)ResolveConstructorSymbol(UnderlyingTypeBuilder.DefineDefaultConstructor(attributes)); } /// public IEventSymbolBuilder DefineEvent(string name, EventAttributes attributes, ITypeSymbol eventtype) { - return new ReflectionEventSymbolBuilder(Context, this, _builder.DefineEvent(name, attributes, eventtype.Unpack())); + return (IEventSymbolBuilder)ResolveEventSymbol(UnderlyingTypeBuilder.DefineEvent(name, attributes, eventtype.Unpack())); } /// public IFieldSymbolBuilder DefineField(string fieldName, ITypeSymbol type, FieldAttributes attributes) { - return new ReflectionFieldSymbolBuilder(Context, this, _builder.DefineField(fieldName, type.Unpack(), attributes)); + return (IFieldSymbolBuilder)ResolveFieldSymbol(UnderlyingTypeBuilder.DefineField(fieldName, type.Unpack(), attributes)); } /// public IFieldSymbolBuilder DefineField(string fieldName, ITypeSymbol type, ITypeSymbol[]? requiredCustomModifiers, ITypeSymbol[]? optionalCustomModifiers, FieldAttributes attributes) { - return new ReflectionFieldSymbolBuilder(Context, this, _builder.DefineField(fieldName, type.Unpack(), requiredCustomModifiers?.Unpack(), optionalCustomModifiers?.Unpack(), attributes)); + return (IFieldSymbolBuilder)ResolveFieldSymbol(UnderlyingTypeBuilder.DefineField(fieldName, type.Unpack(), requiredCustomModifiers?.Unpack(), optionalCustomModifiers?.Unpack(), attributes)); } /// public IMethodSymbolBuilder DefineMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers) { - return new ReflectionMethodSymbolBuilder(Context, this, _builder.DefineMethod(name, attributes, callingConvention, returnType?.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack())); + return (IMethodSymbolBuilder)ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, attributes, callingConvention, returnType?.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack())); } /// public IMethodSymbolBuilder DefineMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes) { - return new ReflectionMethodSymbolBuilder(Context, this, _builder.DefineMethod(name, attributes, callingConvention, returnType?.Unpack(), parameterTypes?.Unpack())); + return (IMethodSymbolBuilder)ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, attributes, callingConvention, returnType?.Unpack(), parameterTypes?.Unpack())); } /// public IMethodSymbolBuilder DefineMethod(string name, MethodAttributes attributes, CallingConventions callingConvention) { - return new ReflectionMethodSymbolBuilder(Context, this, _builder.DefineMethod(name, attributes, callingConvention)); + return (IMethodSymbolBuilder)ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, attributes, callingConvention)); } /// public IMethodSymbolBuilder DefineMethod(string name, MethodAttributes attributes) { - return new ReflectionMethodSymbolBuilder(Context, this, _builder.DefineMethod(name, attributes)); + return (IMethodSymbolBuilder)ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, attributes)); } /// public IMethodSymbolBuilder DefineMethod(string name, MethodAttributes attributes, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes) { - return new ReflectionMethodSymbolBuilder(Context, this, _builder.DefineMethod(name, attributes, returnType?.Unpack(), parameterTypes?.Unpack())); + return (IMethodSymbolBuilder)ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, attributes, returnType?.Unpack(), parameterTypes?.Unpack())); + } + + /// + public void DefineMethodOverride(IMethodSymbolBuilder methodInfoBody, IMethodSymbol methodInfoDeclaration) + { + UnderlyingTypeBuilder.DefineMethodOverride(methodInfoBody.Unpack(), methodInfoDeclaration.Unpack()); } /// public ITypeSymbolBuilder DefineNestedType(string name, TypeAttributes attr, ITypeSymbol? parent, ITypeSymbol[]? interfaces) { - return new ReflectionTypeSymbolBuilder(Context, ContainingModuleBuilder, _builder.DefineNestedType(name, attr, parent?.Unpack(), interfaces?.Unpack())); + return (ITypeSymbolBuilder)ResolveTypeSymbol(UnderlyingTypeBuilder.DefineNestedType(name, attr, parent?.Unpack(), interfaces?.Unpack())); } /// public ITypeSymbolBuilder DefineNestedType(string name, TypeAttributes attr, ITypeSymbol? parent, PackingSize packSize, int typeSize) { - return new ReflectionTypeSymbolBuilder(Context, ContainingModuleBuilder, _builder.DefineNestedType(name, attr, parent?.Unpack(), packSize, typeSize)); + return (ITypeSymbolBuilder)ResolveTypeSymbol(UnderlyingTypeBuilder.DefineNestedType(name, attr, parent?.Unpack(), packSize, typeSize)); } /// public ITypeSymbolBuilder DefineNestedType(string name, TypeAttributes attr, ITypeSymbol? parent, PackingSize packSize) { - return new ReflectionTypeSymbolBuilder(Context, ContainingModuleBuilder, _builder.DefineNestedType(name, attr, parent?.Unpack(), packSize)); + return (ITypeSymbolBuilder)ResolveTypeSymbol(UnderlyingTypeBuilder.DefineNestedType(name, attr, parent?.Unpack(), packSize)); } /// public ITypeSymbolBuilder DefineNestedType(string name) { - return new ReflectionTypeSymbolBuilder(Context, ContainingModuleBuilder, _builder.DefineNestedType(name)); + return (ITypeSymbolBuilder)ResolveTypeSymbol(UnderlyingTypeBuilder.DefineNestedType(name)); } /// public ITypeSymbolBuilder DefineNestedType(string name, TypeAttributes attr, ITypeSymbol? parent) { - return new ReflectionTypeSymbolBuilder(Context, ContainingModuleBuilder, _builder.DefineNestedType(name, attr, parent?.Unpack())); + return (ITypeSymbolBuilder)ResolveTypeSymbol(UnderlyingTypeBuilder.DefineNestedType(name, attr, parent?.Unpack())); } /// public ITypeSymbolBuilder DefineNestedType(string name, TypeAttributes attr) { - return new ReflectionTypeSymbolBuilder(Context, ContainingModuleBuilder, _builder.DefineNestedType(name, attr)); + return (ITypeSymbolBuilder)ResolveTypeSymbol(UnderlyingTypeBuilder.DefineNestedType(name, attr)); } /// public ITypeSymbolBuilder DefineNestedType(string name, TypeAttributes attr, ITypeSymbol? parent, int typeSize) { - return new ReflectionTypeSymbolBuilder(Context, ContainingModuleBuilder, _builder.DefineNestedType(name, attr, parent?.Unpack(), typeSize)); + return (ITypeSymbolBuilder)ResolveTypeSymbol(UnderlyingTypeBuilder.DefineNestedType(name, attr, parent?.Unpack(), typeSize)); } /// public IMethodSymbolBuilder DefinePInvokeMethod(string name, string dllName, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet) { - return new ReflectionMethodSymbolBuilder(Context, ContainingModuleBuilder, _builder.DefinePInvokeMethod(name, dllName, attributes, callingConvention, returnType?.Unpack(), parameterTypes?.Unpack(), nativeCallConv, nativeCharSet)); + return (IMethodSymbolBuilder)ResolveMethodSymbol(UnderlyingTypeBuilder.DefinePInvokeMethod(name, dllName, attributes, callingConvention, returnType?.Unpack(), parameterTypes?.Unpack(), nativeCallConv, nativeCharSet)); } /// public IMethodSymbolBuilder DefinePInvokeMethod(string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet) { - return new ReflectionMethodSymbolBuilder(Context, ContainingModuleBuilder, _builder.DefinePInvokeMethod(name, dllName, entryName, attributes, callingConvention, returnType?.Unpack(), parameterTypes?.Unpack(), nativeCallConv, nativeCharSet)); + return (IMethodSymbolBuilder)ResolveMethodSymbol(UnderlyingTypeBuilder.DefinePInvokeMethod(name, dllName, entryName, attributes, callingConvention, returnType?.Unpack(), parameterTypes?.Unpack(), nativeCallConv, nativeCharSet)); } /// public IMethodSymbolBuilder DefinePInvokeMethod(string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers, CallingConvention nativeCallConv, CharSet nativeCharSet) { - return new ReflectionMethodSymbolBuilder(Context, ContainingModuleBuilder, _builder.DefinePInvokeMethod(name, dllName, entryName, attributes, callingConvention, returnType?.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack(), nativeCallConv, nativeCharSet)); + return (IMethodSymbolBuilder)ResolveMethodSymbol(UnderlyingTypeBuilder.DefinePInvokeMethod(name, dllName, entryName, attributes, callingConvention, returnType?.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack(), nativeCallConv, nativeCharSet)); } /// public IPropertySymbolBuilder DefineProperty(string name, PropertyAttributes attributes, ITypeSymbol returnType, ITypeSymbol[]? parameterTypes) { - return new ReflectionPropertySymbolBuilder(Context, this, _builder.DefineProperty(name, attributes, returnType.Unpack(), parameterTypes?.Unpack())); + return (IPropertySymbolBuilder)ResolvePropertySymbol(UnderlyingTypeBuilder.DefineProperty(name, attributes, returnType.Unpack(), parameterTypes?.Unpack())); } /// public IPropertySymbolBuilder DefineProperty(string name, PropertyAttributes attributes, CallingConventions callingConvention, ITypeSymbol returnType, ITypeSymbol[]? parameterTypes) { - return new ReflectionPropertySymbolBuilder(Context, this, _builder.DefineProperty(name, attributes, callingConvention, returnType.Unpack(), parameterTypes?.Unpack())); + return (IPropertySymbolBuilder)ResolvePropertySymbol(UnderlyingTypeBuilder.DefineProperty(name, attributes, callingConvention, returnType.Unpack(), parameterTypes?.Unpack())); } /// public IPropertySymbolBuilder DefineProperty(string name, PropertyAttributes attributes, ITypeSymbol returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers) { - return new ReflectionPropertySymbolBuilder(Context, this, _builder.DefineProperty(name, attributes, returnType.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack())); + return (IPropertySymbolBuilder)ResolvePropertySymbol(UnderlyingTypeBuilder.DefineProperty(name, attributes, returnType.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack())); } /// public IPropertySymbolBuilder DefineProperty(string name, PropertyAttributes attributes, CallingConventions callingConvention, ITypeSymbol returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers) { - return new ReflectionPropertySymbolBuilder(Context, this, _builder.DefineProperty(name, attributes, callingConvention, returnType.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack())); + return (IPropertySymbolBuilder)ResolvePropertySymbol(UnderlyingTypeBuilder.DefineProperty(name, attributes, callingConvention, returnType.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack())); } /// public IConstructorSymbolBuilder DefineTypeInitializer() { - return new ReflectionConstructorSymbolBuilder(Context, this, _builder.DefineTypeInitializer()); + return (IConstructorSymbolBuilder)ResolveConstructorSymbol(UnderlyingTypeBuilder.DefineTypeInitializer()); } /// public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) { - _builder.SetCustomAttribute(con.Unpack(), binaryAttribute); + UnderlyingTypeBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); } /// public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) { - _builder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).ReflectionBuilder); + UnderlyingTypeBuilder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); + } + + #endregion + + #region ITypeSymbol + + /// + public TypeAttributes Attributes => _impl.Attributes; + + /// + public IAssemblySymbol Assembly => _impl.Assembly; + + /// + public IMethodBaseSymbol? DeclaringMethod => _impl.DeclaringMethod; + + /// + public string? AssemblyQualifiedName => _impl.AssemblyQualifiedName; + + /// + public string? FullName => _impl.FullName; + + /// + public string? Namespace => _impl.Namespace; + + /// + public TypeCode TypeCode => _impl.TypeCode; + + /// + public ITypeSymbol? BaseType => _impl.BaseType; + + /// + public bool ContainsGenericParameters => _impl.ContainsGenericParameters; + + /// + public GenericParameterAttributes GenericParameterAttributes => _impl.GenericParameterAttributes; + + /// + public int GenericParameterPosition => _impl.GenericParameterPosition; + + /// + public ITypeSymbol[] GenericTypeArguments => _impl.GenericTypeArguments; + + /// + public bool IsConstructedGenericType => _impl.IsConstructedGenericType; + + /// + public bool IsGenericType => _impl.IsGenericType; + + /// + public bool IsGenericTypeDefinition => _impl.IsGenericTypeDefinition; + + /// + public bool IsGenericParameter => _impl.IsGenericParameter; + + /// + public bool IsAutoLayout => _impl.IsAutoLayout; + + /// + public bool IsExplicitLayout => _impl.IsExplicitLayout; + + /// + public bool IsLayoutSequential => _impl.IsLayoutSequential; + + /// + public bool HasElementType => _impl.HasElementType; + + /// + public bool IsClass => _impl.IsClass; + + /// + public bool IsValueType => _impl.IsValueType; + + /// + public bool IsInterface => _impl.IsInterface; + + /// + public bool IsPrimitive => _impl.IsPrimitive; + + /// + public bool IsSZArray => _impl.IsSZArray; + + /// + public bool IsArray => _impl.IsArray; + + /// + public bool IsEnum => _impl.IsEnum; + + /// + public bool IsPointer => _impl.IsPointer; + + /// + public bool IsFunctionPointer => _impl.IsFunctionPointer; + + /// + public bool IsUnmanagedFunctionPointer => _impl.IsUnmanagedFunctionPointer; + + /// + public bool IsByRef => _impl.IsByRef; + + /// + public bool IsAbstract => _impl.IsAbstract; + + /// + public bool IsSealed => _impl.IsSealed; + + /// + public bool IsVisible => _impl.IsVisible; + + /// + public bool IsPublic => _impl.IsPublic; + + /// + public bool IsNotPublic => _impl.IsNotPublic; + + /// + public bool IsNested => _impl.IsNested; + + /// + public bool IsNestedAssembly => _impl.IsNestedAssembly; + + /// + public bool IsNestedFamANDAssem => _impl.IsNestedFamANDAssem; + + /// + public bool IsNestedFamily => _impl.IsNestedFamily; + + /// + public bool IsNestedFamORAssem => _impl.IsNestedFamORAssem; + + /// + public bool IsNestedPrivate => _impl.IsNestedPrivate; + + /// + public bool IsNestedPublic => _impl.IsNestedPublic; + + /// + public bool IsSerializable => _impl.IsSerializable; + + /// + public bool IsSignatureType => _impl.IsSignatureType; + + /// + public bool IsSpecialName => _impl.IsSpecialName; + + /// + public IConstructorSymbol? TypeInitializer => _impl.TypeInitializer; + + /// + public override bool IsComplete => _builder == null; + + /// + public int GetArrayRank() + { + return _impl.GetArrayRank(); + } + + /// + public IMemberSymbol[] GetDefaultMembers() + { + return _impl.GetDefaultMembers(); + } + + /// + public ITypeSymbol? GetElementType() + { + return _impl.GetElementType(); + } + + /// + public string? GetEnumName(object value) + { + return _impl.GetEnumName(value); + } + + /// + public string[] GetEnumNames() + { + return _impl.GetEnumNames(); + } + + /// + public ITypeSymbol GetEnumUnderlyingType() + { + return _impl.GetEnumUnderlyingType(); + } + + /// + public ITypeSymbol[] GetGenericArguments() + { + return _impl.GetGenericArguments(); + } + + /// + public ITypeSymbol[] GetGenericParameterConstraints() + { + return _impl.GetGenericParameterConstraints(); + } + + /// + public ITypeSymbol GetGenericTypeDefinition() + { + return _impl.GetGenericTypeDefinition(); + } + + /// + public ITypeSymbol? GetInterface(string name) + { + return _impl.GetInterface(name); + } + + /// + public ITypeSymbol? GetInterface(string name, bool ignoreCase) + { + return _impl.GetInterface(name, ignoreCase); + } + + /// + public ITypeSymbol[] GetInterfaces(bool inherit = true) + { + return _impl.GetInterfaces(inherit); } /// - void Complete(Type type) + public InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) { - ReflectionSymbol.Complete(type); + return _impl.GetInterfaceMap(interfaceType); } + /// + public IMemberSymbol[] GetMember(string name) + { + return _impl.GetMember(name); + } + + /// + public IMemberSymbol[] GetMember(string name, BindingFlags bindingAttr) + { + return _impl.GetMember(name, bindingAttr); + } + + /// + public IMemberSymbol[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) + { + return _impl.GetMember(name, type, bindingAttr); + } + + /// + public IMemberSymbol[] GetMembers() + { + return _impl.GetMembers(); + } + + /// + public IMemberSymbol[] GetMembers(BindingFlags bindingAttr) + { + return _impl.GetMembers(bindingAttr); + } + + public IConstructorSymbol? GetConstructor(ITypeSymbol[] types) + { + return _impl.GetConstructor(types); + } + + /// + public IConstructorSymbol? GetConstructor(BindingFlags bindingAttr, ITypeSymbol[] types) + { + return _impl.GetConstructor(bindingAttr, types); + } + + /// + public IConstructorSymbol[] GetConstructors() + { + return _impl.GetConstructors(); + } + + /// + public IConstructorSymbol[] GetConstructors(BindingFlags bindingAttr) + { + return _impl.GetConstructors(bindingAttr); + } + + /// + public IFieldSymbol? GetField(string name) + { + return _impl.GetField(name); + } + + /// + public IFieldSymbol? GetField(string name, BindingFlags bindingAttr) + { + return _impl.GetField(name, bindingAttr); + } + + /// + public IFieldSymbol[] GetFields() + { + return _impl.GetFields(); + } + + /// + public IFieldSymbol[] GetFields(BindingFlags bindingAttr) + { + return _impl.GetFields(bindingAttr); + } + + /// + public IMethodSymbol? GetMethod(string name) + { + return _impl.GetMethod(name); + } + + /// + public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) + { + return _impl.GetMethod(name, types); + } + + /// + public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr) + { + return _impl.GetMethod(name, bindingAttr); + } + + /// + public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types) + { + return _impl.GetMethod(name, bindingAttr, types); + } + + /// + public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers) + { + return _impl.GetMethod(name, bindingAttr, callConvention, types, modifiers); + } + + /// + public IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers) + { + return _impl.GetMethod(name, genericParameterCount, bindingAttr, callConvention, types, modifiers); + } + + /// + public IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, ITypeSymbol[] types, ParameterModifier[]? modifiers) + { + return _impl.GetMethod(name, genericParameterCount, bindingAttr, types, modifiers); + } + + /// + public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types, ParameterModifier[]? modifiers) + { + return _impl.GetMethod(name, bindingAttr, types, modifiers); + } + + /// + public IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, ParameterModifier[]? modifiers) + { + return _impl.GetMethod(name, genericParameterCount, types, modifiers); + } + + /// + public IMethodSymbol[] GetMethods() + { + return _impl.GetMethods(); + } + + /// + public IMethodSymbol[] GetMethods(BindingFlags bindingAttr) + { + return _impl.GetMethods(bindingAttr); + } + + /// + public IPropertySymbol? GetProperty(string name) + { + return _impl.GetProperty(name); + } + + /// + public IPropertySymbol? GetProperty(string name, BindingFlags bindingAttr) + { + return _impl.GetProperty(name, bindingAttr); + } + + /// + public IPropertySymbol? GetProperty(string name, ITypeSymbol[] types) + { + return _impl.GetProperty(name, types); + } + + /// + public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types) + { + return _impl.GetProperty(name, returnType, types); + } + + /// + public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) + { + return _impl.GetProperty(name, returnType); + } + + /// + public IPropertySymbol[] GetProperties() + { + return _impl.GetProperties(); + } + + /// + public IPropertySymbol[] GetProperties(BindingFlags bindingAttr) + { + return _impl.GetProperties(bindingAttr); + } + + /// + public IEventSymbol? GetEvent(string name) + { + return _impl.GetEvent(name); + } + + /// + public IEventSymbol? GetEvent(string name, BindingFlags bindingAttr) + { + return _impl.GetEvent(name, bindingAttr); + } + + /// + public IEventSymbol[] GetEvents() + { + return _impl.GetEvents(); + } + + /// + public IEventSymbol[] GetEvents(BindingFlags bindingAttr) + { + return _impl.GetEvents(bindingAttr); + } + + /// + public ITypeSymbol? GetNestedType(string name) + { + return _impl.GetNestedType(name); + } + + /// + public ITypeSymbol? GetNestedType(string name, BindingFlags bindingAttr) + { + return _impl.GetNestedType(name, bindingAttr); + } + + /// + public ITypeSymbol[] GetNestedTypes() + { + return _impl.GetNestedTypes(); + } + + /// + public ITypeSymbol[] GetNestedTypes(BindingFlags bindingAttr) + { + return _impl.GetNestedTypes(); + } + + /// + public bool IsAssignableFrom(ITypeSymbol? c) + { + return _impl.IsAssignableFrom(c); + } + + /// + public bool IsSubclassOf(ITypeSymbol c) + { + return _impl.IsSubclassOf(c); + } + + /// + public bool IsEnumDefined(object value) + { + return _impl.IsEnumDefined(value); + } + + /// + public ITypeSymbol MakeArrayType() + { + return _impl.MakeArrayType(); + } + + /// + public ITypeSymbol MakeArrayType(int rank) + { + return _impl.MakeArrayType(rank); + } + + /// + public ITypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments) + { + return _impl.MakeGenericType(typeArguments); + } + + /// + public ITypeSymbol MakePointerType() + { + return _impl.MakePointerType(); + } + + /// + public ITypeSymbol MakeByRefType() + { + return _impl.MakeByRefType(); + } + + #endregion + /// public void Complete() { - if (_builder.IsCreated() == false) + if (_builder != null) { - var type = _builder.CreateType(); - if (type != null) - Complete(type); + // complete type + if (_builder.IsCreated() == false) + _builder.CreateType(); + + // force module to reresolve + Context.GetOrCreateModuleSymbol(ResolvingModule.UnderlyingModule); + OnComplete(); } } + /// + public override void OnComplete() + { + const BindingFlags DefaultBindingFlags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static; + + _type = ResolvingModule.UnderlyingModule.ResolveType(MetadataToken); + _builder = null; + + foreach (var i in GetGenericArguments()) + if (i is IReflectionGenericTypeParameterSymbolBuilder b) + b.OnComplete(); + + foreach (var i in GetConstructors(DefaultBindingFlags)) + if (i is IReflectionConstructorSymbolBuilder b) + b.OnComplete(); + + foreach (var i in GetMethods(DefaultBindingFlags)) + if (i is IReflectionMethodSymbolBuilder b) + b.OnComplete(); + + foreach (var i in GetFields(DefaultBindingFlags)) + if (i is IReflectionFieldSymbolBuilder b) + b.OnComplete(); + + foreach (var i in GetProperties(DefaultBindingFlags)) + if (i is IReflectionPropertySymbolBuilder b) + b.OnComplete(); + + foreach (var m in GetEvents(DefaultBindingFlags)) + if (m is IReflectionPropertySymbolBuilder b) + b.OnComplete(); + + base.OnComplete(); + } + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionAssemblySymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionAssemblySymbol.cs new file mode 100644 index 000000000..c16db0d74 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionAssemblySymbol.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Reflection.Emit; + +using IKVM.CoreLib.Symbols.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.Reflection +{ + + interface IReflectionAssemblySymbol : IReflectionSymbol, IAssemblySymbol + { + + /// + /// Gets a reference to the underlying . + /// + Assembly UnderlyingAssembly { get; } + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IReflectionModuleSymbol GetOrCreateModuleSymbol(Module module); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IReflectionModuleSymbolBuilder GetOrCreateModuleSymbol(ModuleBuilder module); + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionConstructorSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionConstructorSymbol.cs new file mode 100644 index 000000000..6da5dafb0 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionConstructorSymbol.cs @@ -0,0 +1,16 @@ +using System.Reflection; + +namespace IKVM.CoreLib.Symbols.Reflection +{ + + interface IReflectionConstructorSymbol : IReflectionMethodBaseSymbol, IConstructorSymbol + { + + /// + /// Gets the underlying . + /// + ConstructorInfo UnderlyingConstructor { get; } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionEventSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionEventSymbol.cs new file mode 100644 index 000000000..33eca5d42 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionEventSymbol.cs @@ -0,0 +1,11 @@ +namespace IKVM.CoreLib.Symbols.Reflection +{ + + interface IReflectionEventSymbol : IReflectionMemberSymbol, IEventSymbol + { + + + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionFieldSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionFieldSymbol.cs new file mode 100644 index 000000000..0ceb9e07c --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionFieldSymbol.cs @@ -0,0 +1,16 @@ +using System.Reflection; + +namespace IKVM.CoreLib.Symbols.Reflection +{ + + interface IReflectionFieldSymbol : IReflectionMemberSymbol, IFieldSymbol + { + + /// + /// Gets the underlying . + /// + FieldInfo UnderlyingField { get; } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMemberSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMemberSymbol.cs new file mode 100644 index 000000000..a83971303 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMemberSymbol.cs @@ -0,0 +1,26 @@ +using System.Reflection; + +namespace IKVM.CoreLib.Symbols.Reflection +{ + + interface IReflectionMemberSymbol : IReflectionSymbol, IMemberSymbol + { + + /// + /// Gets the resolving module. + /// + IReflectionModuleSymbol ResolvingModule { get; } + + /// + /// Gets the resolving type. + /// + IReflectionTypeSymbol? ResolvingType { get; } + + /// + /// Gets the underlying . + /// + MemberInfo UnderlyingMember { get; } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMethodBaseSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMethodBaseSymbol.cs new file mode 100644 index 000000000..13ccd1ef9 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMethodBaseSymbol.cs @@ -0,0 +1,16 @@ +using System.Reflection; + +namespace IKVM.CoreLib.Symbols.Reflection +{ + + interface IReflectionMethodBaseSymbol : IReflectionMemberSymbol, IMethodBaseSymbol + { + + /// + /// Gets the underlying . + /// + MethodBase UnderlyingMethodBase { get; } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMethodSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMethodSymbol.cs new file mode 100644 index 000000000..a806c9195 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMethodSymbol.cs @@ -0,0 +1,16 @@ +using System.Reflection; + +namespace IKVM.CoreLib.Symbols.Reflection +{ + + interface IReflectionMethodSymbol : IReflectionMethodBaseSymbol, IMethodSymbol + { + + /// + /// Gets the underlying . + /// + MethodInfo UnderlyingMethod { get; } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionModuleSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionModuleSymbol.cs new file mode 100644 index 000000000..c4b936129 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionModuleSymbol.cs @@ -0,0 +1,123 @@ +using System; +using System.Reflection; +using System.Reflection.Emit; + +using IKVM.CoreLib.Symbols.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.Reflection +{ + + interface IReflectionModuleSymbol : IReflectionSymbol, IModuleSymbol + { + + /// + /// Gets the which contains this . + /// + IReflectionAssemblySymbol ResolvingAssembly { get; } + + /// + /// Gets the underlying . + /// + Module UnderlyingModule { get; } + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IReflectionTypeSymbol GetOrCreateTypeSymbol(Type type); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IReflectionTypeSymbolBuilder GetOrCreateTypeSymbol(TypeBuilder type); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter); + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionParameterSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionParameterSymbol.cs new file mode 100644 index 000000000..20e1cb494 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionParameterSymbol.cs @@ -0,0 +1,26 @@ +using System.Reflection; + +namespace IKVM.CoreLib.Symbols.Reflection +{ + + interface IReflectionParameterSymbol : IReflectionSymbol, IParameterSymbol + { + + /// + /// Gets the module that resolved the parameter. + /// + IReflectionModuleSymbol ResolvingModule { get; } + + /// + /// Gets the method that resolved the parameter. + /// + IReflectionMethodBaseSymbol ResolvingMethod { get; } + + /// + /// Gets the underlying . + /// + ParameterInfo UnderlyingParameter { get; } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionPropertySymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionPropertySymbol.cs new file mode 100644 index 000000000..9309bf3ea --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionPropertySymbol.cs @@ -0,0 +1,16 @@ +using System.Reflection; + +namespace IKVM.CoreLib.Symbols.Reflection +{ + + interface IReflectionPropertySymbol : IReflectionMemberSymbol, IPropertySymbol + { + + /// + /// Gets the underlying . + /// + PropertyInfo UnderlyingProperty { get; } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionSymbol.cs new file mode 100644 index 000000000..7db22745b --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionSymbol.cs @@ -0,0 +1,335 @@ +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Diagnostics.CodeAnalysis; +using System.Reflection; +using System.Reflection.Emit; + +using IKVM.CoreLib.Symbols.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.Reflection +{ + + interface IReflectionSymbol : ISymbol + { + + /// + /// Gets the that contains this symbol. + /// + ReflectionSymbolContext Context { get; } + + /// + /// Resolves the symbol for the specified assembly. + /// + /// + /// + [return: NotNullIfNotNull(nameof(assembly))] + IReflectionAssemblySymbol? ResolveAssemblySymbol(Assembly? assembly); + + /// + /// Resolves the symbol for the specified assembly builder. + /// + /// + /// + [return: NotNullIfNotNull(nameof(assembly))] + IReflectionAssemblySymbolBuilder ResolveAssemblySymbol(AssemblyBuilder assembly); + + /// + /// Resolves the symbols for the specified assemblies. + /// + /// + /// + [return: NotNullIfNotNull(nameof(assemblies))] + IReflectionAssemblySymbol[]? ResolveAssemblySymbols(Assembly[]? assemblies); + + /// + /// Resolves the symbol for the specified module. + /// + /// + /// + [return: NotNullIfNotNull(nameof(module))] + IReflectionModuleSymbol? ResolveModuleSymbol(Module? module); + + /// + /// Resolves the symbol for the specified module. + /// + /// + /// + [return: NotNullIfNotNull(nameof(module))] + IReflectionModuleSymbolBuilder ResolveModuleSymbol(ModuleBuilder module); + + /// + /// Resolves the symbols for the specified modules. + /// + /// + /// + [return: NotNullIfNotNull(nameof(modules))] + IReflectionModuleSymbol[]? ResolveModuleSymbols(Module[]? modules); + + /// + /// Resolves the symbols for the specified modules. + /// + /// + /// + IEnumerable ResolveModuleSymbols(IEnumerable modules); + + /// + /// Resolves the symbol for the specified member. + /// + /// + /// + [return: NotNullIfNotNull(nameof(member))] + IReflectionMemberSymbol? ResolveMemberSymbol(MemberInfo? member); + + /// + /// Resolves the symbols for the specified members. + /// + /// + /// + [return: NotNullIfNotNull(nameof(types))] + IReflectionMemberSymbol[]? ResolveMemberSymbols(MemberInfo[]? types); + + /// + /// Resolves the symbol for the specified type. + /// + /// + /// + [return: NotNullIfNotNull(nameof(type))] + IReflectionTypeSymbol? ResolveTypeSymbol(Type? type); + + /// + /// Resolves the symbol for the specified type. + /// + /// + /// + [return: NotNullIfNotNull(nameof(type))] + IReflectionTypeSymbolBuilder ResolveTypeSymbol(TypeBuilder type); + + /// + /// Resolves the symbols for the specified types. + /// + /// + /// + [return: NotNullIfNotNull(nameof(types))] + IReflectionTypeSymbol[]? ResolveTypeSymbols(Type[]? types); + + /// + /// Resolves the symbols for the specified types. + /// + /// + /// + IEnumerable ResolveTypeSymbols(IEnumerable types); + + /// + /// Resolves the symbol for the specified method. + /// + /// + /// + [return: NotNullIfNotNull(nameof(method))] + IReflectionMethodBaseSymbol? ResolveMethodBaseSymbol(MethodBase? method); + + /// + /// Resolves the symbol for the specified constructor. + /// + /// + /// + [return: NotNullIfNotNull(nameof(ctor))] + IReflectionConstructorSymbol? ResolveConstructorSymbol(ConstructorInfo? ctor); + + /// + /// Resolves the symbol for the specified constructor. + /// + /// + /// + [return: NotNullIfNotNull(nameof(ctor))] + IReflectionConstructorSymbolBuilder ResolveConstructorSymbol(ConstructorBuilder ctor); + + /// + /// Resolves the symbols for the specified constructors. + /// + /// + /// + [return: NotNullIfNotNull(nameof(ctors))] + IReflectionConstructorSymbol[]? ResolveConstructorSymbols(ConstructorInfo[]? ctors); + + /// + /// Resolves the symbol for the specified method. + /// + /// + /// + [return: NotNullIfNotNull(nameof(method))] + IReflectionMethodSymbol? ResolveMethodSymbol(MethodInfo? method); + + /// + /// Resolves the symbol for the specified method. + /// + /// + /// + [return: NotNullIfNotNull(nameof(method))] + IReflectionMethodSymbolBuilder ResolveMethodSymbol(MethodBuilder method); + + /// + /// Resolves the symbols for the specified methods. + /// + /// + /// + [return: NotNullIfNotNull(nameof(methods))] + IReflectionMethodSymbol[]? ResolveMethodSymbols(MethodInfo[]? methods); + + /// + /// Resolves the symbol for the specified field. + /// + /// + /// + [return: NotNullIfNotNull(nameof(field))] + IReflectionFieldSymbol? ResolveFieldSymbol(FieldInfo? field); + + /// + /// Resolves the symbol for the specified field. + /// + /// + /// + [return: NotNullIfNotNull(nameof(field))] + IReflectionFieldSymbolBuilder ResolveFieldSymbol(FieldBuilder field); + + /// + /// Resolves the symbols for the specified fields. + /// + /// + /// + [return: NotNullIfNotNull(nameof(fields))] + IReflectionFieldSymbol[]? ResolveFieldSymbols(FieldInfo[]? fields); + + /// + /// Resolves the symbol for the specified property. + /// + /// + /// + [return: NotNullIfNotNull(nameof(property))] + IReflectionPropertySymbol? ResolvePropertySymbol(PropertyInfo? property); + + /// + /// Resolves the symbol for the specified property. + /// + /// + /// + [return: NotNullIfNotNull(nameof(property))] + IReflectionPropertySymbolBuilder ResolvePropertySymbol(PropertyBuilder property); + + /// + /// Resolves the symbols for the specified properties. + /// + /// + /// + [return: NotNullIfNotNull(nameof(properties))] + IReflectionPropertySymbol[]? ResolvePropertySymbols(PropertyInfo[]? properties); + + /// + /// Resolves the symbol for the specified event. + /// + /// + /// + [return: NotNullIfNotNull(nameof(@event))] + IReflectionEventSymbol? ResolveEventSymbol(EventInfo? @event); + + /// + /// Resolves the symbol for the specified event. + /// + /// + /// + [return: NotNullIfNotNull(nameof(@event))] + IReflectionEventSymbolBuilder ResolveEventSymbol(EventBuilder @event); + + /// + /// Resolves the symbols for the specified events. + /// + /// + /// + [return: NotNullIfNotNull(nameof(events))] + IReflectionEventSymbol[]? ResolveEventSymbols(EventInfo[]? events); + + /// + /// Resolves the symbol for the specified parameter. + /// + /// + /// + [return: NotNullIfNotNull(nameof(parameter))] + IReflectionParameterSymbol? ResolveParameterSymbol(ParameterInfo? parameter); + + /// + /// Resolves the symbol for the specified parameter. + /// + /// + /// + [return: NotNullIfNotNull(nameof(parameter))] + IReflectionParameterSymbolBuilder? ResolveParameterSymbol(ParameterBuilder parameter); + + /// + /// Resolves the symbols for the specified parameters. + /// + /// + /// + [return: NotNullIfNotNull(nameof(parameters))] + IReflectionParameterSymbol[]? ResolveParameterSymbols(ParameterInfo[]? parameters); + + /// + /// Transforms a custom set of custom attribute data records to a symbol record. + /// + /// + /// + [return: NotNullIfNotNull(nameof(attributes))] + CustomAttribute[]? ResolveCustomAttributes(IList? attributes); + + /// + /// Transforms a custom set of custom attribute data records to a symbol record. + /// + /// + /// + IEnumerable ResolveCustomAttributes(IEnumerable attributes); + + /// + /// Transforms a custom attribute data record to a symbol record. + /// + /// + /// + [return: NotNullIfNotNull(nameof(customAttributeData))] + CustomAttribute? ResolveCustomAttribute(CustomAttributeData? customAttributeData); + + /// + /// Transforms a list of values into symbols. + /// + /// + /// + ImmutableArray ResolveCustomAttributeTypedArguments(IList args); + + /// + /// Transforms a values into a symbol. + /// + /// + /// + CustomAttributeTypedArgument ResolveCustomAttributeTypedArgument(System.Reflection.CustomAttributeTypedArgument arg); + + /// + /// Transforms the type as appropriate. + /// + /// + /// + object? ResolveCustomAttributeTypedValue(object? value); + + /// + /// Transforms a list of values into symbols. + /// + /// + /// + ImmutableArray ResolveCustomAttributeNamedArguments(IList args); + + /// + /// Transforms a values into a symbol. + /// + /// + /// + CustomAttributeNamedArgument ResolveCustomAttributeNamedArgument(System.Reflection.CustomAttributeNamedArgument arg); + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionTypeSymbol.cs new file mode 100644 index 000000000..fa7dc4bba --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionTypeSymbol.cs @@ -0,0 +1,16 @@ +using System; + +namespace IKVM.CoreLib.Symbols.Reflection +{ + + interface IReflectionTypeSymbol : IReflectionMemberSymbol, ITypeSymbol + { + + /// + /// Gets the underlying . + /// + Type UnderlyingType { get; } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblyMetadata.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblyMetadata.cs new file mode 100644 index 000000000..7ba66dc3e --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblyMetadata.cs @@ -0,0 +1,66 @@ +using System; +using System.Diagnostics; +using System.Reflection; +using System.Reflection.Emit; +using System.Threading; + +using IKVM.CoreLib.Collections; +using IKVM.CoreLib.Reflection; +using IKVM.CoreLib.Symbols.Reflection.Emit; +using IKVM.CoreLib.Threading; + +namespace IKVM.CoreLib.Symbols.Reflection +{ + + struct ReflectionAssemblyMetadata + { + + readonly IReflectionAssemblySymbol _symbol; + + IndexRangeDictionary _moduleSymbols = new(initialCapacity: 1, maxCapacity: 32); + ReaderWriterLockSlim? _moduleLock; + + /// + /// Initializes a new instance. + /// + /// + /// + public ReflectionAssemblyMetadata(IReflectionAssemblySymbol symbol) + { + _symbol = symbol ?? throw new ArgumentNullException(nameof(symbol)); + } + + /// + /// Gets or creates the cached for the module. + /// + /// + /// + /// + public IReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) + { + if (module is null) + throw new ArgumentNullException(nameof(module)); + + Debug.Assert(AssemblyNameEqualityComparer.Instance.Equals(module.Assembly.GetName(), _symbol.UnderlyingAssembly.GetName())); + + // create lock on demand + if (_moduleLock == null) + Interlocked.CompareExchange(ref _moduleLock, new ReaderWriterLockSlim(), null); + + using (_moduleLock.CreateUpgradeableReadLock()) + { + var row = module.GetMetadataTokenRowNumberSafe(); + if (_moduleSymbols[row] == null) + using (_moduleLock.CreateWriteLock()) + if (module is ModuleBuilder builder) + return _moduleSymbols[row] = new ReflectionModuleSymbolBuilder(_symbol.Context, _symbol, builder); + else + return _moduleSymbols[row] = new ReflectionModuleSymbol(_symbol.Context, _symbol, module); + else + return _moduleSymbols[row] ?? throw new InvalidOperationException(); + } + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs index ef66d94d1..3280e999b 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs @@ -1,24 +1,19 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; using System.Reflection; -using System.Threading; +using System.Reflection.Emit; -using IKVM.CoreLib.Collections; -using IKVM.CoreLib.Reflection; -using IKVM.CoreLib.Threading; +using IKVM.CoreLib.Symbols.Reflection.Emit; namespace IKVM.CoreLib.Symbols.Reflection { - class ReflectionAssemblySymbol : ReflectionSymbol, IAssemblySymbol + class ReflectionAssemblySymbol : ReflectionSymbol, IReflectionAssemblySymbol { - Assembly _assembly; - - IndexRangeDictionary _moduleSymbols = new(initialCapacity: 1, maxCapacity: 32); - ReaderWriterLockSlim? _moduleLock; + readonly Assembly _assembly; + ReflectionAssemblyMetadata _impl; /// /// Initializes a new instance. @@ -29,44 +24,21 @@ public ReflectionAssemblySymbol(ReflectionSymbolContext context, Assembly assemb base(context) { _assembly = assembly ?? throw new ArgumentNullException(nameof(assembly)); + _impl = new ReflectionAssemblyMetadata(this); } - internal Assembly ReflectionObject => _assembly; - /// - /// Gets or creates the cached for the module. + /// Gets the underlying instance. /// - /// - /// - /// - internal ReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) - { - if (module is null) - throw new ArgumentNullException(nameof(module)); - - Debug.Assert(AssemblyNameEqualityComparer.Instance.Equals(module.Assembly.GetName(), _assembly.GetName())); + public Assembly UnderlyingAssembly => _assembly; - // create lock on demand - if (_moduleLock == null) - lock (this) - _moduleLock ??= new ReaderWriterLockSlim(); - - using (_moduleLock.CreateUpgradeableReadLock()) - { - var row = module.GetMetadataTokenRowNumberSafe(); - if (_moduleSymbols[row] == null) - using (_moduleLock.CreateWriteLock()) - return _moduleSymbols[row] ??= new ReflectionModuleSymbol(Context, this, module); - else - return _moduleSymbols[row] ?? throw new InvalidOperationException(); - } - } + #region IAssemblySymbol /// public IEnumerable DefinedTypes => ResolveTypeSymbols(_assembly.DefinedTypes); /// - public IMethodSymbol? EntryPoint => _assembly.EntryPoint is { } m ? ResolveMethodSymbol(m) : null; + public IMethodSymbol? EntryPoint => ResolveMethodSymbol(_assembly.EntryPoint); /// public IEnumerable ExportedTypes => ResolveTypeSymbols(_assembly.ExportedTypes); @@ -92,7 +64,7 @@ public ITypeSymbol[] GetExportedTypes() /// public IModuleSymbol? GetModule(string name) { - return _assembly.GetModule(name) is Module m ? GetOrCreateModuleSymbol(m) : null; + return ResolveModuleSymbol(_assembly.GetModule(name)); } /// @@ -128,19 +100,19 @@ public AssemblyName[] GetReferencedAssemblies() /// public ITypeSymbol? GetType(string name, bool throwOnError) { - return _assembly.GetType(name, throwOnError) is Type t ? Context.GetOrCreateTypeSymbol(t) : null; + return ResolveTypeSymbol(_assembly.GetType(name, throwOnError)); } /// public ITypeSymbol? GetType(string name, bool throwOnError, bool ignoreCase) { - return _assembly.GetType(name, throwOnError, ignoreCase) is Type t ? Context.GetOrCreateTypeSymbol(t) : null; + return ResolveTypeSymbol(_assembly.GetType(name, throwOnError, ignoreCase)); } /// public ITypeSymbol? GetType(string name) { - return _assembly.GetType(name) is Type t ? Context.GetOrCreateTypeSymbol(t) : null; + return ResolveTypeSymbol(_assembly.GetType(name)); } /// @@ -158,7 +130,8 @@ public CustomAttribute[] GetCustomAttributes(bool inherit = false) /// public CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) { - return ResolveCustomAttributes(_assembly.GetCustomAttributesData().Where(i => i.AttributeType == ((ReflectionTypeSymbol)attributeType).ReflectionObject)); + var _attributeType = attributeType.Unpack(); + return ResolveCustomAttributes(_assembly.GetCustomAttributesData().Where(i => i.AttributeType == _attributeType).ToArray()); } /// @@ -170,16 +143,19 @@ public CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inh /// public bool IsDefined(ITypeSymbol attributeType, bool inherit = false) { - return _assembly.IsDefined(((ReflectionTypeSymbol)attributeType).ReflectionObject, false); + return _assembly.IsDefined(attributeType.Unpack(), inherit); } - /// - /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. - /// - /// - internal void Complete(Assembly assembly) + #endregion + + public IReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) + { + return _impl.GetOrCreateModuleSymbol(module); + } + + public IReflectionModuleSymbolBuilder GetOrCreateModuleSymbol(ModuleBuilder module) { - Context.GetOrCreateAssemblySymbol(_assembly = assembly); + return (IReflectionModuleSymbolBuilder)_impl.GetOrCreateModuleSymbol(module); } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionConstructorSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionConstructorSymbol.cs index b4d8759e7..6b30a2fc8 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionConstructorSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionConstructorSymbol.cs @@ -4,35 +4,26 @@ namespace IKVM.CoreLib.Symbols.Reflection { - class ReflectionConstructorSymbol : ReflectionMethodBaseSymbol, IConstructorSymbol + class ReflectionConstructorSymbol : ReflectionMethodBaseSymbol, IReflectionConstructorSymbol { + readonly ConstructorInfo _ctor; + /// /// Initializes a new instance. /// /// - /// + /// + /// /// - public ReflectionConstructorSymbol(ReflectionSymbolContext context, ReflectionTypeSymbol type, ConstructorInfo ctor) : - base(context, type, ctor) + public ReflectionConstructorSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol resolvingType, ConstructorInfo ctor) : + base(context, resolvingModule, resolvingType, ctor) { - + _ctor = ctor ?? throw new ArgumentNullException(nameof(ctor)); } - /// - /// Gets the underlying wrapped by this symbol. - /// - internal new ConstructorInfo ReflectionObject => (ConstructorInfo)base.ReflectionObject; - - - /// - /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. - /// - /// - internal void Complete(ConstructorInfo type) - { - base.Complete(type); - } + /// + public ConstructorInfo UnderlyingConstructor => _ctor; } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionEventSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionEventSymbol.cs index 81bcd813c..dc1b0c8ee 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionEventSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionEventSymbol.cs @@ -4,19 +4,20 @@ namespace IKVM.CoreLib.Symbols.Reflection { - class ReflectionEventSymbol : ReflectionMemberSymbol, IEventSymbol + class ReflectionEventSymbol : ReflectionMemberSymbol, IReflectionEventSymbol { - EventInfo _event; + readonly EventInfo _event; /// /// Initializes a new instance. /// /// - /// + /// + /// /// - public ReflectionEventSymbol(ReflectionSymbolContext context, ReflectionTypeSymbol type, EventInfo @event) : - base(context, type, @event) + public ReflectionEventSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol resolvingType, EventInfo @event) : + base(context, resolvingModule, resolvingType, @event) { _event = @event ?? throw new ArgumentNullException(nameof(@event)); } @@ -24,83 +25,77 @@ public ReflectionEventSymbol(ReflectionSymbolContext context, ReflectionTypeSymb /// /// Gets the underlying wrapped by this symbol. /// - internal new EventInfo ReflectionObject => _event; + public EventInfo UnderlyingEvent => _event; + + #region IEventSymbol /// - public EventAttributes Attributes => _event.Attributes; + public EventAttributes Attributes => UnderlyingEvent.Attributes; /// - public ITypeSymbol? EventHandlerType => _event.EventHandlerType is { } m ? ResolveTypeSymbol(m) : null; + public ITypeSymbol? EventHandlerType => ResolveTypeSymbol(UnderlyingEvent.EventHandlerType); /// - public bool IsSpecialName => _event.IsSpecialName; + public bool IsSpecialName => UnderlyingEvent.IsSpecialName; /// - public IMethodSymbol? AddMethod => _event.AddMethod is { } m ? ResolveMethodSymbol(m) : null; + public IMethodSymbol? AddMethod => ResolveMethodSymbol(UnderlyingEvent.AddMethod); /// - public IMethodSymbol? RemoveMethod => _event.RemoveMethod is { } m ? ResolveMethodSymbol(m) : null; + public IMethodSymbol? RemoveMethod => ResolveMethodSymbol(UnderlyingEvent.RemoveMethod); /// - public IMethodSymbol? RaiseMethod => _event.RaiseMethod is { } m ? ResolveMethodSymbol(m) : null; + public IMethodSymbol? RaiseMethod => ResolveMethodSymbol(UnderlyingEvent.RaiseMethod); /// public IMethodSymbol? GetAddMethod() { - return _event.GetAddMethod() is { } m ? ResolveMethodSymbol(m) : null; + return ResolveMethodSymbol(UnderlyingEvent.GetAddMethod()); } /// public IMethodSymbol? GetAddMethod(bool nonPublic) { - return _event.GetAddMethod(nonPublic) is { } m ? ResolveMethodSymbol(m) : null; + return ResolveMethodSymbol(UnderlyingEvent.GetAddMethod(nonPublic)); } /// public IMethodSymbol? GetRemoveMethod() { - return _event.GetRemoveMethod() is { } m ? ResolveMethodSymbol(m) : null; + return ResolveMethodSymbol(UnderlyingEvent.GetRemoveMethod()); } /// public IMethodSymbol? GetRemoveMethod(bool nonPublic) { - return _event.GetRemoveMethod(nonPublic) is { } m ? ResolveMethodSymbol(m) : null; + return ResolveMethodSymbol(UnderlyingEvent.GetRemoveMethod(nonPublic)); } /// public IMethodSymbol? GetRaiseMethod() { - return _event.GetRaiseMethod() is { } m ? ResolveMethodSymbol(m) : null; + return ResolveMethodSymbol(UnderlyingEvent.GetRaiseMethod()); } /// public IMethodSymbol? GetRaiseMethod(bool nonPublic) { - return _event.GetRaiseMethod(nonPublic) is { } m ? ResolveMethodSymbol(m) : null; + return ResolveMethodSymbol(UnderlyingEvent.GetRaiseMethod(nonPublic)); } /// public IMethodSymbol[] GetOtherMethods() { - return ResolveMethodSymbols(_event.GetOtherMethods()); + return ResolveMethodSymbols(UnderlyingEvent.GetOtherMethods()); } /// public IMethodSymbol[] GetOtherMethods(bool nonPublic) { - return ResolveMethodSymbols(_event.GetOtherMethods(nonPublic)); + return ResolveMethodSymbols(UnderlyingEvent.GetOtherMethods(nonPublic)); } - /// - /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. - /// - /// - internal void Complete(EventInfo @event) - { - ResolveEventSymbol(_event = @event); - base.Complete(_event); - } + #endregion } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionFieldSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionFieldSymbol.cs index ca18fda1a..8e476d98e 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionFieldSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionFieldSymbol.cs @@ -4,111 +4,92 @@ namespace IKVM.CoreLib.Symbols.Reflection { - class ReflectionFieldSymbol : ReflectionMemberSymbol, IFieldSymbol + class ReflectionFieldSymbol : ReflectionMemberSymbol, IReflectionFieldSymbol { - FieldInfo _field; + readonly FieldInfo _field; /// /// Initializes a new instance. /// /// - /// + /// + /// /// - public ReflectionFieldSymbol(ReflectionSymbolContext context, ReflectionModuleSymbol containingModule, FieldInfo field) : - base(context, containingModule, field) + public ReflectionFieldSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol? resolvingType, FieldInfo field) : + base(context, resolvingModule, resolvingType, field) { _field = field ?? throw new ArgumentNullException(nameof(field)); } - /// - /// Initializes a new instance. - /// - /// - /// - /// - public ReflectionFieldSymbol(ReflectionSymbolContext context, ReflectionTypeSymbol containingType, FieldInfo field) : - base(context, containingType, field) - { - _field = field ?? throw new ArgumentNullException(nameof(field)); - } + /// + public FieldInfo UnderlyingField => _field; - /// - /// Gets the underlying wrapped by this symbol. - /// - internal new FieldInfo ReflectionObject => (FieldInfo)base.ReflectionObject; + #region IFieldSymbol /// - public FieldAttributes Attributes => _field.Attributes; + public FieldAttributes Attributes => UnderlyingField.Attributes; /// - public ITypeSymbol FieldType => ResolveTypeSymbol(_field.FieldType); + public ITypeSymbol FieldType => ResolveTypeSymbol(UnderlyingField.FieldType); /// - public bool IsSpecialName => _field.IsSpecialName; + public bool IsSpecialName => UnderlyingField.IsSpecialName; /// - public bool IsAssembly => _field.IsAssembly; + public bool IsAssembly => UnderlyingField.IsAssembly; /// - public bool IsFamily => _field.IsFamily; + public bool IsFamily => UnderlyingField.IsFamily; /// - public bool IsFamilyAndAssembly => _field.IsFamilyAndAssembly; + public bool IsFamilyAndAssembly => UnderlyingField.IsFamilyAndAssembly; /// - public bool IsFamilyOrAssembly => _field.IsFamilyOrAssembly; + public bool IsFamilyOrAssembly => UnderlyingField.IsFamilyOrAssembly; /// - public bool IsInitOnly => _field.IsInitOnly; + public bool IsInitOnly => UnderlyingField.IsInitOnly; /// - public bool IsLiteral => _field.IsLiteral; + public bool IsLiteral => UnderlyingField.IsLiteral; #pragma warning disable SYSLIB0050 // Type or member is obsolete /// - public bool IsNotSerialized => _field.IsNotSerialized; + public bool IsNotSerialized => UnderlyingField.IsNotSerialized; #pragma warning restore SYSLIB0050 // Type or member is obsolete /// - public bool IsPinvokeImpl => _field.IsPinvokeImpl; + public bool IsPinvokeImpl => UnderlyingField.IsPinvokeImpl; /// - public bool IsPrivate => _field.IsPrivate; + public bool IsPrivate => UnderlyingField.IsPrivate; /// - public bool IsPublic => _field.IsPublic; + public bool IsPublic => UnderlyingField.IsPublic; /// - public bool IsStatic => _field.IsStatic; + public bool IsStatic => UnderlyingField.IsStatic; /// public ITypeSymbol[] GetOptionalCustomModifiers() { - return ResolveTypeSymbols(_field.GetOptionalCustomModifiers()); + return ResolveTypeSymbols(UnderlyingField.GetOptionalCustomModifiers()); } /// public ITypeSymbol[] GetRequiredCustomModifiers() { - return ResolveTypeSymbols(_field.GetRequiredCustomModifiers()); + return ResolveTypeSymbols(UnderlyingField.GetRequiredCustomModifiers()); } /// public object? GetRawConstantValue() { - return _field.GetRawConstantValue(); + return UnderlyingField.GetRawConstantValue(); } - /// - /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. - /// - /// - internal void Complete(FieldInfo field) - { - ResolveFieldSymbol(_field = field); - base.Complete(_field); - } + #endregion } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericTypeParameterSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericTypeParameterSymbol.cs new file mode 100644 index 000000000..a851d2cf9 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericTypeParameterSymbol.cs @@ -0,0 +1,562 @@ +using System; +using System.Diagnostics.CodeAnalysis; +using System.Reflection; + +namespace IKVM.CoreLib.Symbols.Reflection +{ + + class ReflectionGenericTypeParameterSymbol : ReflectionMemberSymbol, IReflectionTypeSymbol + { + + readonly IReflectionMethodSymbol? _resolvingMethod; + readonly Type _type; + ReflectionTypeImpl _impl; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + /// + /// + public ReflectionGenericTypeParameterSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol? resolvingType, IReflectionMethodSymbol? resolvingMethod, Type type) : + base(context, resolvingModule, resolvingType, type) + { + _resolvingMethod = resolvingMethod; + _type = type ?? throw new ArgumentNullException(nameof(type)); + _impl = new ReflectionTypeImpl(this); + } + + /// + /// Resolves the symbol for the specified type. + /// + /// + /// + [return: NotNullIfNotNull(nameof(type))] + public override IReflectionTypeSymbol? ResolveTypeSymbol(Type? type) + { + if (type == _type) + return this; + else + return base.ResolveTypeSymbol(type); + } + + /// + /// Gets the underlying . + /// + public Type UnderlyingType => _type; + + /// + /// Gets the method base that declares this type parameter. + /// + public IReflectionMethodBaseSymbol? ResolvingMethodBase => _resolvingMethod; + + #region ITypeSymbol + + /// + public TypeAttributes Attributes => _impl.Attributes; + + /// + public IAssemblySymbol Assembly => _impl.Assembly; + + /// + public IMethodBaseSymbol? DeclaringMethod => _impl.DeclaringMethod; + + /// + public string? AssemblyQualifiedName => _impl.AssemblyQualifiedName; + + /// + public string? FullName => _impl.FullName; + + /// + public string? Namespace => _impl.Namespace; + + /// + public TypeCode TypeCode => _impl.TypeCode; + + /// + public ITypeSymbol? BaseType => _impl.BaseType; + + /// + public bool ContainsGenericParameters => _impl.ContainsGenericParameters; + + /// + public GenericParameterAttributes GenericParameterAttributes => _impl.GenericParameterAttributes; + + /// + public int GenericParameterPosition => _impl.GenericParameterPosition; + + /// + public ITypeSymbol[] GenericTypeArguments => _impl.GenericTypeArguments; + + /// + public bool IsConstructedGenericType => _impl.IsConstructedGenericType; + + /// + public bool IsGenericType => _impl.IsGenericType; + + /// + public bool IsGenericTypeDefinition => _impl.IsGenericTypeDefinition; + + /// + public bool IsGenericParameter => _impl.IsGenericParameter; + + /// + public bool IsAutoLayout => _impl.IsAutoLayout; + + /// + public bool IsExplicitLayout => _impl.IsExplicitLayout; + + /// + public bool IsLayoutSequential => _impl.IsLayoutSequential; + + /// + public bool HasElementType => _impl.HasElementType; + + /// + public bool IsClass => _impl.IsClass; + + /// + public bool IsValueType => _impl.IsValueType; + + /// + public bool IsInterface => _impl.IsInterface; + + /// + public bool IsPrimitive => _impl.IsPrimitive; + + /// + public bool IsSZArray => _impl.IsSZArray; + + /// + public bool IsArray => _impl.IsArray; + + /// + public bool IsEnum => _impl.IsEnum; + + /// + public bool IsPointer => _impl.IsPointer; + + /// + public bool IsFunctionPointer => _impl.IsFunctionPointer; + + /// + public bool IsUnmanagedFunctionPointer => _impl.IsUnmanagedFunctionPointer; + + /// + public bool IsByRef => _impl.IsByRef; + + /// + public bool IsAbstract => _impl.IsAbstract; + + /// + public bool IsSealed => _impl.IsSealed; + + /// + public bool IsVisible => _impl.IsVisible; + + /// + public bool IsPublic => _impl.IsPublic; + + /// + public bool IsNotPublic => _impl.IsNotPublic; + + /// + public bool IsNested => _impl.IsNested; + + /// + public bool IsNestedAssembly => _impl.IsNestedAssembly; + + /// + public bool IsNestedFamANDAssem => _impl.IsNestedFamANDAssem; + + /// + public bool IsNestedFamily => _impl.IsNestedFamily; + + /// + public bool IsNestedFamORAssem => _impl.IsNestedFamORAssem; + + /// + public bool IsNestedPrivate => _impl.IsNestedPrivate; + + /// + public bool IsNestedPublic => _impl.IsNestedPublic; + + /// + public bool IsSerializable => _impl.IsSerializable; + + /// + public bool IsSignatureType => _impl.IsSignatureType; + + /// + public bool IsSpecialName => _impl.IsSpecialName; + + /// + public IConstructorSymbol? TypeInitializer => throw new NotImplementedException(); + + /// + public int GetArrayRank() + { + return _impl.GetArrayRank(); + } + + /// + public IMemberSymbol[] GetDefaultMembers() + { + return _impl.GetDefaultMembers(); + } + + /// + public ITypeSymbol? GetElementType() + { + return _impl.GetElementType(); + } + + /// + public string? GetEnumName(object value) + { + return _impl.GetEnumName(value); + } + + /// + public string[] GetEnumNames() + { + return _impl.GetEnumNames(); + } + + /// + public ITypeSymbol GetEnumUnderlyingType() + { + return _impl.GetEnumUnderlyingType(); + } + + /// + public ITypeSymbol[] GetGenericArguments() + { + return _impl.GetGenericArguments(); + } + + /// + public ITypeSymbol[] GetGenericParameterConstraints() + { + return _impl.GetGenericParameterConstraints(); + } + + /// + public ITypeSymbol GetGenericTypeDefinition() + { + return _impl.GetGenericTypeDefinition(); + } + + /// + public ITypeSymbol? GetInterface(string name) + { + return _impl.GetInterface(name); + } + + /// + public ITypeSymbol? GetInterface(string name, bool ignoreCase) + { + return _impl.GetInterface(name, ignoreCase); + } + + /// + public ITypeSymbol[] GetInterfaces(bool inherit = true) + { + return _impl.GetInterfaces(inherit); + } + + /// + public InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) + { + return _impl.GetInterfaceMap(interfaceType); + } + + /// + public IMemberSymbol[] GetMember(string name) + { + return _impl.GetMember(name); + } + + /// + public IMemberSymbol[] GetMember(string name, BindingFlags bindingAttr) + { + return _impl.GetMember(name, bindingAttr); + } + + /// + public IMemberSymbol[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) + { + return _impl.GetMember(name, type, bindingAttr); + } + + /// + public IMemberSymbol[] GetMembers() + { + return _impl.GetMembers(); + } + + /// + public IMemberSymbol[] GetMembers(BindingFlags bindingAttr) + { + return _impl.GetMembers(bindingAttr); + } + + public IConstructorSymbol? GetConstructor(ITypeSymbol[] types) + { + return _impl.GetConstructor(types); + } + + /// + public IConstructorSymbol? GetConstructor(BindingFlags bindingAttr, ITypeSymbol[] types) + { + return _impl.GetConstructor(bindingAttr, types); + } + + /// + public IConstructorSymbol[] GetConstructors() + { + return _impl.GetConstructors(); + } + + /// + public IConstructorSymbol[] GetConstructors(BindingFlags bindingAttr) + { + return _impl.GetConstructors(bindingAttr); + } + + /// + public IFieldSymbol? GetField(string name) + { + return _impl.GetField(name); + } + + /// + public IFieldSymbol? GetField(string name, BindingFlags bindingAttr) + { + return _impl.GetField(name, bindingAttr); + } + + /// + public IFieldSymbol[] GetFields() + { + return _impl.GetFields(); + } + + /// + public IFieldSymbol[] GetFields(BindingFlags bindingAttr) + { + return _impl.GetFields(bindingAttr); + } + + /// + public IMethodSymbol? GetMethod(string name) + { + return _impl.GetMethod(name); + } + + /// + public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) + { + return _impl.GetMethod(name, types); + } + + /// + public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr) + { + return _impl.GetMethod(name, bindingAttr); + } + + /// + public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types) + { + return _impl.GetMethod(name, bindingAttr, types); + } + + /// + public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers) + { + return _impl.GetMethod(name, bindingAttr, callConvention, types, modifiers); + } + + /// + public IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers) + { + return _impl.GetMethod(name, genericParameterCount, bindingAttr, callConvention, types, modifiers); + } + + /// + public IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, ITypeSymbol[] types, ParameterModifier[]? modifiers) + { + return _impl.GetMethod(name, genericParameterCount, bindingAttr, types, modifiers); + } + + /// + public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types, ParameterModifier[]? modifiers) + { + return _impl.GetMethod(name, bindingAttr, types, modifiers); + } + + /// + public IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, ParameterModifier[]? modifiers) + { + return _impl.GetMethod(name, genericParameterCount, types, modifiers); + } + + /// + public IMethodSymbol[] GetMethods() + { + return _impl.GetMethods(); + } + + /// + public IMethodSymbol[] GetMethods(BindingFlags bindingAttr) + { + return _impl.GetMethods(bindingAttr); + } + + /// + public IPropertySymbol? GetProperty(string name) + { + return _impl.GetProperty(name); + } + + /// + public IPropertySymbol? GetProperty(string name, BindingFlags bindingAttr) + { + return _impl.GetProperty(name, bindingAttr); + } + + /// + public IPropertySymbol? GetProperty(string name, ITypeSymbol[] types) + { + return _impl.GetProperty(name, types); + } + + /// + public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types) + { + return _impl.GetProperty(name, returnType, types); + } + + /// + public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) + { + return _impl.GetProperty(name, returnType); + } + + /// + public IPropertySymbol[] GetProperties() + { + return _impl.GetProperties(); + } + + /// + public IPropertySymbol[] GetProperties(BindingFlags bindingAttr) + { + return _impl.GetProperties(bindingAttr); + } + + /// + public IEventSymbol? GetEvent(string name) + { + return _impl.GetEvent(name); + } + + /// + public IEventSymbol? GetEvent(string name, BindingFlags bindingAttr) + { + return _impl.GetEvent(name, bindingAttr); + } + + /// + public IEventSymbol[] GetEvents() + { + return _impl.GetEvents(); + } + + /// + public IEventSymbol[] GetEvents(BindingFlags bindingAttr) + { + return _impl.GetEvents(bindingAttr); + } + + /// + public ITypeSymbol? GetNestedType(string name) + { + return _impl.GetNestedType(name); + } + + /// + public ITypeSymbol? GetNestedType(string name, BindingFlags bindingAttr) + { + return _impl.GetNestedType(name, bindingAttr); + } + + /// + public ITypeSymbol[] GetNestedTypes() + { + return _impl.GetNestedTypes(); + } + + /// + public ITypeSymbol[] GetNestedTypes(BindingFlags bindingAttr) + { + return _impl.GetNestedTypes(); + } + + /// + public bool IsAssignableFrom(ITypeSymbol? c) + { + return _impl.IsAssignableFrom(c); + } + + /// + public bool IsSubclassOf(ITypeSymbol c) + { + return _impl.IsSubclassOf(c); + } + + /// + public bool IsEnumDefined(object value) + { + return _impl.IsEnumDefined(value); + } + + /// + public ITypeSymbol MakeArrayType() + { + return _impl.MakeArrayType(); + } + + /// + public ITypeSymbol MakeArrayType(int rank) + { + return _impl.MakeArrayType(rank); + } + + /// + public ITypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments) + { + return _impl.MakeGenericType(typeArguments); + } + + /// + public ITypeSymbol MakePointerType() + { + return _impl.MakePointerType(); + } + + /// + public ITypeSymbol MakeByRefType() + { + return _impl.MakeByRefType(); + } + + #endregion + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs index 52b19f985..7037880a3 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs @@ -1,7 +1,12 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reflection; +using System.Reflection.Emit; + +using IKVM.CoreLib.Reflection; +using IKVM.CoreLib.Symbols.Reflection.Emit; namespace IKVM.CoreLib.Symbols.Reflection { @@ -9,7 +14,7 @@ namespace IKVM.CoreLib.Symbols.Reflection /// /// Obtains information about the attributes of a member and provides access to member metadata. /// - abstract class ReflectionMemberSymbol : ReflectionSymbol, IMemberSymbol + abstract class ReflectionMemberSymbol : ReflectionSymbol, IReflectionMemberSymbol { /// @@ -40,9 +45,9 @@ static T[] Concat(List? list) return a; } - readonly ReflectionModuleSymbol _containingModule; - readonly ReflectionTypeSymbol? _containingType; - MemberInfo _member; + readonly IReflectionModuleSymbol _resolvingModule; + readonly IReflectionTypeSymbol? _resolvingType; + readonly MemberInfo _member; CustomAttribute[]? _customAttributes; CustomAttribute[]? _inheritedCustomAttributes; @@ -51,137 +56,46 @@ static T[] Concat(List? list) /// Initializes a new instance. /// /// - /// + /// + /// /// - public ReflectionMemberSymbol(ReflectionSymbolContext context, ReflectionModuleSymbol containingModule, MemberInfo member) : + public ReflectionMemberSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol? resolvingType, MemberInfo member) : base(context) { - _containingModule = containingModule ?? throw new ArgumentNullException(nameof(containingModule)); + _resolvingModule = resolvingModule ?? throw new ArgumentNullException(nameof(resolvingModule)); + _resolvingType = resolvingType; _member = member ?? throw new ArgumentNullException(nameof(member)); } - /// - /// Initializes a new instance. - /// - /// - /// - /// - public ReflectionMemberSymbol(ReflectionSymbolContext context, ReflectionTypeSymbol containingType, MemberInfo member) : - this(context, containingType.ContainingModule, member) - { - _containingType = containingType ?? throw new ArgumentNullException(nameof(containingType)); - } - - /// - /// Resolves the symbol for the specified type. - /// - /// - /// - protected internal override ReflectionTypeSymbol ResolveTypeSymbol(Type type) - { - if (_containingType != null && type == _containingType.ReflectionObject) - return _containingType; - else if (type.Module == _member.Module) - return _containingModule.GetOrCreateTypeSymbol(type); - else - return base.ResolveTypeSymbol(type); - } - - /// - /// Resolves the symbol for the specified constructor. - /// - /// - /// - protected internal override ReflectionConstructorSymbol ResolveConstructorSymbol(ConstructorInfo ctor) - { - if (ctor.Module == _member.Module) - return _containingModule.GetOrCreateConstructorSymbol(ctor); - else - return base.ResolveConstructorSymbol(ctor); - } - - /// - /// Resolves the symbol for the specified method. - /// - /// - /// - protected internal override ReflectionMethodSymbol ResolveMethodSymbol(MethodInfo method) - { - if (method.Module == _member.Module) - return _containingModule.GetOrCreateMethodSymbol(method); - else - return base.ResolveMethodSymbol(method); - } - - /// - /// Resolves the symbol for the specified field. - /// - /// - /// - protected internal override ReflectionFieldSymbol ResolveFieldSymbol(FieldInfo field) - { - if (field.Module == _member.Module) - return _containingModule.GetOrCreateFieldSymbol(field); - else - return base.ResolveFieldSymbol(field); - } - - - /// - /// Resolves the symbol for the specified field. - /// - /// - /// - protected internal override ReflectionPropertySymbol ResolvePropertySymbol(PropertyInfo property) - { - if (property.Module == _member.Module) - return _containingModule.GetOrCreatePropertySymbol(property); - else - return base.ResolvePropertySymbol(property); - } - - /// - /// Resolves the symbol for the specified event. - /// - /// - /// - protected internal override ReflectionEventSymbol ResolveEventSymbol(EventInfo @event) - { - if (@event.Module == _member.Module) - return _containingModule.GetOrCreateEventSymbol(@event); - else - return base.ResolveEventSymbol(@event); - } + /// + public MemberInfo UnderlyingMember => _member; /// - /// Gets the underlying wrapped by this symbol. + /// Gets the which contains the metadata of this member. /// - internal MemberInfo ReflectionObject => _member; + public IReflectionModuleSymbol ResolvingModule => _resolvingModule; /// - /// Gets the which contains the metadata of this member. + /// Gets the which contains the metadata of this member, or null if the member is not a member of a type. /// - internal ReflectionModuleSymbol ContainingModule => _containingModule; + public IReflectionTypeSymbol? ResolvingType => _resolvingType; - /// - /// Gets the which contains the metadata of this member, or null if the member is not a member of a type. - /// - internal ReflectionTypeSymbol? ContainingType => _containingType; + #region IMemberSymbol /// - public virtual IModuleSymbol Module => Context.GetOrCreateModuleSymbol(_member.Module); + public virtual IModuleSymbol Module => ResolveModuleSymbol(UnderlyingMember.Module)!; /// - public virtual ITypeSymbol? DeclaringType => _member.DeclaringType is Type t ? Context.GetOrCreateTypeSymbol(t) : null; + public virtual ITypeSymbol? DeclaringType => ResolveTypeSymbol(UnderlyingMember.DeclaringType)!; /// - public virtual MemberTypes MemberType => _member.MemberType; + public virtual MemberTypes MemberType => UnderlyingMember.MemberType; /// - public virtual int MetadataToken => _member.MetadataToken; + public virtual int MetadataToken => UnderlyingMember.MetadataToken; /// - public virtual string Name => _member.Name; + public virtual string Name => UnderlyingMember.Name; /// public virtual CustomAttribute[] GetCustomAttributes(bool inherit = false) @@ -196,8 +110,11 @@ public virtual CustomAttribute[] GetCustomAttributes(bool inherit = false) var list = default(List?); for (; ; ) { + if (self == null) + throw new InvalidOperationException(); + // get attribute for current member and append to list - var attr = ResolveMemberSymbol(self).GetCustomAttributes(false); + var attr = ResolveMemberSymbol(self)!.GetCustomAttributes(false); if (attr.Length > 0) { list ??= []; @@ -231,7 +148,7 @@ public virtual CustomAttribute[] GetCustomAttributes(bool inherit = false) } } - return _customAttributes ??= ResolveCustomAttributes(_member.GetCustomAttributesData()); + return _customAttributes ??= ResolveCustomAttributes(UnderlyingMember.GetCustomAttributesData())!; } /// @@ -249,20 +166,201 @@ public virtual CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, /// public virtual bool IsDefined(ITypeSymbol attributeType, bool inherit = false) { - return _member.IsDefined(((ReflectionTypeSymbol)attributeType).ReflectionObject, inherit); + return UnderlyingMember.IsDefined(attributeType.Unpack(), inherit); } - /// - /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. - /// - /// - protected void Complete(MemberInfo member) + #endregion + + /// + [return: NotNullIfNotNull(nameof(type))] + public override IReflectionTypeSymbol? ResolveTypeSymbol(Type? type) { - ResolveMemberSymbol(_member = member); - _customAttributes = null; - _inheritedCustomAttributes = null; + if (type is null) + return null; + + if (_member == type) + return (IReflectionTypeSymbol)this; + + if (_resolvingType != null && type == _resolvingType.UnderlyingType) + return _resolvingType; + + if (type.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateTypeSymbol(type); + + return base.ResolveTypeSymbol(type); + } + + /// + [return: NotNullIfNotNull(nameof(ctor))] + public override IReflectionConstructorSymbol? ResolveConstructorSymbol(ConstructorInfo? ctor) + { + if (ctor is null) + return null; + + if (_member == ctor) + return (IReflectionConstructorSymbol)this; + + if (ctor.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateConstructorSymbol(ctor); + + return base.ResolveConstructorSymbol(ctor); + } + + /// + [return: NotNullIfNotNull(nameof(ctor))] + public override IReflectionConstructorSymbolBuilder ResolveConstructorSymbol(ConstructorBuilder ctor) + { + if (ctor is null) + throw new ArgumentNullException(nameof(ctor)); + + if (ctor.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateConstructorSymbol(ctor); + + return base.ResolveConstructorSymbol(ctor); + } + + /// + [return: NotNullIfNotNull(nameof(method))] + public override IReflectionMethodSymbol? ResolveMethodSymbol(MethodInfo? method) + { + if (method is null) + return null; + + if (_member == method) + return (IReflectionMethodSymbol)this; + + if (method.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateMethodSymbol(method); + + return base.ResolveMethodSymbol(method); + } + + /// + [return: NotNullIfNotNull(nameof(method))] + public override IReflectionMethodSymbolBuilder ResolveMethodSymbol(MethodBuilder method) + { + if (method is null) + throw new ArgumentNullException(nameof(method)); + + if (method.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateMethodSymbol(method); + + return base.ResolveMethodSymbol(method); + } + + /// + [return: NotNullIfNotNull(nameof(field))] + public override IReflectionFieldSymbol? ResolveFieldSymbol(FieldInfo? field) + { + if (field is null) + return null; + + if (_member == field) + return (IReflectionFieldSymbol)this; + + if (field.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateFieldSymbol(field); + + return base.ResolveFieldSymbol(field); + } + + /// + [return: NotNullIfNotNull(nameof(field))] + public override IReflectionFieldSymbolBuilder ResolveFieldSymbol(FieldBuilder field) + { + if (field is null) + throw new ArgumentNullException(nameof(field)); + + if (field.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateFieldSymbol(field); + + return base.ResolveFieldSymbol(field); + } + + /// + [return: NotNullIfNotNull(nameof(property))] + public override IReflectionPropertySymbol? ResolvePropertySymbol(PropertyInfo? property) + { + if (property is null) + return null; + + if (_member == property) + return (IReflectionPropertySymbol)this; + + if (property.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreatePropertySymbol(property); + + return base.ResolvePropertySymbol(property); + } + + /// + [return: NotNullIfNotNull(nameof(property))] + public override IReflectionPropertySymbolBuilder ResolvePropertySymbol(PropertyBuilder property) + { + if (property is null) + throw new ArgumentNullException(nameof(property)); + + if (property.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreatePropertySymbol(property); + + return base.ResolvePropertySymbol(property); + } + + /// + [return: NotNullIfNotNull(nameof(@event))] + public override IReflectionEventSymbol? ResolveEventSymbol(EventInfo? @event) + { + if (@event is null) + return null; + + if (_member == @event) + return (IReflectionEventSymbol)this; + + if (@event.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateEventSymbol(@event); + + return base.ResolveEventSymbol(@event); + } + + /// + [return: NotNullIfNotNull(nameof(@event))] + public override IReflectionEventSymbolBuilder ResolveEventSymbol(EventBuilder @event) + { + if (@event is null) + throw new ArgumentNullException(nameof(@event)); + + if (@event.GetModuleBuilder() == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateEventSymbol(@event); + + return base.ResolveEventSymbol(@event); + } + + /// + [return: NotNullIfNotNull(nameof(parameter))] + public override IReflectionParameterSymbol? ResolveParameterSymbol(ParameterInfo? parameter) + { + if (parameter is null) + throw new ArgumentNullException(nameof(parameter)); + + if (parameter.Member.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateParameterSymbol(parameter); + + return base.ResolveParameterSymbol(parameter); + } + + /// + [return: NotNullIfNotNull(nameof(parameter))] + public override IReflectionParameterSymbolBuilder ResolveParameterSymbol(ParameterBuilder parameter) + { + if (parameter is null) + throw new ArgumentNullException(nameof(parameter)); + + if (parameter.GetModuleBuilder() == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateParameterSymbol(parameter); + + return base.ResolveParameterSymbol(parameter); } } -} \ No newline at end of file +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodBaseSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodBaseSymbol.cs index 911580f57..76ae425fc 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodBaseSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodBaseSymbol.cs @@ -1,132 +1,111 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.Reflection; namespace IKVM.CoreLib.Symbols.Reflection { - abstract class ReflectionMethodBaseSymbol : ReflectionMemberSymbol, IMethodBaseSymbol + abstract class ReflectionMethodBaseSymbol : ReflectionMemberSymbol, IReflectionMethodBaseSymbol { - MethodBase _method; + readonly MethodBase _method; /// /// Initializes a new instance. /// /// - /// + /// + /// /// - public ReflectionMethodBaseSymbol(ReflectionSymbolContext context, ReflectionModuleSymbol module, MethodBase method) : - base(context, module, method) + public ReflectionMethodBaseSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol? resolvingType, MethodBase method) : + base(context, resolvingModule, resolvingType, method) { _method = method ?? throw new ArgumentNullException(nameof(method)); } - /// - /// Initializes a new instance. - /// - /// - /// - /// - /// - public ReflectionMethodBaseSymbol(ReflectionSymbolContext context, ReflectionTypeSymbol type, MethodBase method) : - this(context, type.ContainingModule, method) - { - - } + #region IMethodBaseSymbol /// /// Gets the underlying wrapped by this symbol. /// - internal new MethodBase ReflectionObject => _method; + public MethodBase UnderlyingMethodBase => _method; /// - public MethodAttributes Attributes => _method.Attributes; + public MethodAttributes Attributes => UnderlyingMethodBase.Attributes; /// - public CallingConventions CallingConvention => _method.CallingConvention; + public CallingConventions CallingConvention => UnderlyingMethodBase.CallingConvention; /// - public bool ContainsGenericParameters => _method.ContainsGenericParameters; + public bool ContainsGenericParameters => UnderlyingMethodBase.ContainsGenericParameters; /// - public bool IsAbstract => _method.IsAbstract; + public bool IsAbstract => UnderlyingMethodBase.IsAbstract; /// - public bool IsAssembly => _method.IsAssembly; + public bool IsAssembly => UnderlyingMethodBase.IsAssembly; /// - public bool IsConstructor => _method.IsConstructor; + public bool IsConstructor => UnderlyingMethodBase.IsConstructor; /// - public bool IsFamily => _method.IsFamily; + public bool IsFamily => UnderlyingMethodBase.IsFamily; /// - public bool IsFamilyAndAssembly => _method.IsFamilyAndAssembly; + public bool IsFamilyAndAssembly => UnderlyingMethodBase.IsFamilyAndAssembly; /// - public bool IsFamilyOrAssembly => _method.IsFamilyOrAssembly; + public bool IsFamilyOrAssembly => UnderlyingMethodBase.IsFamilyOrAssembly; /// - public bool IsFinal => _method.IsFinal; + public bool IsFinal => UnderlyingMethodBase.IsFinal; /// - public bool IsGenericMethod => _method.IsGenericMethod; + public bool IsGenericMethod => UnderlyingMethodBase.IsGenericMethod; /// - public bool IsGenericMethodDefinition => _method.IsGenericMethodDefinition; + public bool IsGenericMethodDefinition => UnderlyingMethodBase.IsGenericMethodDefinition; /// - public bool IsHideBySig => _method.IsHideBySig; + public bool IsHideBySig => UnderlyingMethodBase.IsHideBySig; /// - public bool IsPrivate => _method.IsPrivate; + public bool IsPrivate => UnderlyingMethodBase.IsPrivate; /// - public bool IsPublic => _method.IsPublic; + public bool IsPublic => UnderlyingMethodBase.IsPublic; /// - public bool IsStatic => _method.IsStatic; + public bool IsStatic => UnderlyingMethodBase.IsStatic; /// - public bool IsVirtual => _method.IsVirtual; + public bool IsVirtual => UnderlyingMethodBase.IsVirtual; /// - public bool IsSpecialName => _method.IsSpecialName; + public bool IsSpecialName => UnderlyingMethodBase.IsSpecialName; /// - public MethodImplAttributes MethodImplementationFlags => _method.MethodImplementationFlags; + public MethodImplAttributes MethodImplementationFlags => UnderlyingMethodBase.MethodImplementationFlags; /// public ITypeSymbol[] GetGenericArguments() { - return ResolveTypeSymbols(_method.GetGenericArguments()); + return ResolveTypeSymbols(UnderlyingMethodBase.GetGenericArguments()); } /// public MethodImplAttributes GetMethodImplementationFlags() { - return _method.GetMethodImplementationFlags(); + return UnderlyingMethodBase.GetMethodImplementationFlags(); } /// public IParameterSymbol[] GetParameters() { - return ResolveParameterSymbols(_method.GetParameters()); + return ResolveParameterSymbols(UnderlyingMethodBase.GetParameters()); } - /// - /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. - /// - /// - internal void Complete(MethodBase method) - { - ResolveMethodBaseSymbol(_method = method); - base.Complete(_method); - - foreach (var i in _method.GetParameters()) - ResolveParameterSymbol(i).Complete(i); - - } + #endregion } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs index dd970e657..4ee162e53 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs @@ -4,7 +4,7 @@ namespace IKVM.CoreLib.Symbols.Reflection { - class ReflectionMethodSymbol : ReflectionMethodBaseSymbol, IMethodSymbol + class ReflectionMethodSymbol : ReflectionMethodBaseSymbol, IReflectionMethodSymbol { readonly MethodInfo _method; @@ -16,34 +16,24 @@ class ReflectionMethodSymbol : ReflectionMethodBaseSymbol, IMethodSymbol /// /// /// - public ReflectionMethodSymbol(ReflectionSymbolContext context, ReflectionModuleSymbol module, MethodInfo method) : - base(context, module, method) + public ReflectionMethodSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol module, IReflectionTypeSymbol? type, MethodInfo method) : + base(context, module, type, method) { _method = method ?? throw new ArgumentNullException(nameof(method)); } /// - /// Initializes a new instance. + /// Gets the underlying wrapped by this symbol. /// - /// - /// - /// - public ReflectionMethodSymbol(ReflectionSymbolContext context, ReflectionTypeSymbol type, MethodInfo method) : - this(context, type.ContainingModule, method) - { + public MethodInfo UnderlyingMethod => _method; - } - - /// - /// Gets the underlying wrapped by this symbol. - /// - internal new MethodInfo ReflectionObject => _method; + #region IMethodSymbol /// - public IParameterSymbol ReturnParameter => ResolveParameterSymbol(_method.ReturnParameter); + public IParameterSymbol ReturnParameter => ResolveParameterSymbol(UnderlyingMethod.ReturnParameter); /// - public ITypeSymbol ReturnType => ResolveTypeSymbol(_method.ReturnType); + public ITypeSymbol ReturnType => ResolveTypeSymbol(UnderlyingMethod.ReturnType); /// public ICustomAttributeProvider ReturnTypeCustomAttributes => throw new NotImplementedException(); @@ -51,21 +41,23 @@ public ReflectionMethodSymbol(ReflectionSymbolContext context, ReflectionTypeSym /// public IMethodSymbol GetBaseDefinition() { - return ResolveMethodSymbol(_method.GetBaseDefinition()); + return ResolveMethodSymbol(UnderlyingMethod.GetBaseDefinition()); } /// public IMethodSymbol GetGenericMethodDefinition() { - return ResolveMethodSymbol(_method.GetGenericMethodDefinition()); + return ResolveMethodSymbol(UnderlyingMethod.GetGenericMethodDefinition()); } /// public IMethodSymbol MakeGenericMethod(params ITypeSymbol[] typeArguments) { - return ResolveMethodSymbol(_method.MakeGenericMethod(typeArguments.Unpack())); + return ResolveMethodSymbol(UnderlyingMethod.MakeGenericMethod(typeArguments.Unpack())); } + #endregion + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleMetadata.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleMetadata.cs new file mode 100644 index 000000000..f51709679 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleMetadata.cs @@ -0,0 +1,488 @@ +using System; +using System.Reflection; +using System.Reflection.Emit; +using System.Reflection.Metadata.Ecma335; +using System.Threading; + +using IKVM.CoreLib.Collections; +using IKVM.CoreLib.Reflection; +using IKVM.CoreLib.Symbols.Emit; +using IKVM.CoreLib.Symbols.Reflection.Emit; +using IKVM.CoreLib.Threading; + +namespace IKVM.CoreLib.Symbols.Reflection +{ + + /// + /// Provides the metadata resolution implementation for a module. + /// + struct ReflectionModuleMetadata + { + + /// + /// Returns true if the given is a TypeDef. That is, not a modified or substituted or generic parameter type. + /// + /// + /// + static bool IsTypeDefinition(Type type) + { +#if NET + return type.IsTypeDefinition; +#else + return type.HasElementType == false && type.IsConstructedGenericType == false && type.IsGenericParameter == false; +#endif + } + + const int MAX_CAPACITY = 65536 * 2; + + readonly IReflectionModuleSymbol _symbol; + + IndexRangeDictionary _typeSymbols = new(maxCapacity: MAX_CAPACITY); + ReaderWriterLockSlim? _typeLock; + + IndexRangeDictionary _methodSymbols = new(maxCapacity: MAX_CAPACITY); + ReaderWriterLockSlim? _methodLock; + + IndexRangeDictionary _fieldSymbols = new(maxCapacity: MAX_CAPACITY); + ReaderWriterLockSlim? _fieldLock; + + IndexRangeDictionary _propertySymbols = new(maxCapacity: MAX_CAPACITY); + ReaderWriterLockSlim? _propertyLock; + + IndexRangeDictionary _eventSymbols = new(maxCapacity: MAX_CAPACITY); + ReaderWriterLockSlim? _eventLock; + + IndexRangeDictionary _parameterSymbols = new(maxCapacity: MAX_CAPACITY); + ReaderWriterLockSlim? _parameterLock; + + IndexRangeDictionary _genericParameterSymbols = new(maxCapacity: MAX_CAPACITY); + ReaderWriterLockSlim? _genericParameterLock; + + /// + /// Initializes a new instance. + /// + /// + /// + public ReflectionModuleMetadata(IReflectionModuleSymbol symbol) + { + _symbol = symbol ?? throw new ArgumentNullException(nameof(symbol)); + } + + /// + /// Gets or creates the cached for the module by type. + /// + /// + /// + public IReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) + { + if (type is null) + throw new ArgumentNullException(nameof(type)); + if (type.Module.GetMetadataTokenSafe() != _symbol.MetadataToken) + throw new ArgumentException(nameof(type)); + + // type is a generic parameter (GenericParam) + if (type.IsGenericParameter) + return GetOrCreateGenericTypeParameterSymbol(type); + + // type is not a type definition (TypeDef) + if (IsTypeDefinition(type) == false) + return GetOrCreateTypeSymbolForSpecification(type); + + // create lock on demand + if (_typeLock == null) + Interlocked.CompareExchange(ref _typeLock, new ReaderWriterLockSlim(), null); + + using (_typeLock.CreateUpgradeableReadLock()) + { + var row = type.GetMetadataTokenRowNumberSafe(); + if (_typeSymbols[row] == null) + using (_typeLock.CreateWriteLock()) + if (type is TypeBuilder builder) + return _typeSymbols[row] ??= new ReflectionTypeSymbolBuilder(_symbol.Context, _symbol, builder); + else + return _typeSymbols[row] ??= new ReflectionTypeSymbol(_symbol.Context, _symbol, type); + else + return _typeSymbols[row] ?? throw new InvalidOperationException(); + } + } + + + /// + /// Gets or creates the cached for the module by type. + /// + /// + /// + public IReflectionTypeSymbolBuilder GetOrCreateTypeSymbol(TypeBuilder type) + { + return (IReflectionTypeSymbolBuilder)GetOrCreateTypeSymbol((Type)type); + } + + /// + /// Gets or creates a for the specification type: array, pointer, generic, etc. + /// + /// + /// + /// + /// + IReflectionTypeSymbol GetOrCreateTypeSymbolForSpecification(Type type) + { + if (type is null) + throw new ArgumentNullException(nameof(type)); + if (type.Module.GetMetadataTokenSafe() != _symbol.MetadataToken) + throw new ArgumentException(nameof(type)); + + if (type.GetElementType() is { } elementType) + { + var elementTypeSymbol = _symbol.ResolveTypeSymbol(elementType)!; + + // handles both SZ arrays and normal arrays + if (type.IsArray) + return (IReflectionTypeSymbol)elementTypeSymbol.MakeArrayType(type.GetArrayRank()); + + if (type.IsPointer) + return (IReflectionTypeSymbol)elementTypeSymbol.MakePointerType(); + + if (type.IsByRef) + return (IReflectionTypeSymbol)elementTypeSymbol.MakeByRefType(); + + throw new InvalidOperationException(); + } + + if (type.IsGenericType) + { + var definitionTypeSymbol = _symbol.GetOrCreateTypeSymbol(type.GetGenericTypeDefinition()); + return (IReflectionTypeSymbol)definitionTypeSymbol.MakeGenericType(definitionTypeSymbol.ResolveTypeSymbols(type.GetGenericArguments())!); + } + + throw new InvalidOperationException(); + } + + /// + /// Gets or creates the cached for the type by method. + /// + /// + /// + public IReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method) + { + if (method is null) + throw new ArgumentNullException(nameof(method)); + if (method.Module.GetMetadataTokenSafe() != _symbol.MetadataToken) + throw new ArgumentException(nameof(method)); + + // they are methods, but they are associated differently + if (method is DynamicMethod) + throw new ArgumentException("Dynamic methods cannot be attached to context."); + + // create lock on demand + if (_methodLock == null) + Interlocked.CompareExchange(ref _methodLock, new ReaderWriterLockSlim(), null); + + using (_methodLock.CreateUpgradeableReadLock()) + { + var row = method.GetMetadataTokenRowNumberSafe(); + if (_methodSymbols[row] == null) + { + using (_methodLock.CreateWriteLock()) + { + if (method is ConstructorInfo c) + { + if (method is ConstructorBuilder builder) + return _methodSymbols[row] ??= new ReflectionConstructorSymbolBuilder(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(c.DeclaringType!), builder); + else + return _methodSymbols[row] ??= new ReflectionConstructorSymbol(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(c.DeclaringType!), c); + } + else if (method is MethodInfo m) + { + if (method is MethodBuilder builder) + return _methodSymbols[row] ??= new ReflectionMethodSymbolBuilder(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(method.DeclaringType), builder); + else + return _methodSymbols[row] ??= new ReflectionMethodSymbol(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(method.DeclaringType), m); + } + else + { + throw new InvalidOperationException(); + } + } + } + else + { + return _methodSymbols[row] ?? throw new InvalidOperationException(); + } + } + } + + /// + /// Gets or creates the cached for the type by ctor. + /// + /// + /// + public IReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) + { + return (IReflectionConstructorSymbol)GetOrCreateMethodBaseSymbol(ctor); + } + + /// + /// Gets or creates the cached for the type by ctor. + /// + /// + /// + public IReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor) + { + return (IReflectionConstructorSymbolBuilder)GetOrCreateConstructorSymbol((ConstructorInfo)ctor); + } + + /// + /// Gets or creates the cached for the type by method. + /// + /// + /// + public IReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) + { + return (IReflectionMethodSymbol)GetOrCreateMethodBaseSymbol(method); + } + + /// + /// Gets or creates the cached for the type by method. + /// + /// + /// + public IReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method) + { + return (IReflectionMethodSymbolBuilder)GetOrCreateMethodBaseSymbol((MethodInfo)method); + } + + /// + /// Gets or creates the cached for the type by field. + /// + /// + /// + public IReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) + { + if (field is null) + throw new ArgumentNullException(nameof(field)); + if (field.Module.GetMetadataTokenSafe() != _symbol.MetadataToken) + throw new ArgumentException(nameof(field)); + + // create lock on demand + if (_fieldLock == null) + Interlocked.CompareExchange(ref _fieldLock, new ReaderWriterLockSlim(), null); + + using (_fieldLock.CreateUpgradeableReadLock()) + { + var row = field.GetMetadataTokenRowNumberSafe(); + if (_fieldSymbols[row] == null) + using (_fieldLock.CreateWriteLock()) + if (field is FieldBuilder builder) + return _fieldSymbols[row] ??= new ReflectionFieldSymbolBuilder(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(field.DeclaringType), builder); + else + return _fieldSymbols[row] ??= new ReflectionFieldSymbol(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(field.DeclaringType), field); + else + return _fieldSymbols[row] ?? throw new InvalidOperationException(); + } + } + + /// + /// Gets or creates the cached for the type by method. + /// + /// + /// + public IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field) + { + return (IReflectionFieldSymbolBuilder)GetOrCreateFieldSymbol((FieldInfo)field); + } + + /// + /// Gets or creates the cached for the type by property. + /// + /// + /// + public IReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) + { + if (property is null) + throw new ArgumentNullException(nameof(property)); + if (property.Module.GetMetadataTokenSafe() != _symbol.MetadataToken) + throw new ArgumentException(nameof(property)); + + // create lock on demand + if (_propertyLock == null) + Interlocked.CompareExchange(ref _propertyLock, new ReaderWriterLockSlim(), null); + + using (_propertyLock.CreateUpgradeableReadLock()) + { + var row = property.GetMetadataTokenRowNumberSafe(); + if (_propertySymbols[row] == null) + using (_propertyLock.CreateWriteLock()) + if (property is PropertyBuilder builder) + return _propertySymbols[row] ??= new ReflectionPropertySymbolBuilder(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(property.DeclaringType!), builder); + else + return _propertySymbols[row] ??= new ReflectionPropertySymbol(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(property.DeclaringType!), property); + else + return _propertySymbols[row] ?? throw new InvalidOperationException(); + } + } + + + /// + /// Gets or creates the cached for the type by property. + /// + /// + /// + public IReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property) + { + return (IReflectionPropertySymbolBuilder)GetOrCreatePropertySymbol((PropertyInfo)property); + } + + /// + /// Gets or creates the cached for the type by event. + /// + /// + /// + public IReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) + { + if (@event is null) + throw new ArgumentNullException(nameof(@event)); + if (@event.Module.GetMetadataTokenSafe() != _symbol.MetadataToken) + throw new ArgumentException(nameof(@event)); + + // create lock on demand + if (_eventLock == null) + Interlocked.CompareExchange(ref _eventLock, new ReaderWriterLockSlim(), null); + + using (_eventLock.CreateUpgradeableReadLock()) + { + var row = @event.GetMetadataTokenRowNumberSafe(); + if (_eventSymbols[row] == null) + using (_eventLock.CreateWriteLock()) + return _eventSymbols[row] ??= new ReflectionEventSymbol(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(@event.DeclaringType!), @event); + else + return _eventSymbols[row] ?? throw new InvalidOperationException(); + } + } + + /// + /// Gets or creates the cached for the type by event. + /// + /// + /// + public IReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event) + { + if (@event is null) + throw new ArgumentNullException(nameof(@event)); + if (@event.GetModuleBuilder().GetMetadataTokenSafe() != _symbol.MetadataToken) + throw new ArgumentException(nameof(@event)); + + // create lock on demand + if (_eventLock == null) + Interlocked.CompareExchange(ref _eventLock, new ReaderWriterLockSlim(), null); + + using (_eventLock.CreateUpgradeableReadLock()) + { + var row = @event.GetMetadataTokenRowNumberSafe(); + if (_eventSymbols[row] == null) + using (_eventLock.CreateWriteLock()) + return (IReflectionEventSymbolBuilder)(_eventSymbols[row] ??= new ReflectionEventSymbolBuilder(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(@event.GetTypeBuilder()), @event)); + else + return (IReflectionEventSymbolBuilder?)_eventSymbols[row] ?? throw new InvalidOperationException(); + } + } + + /// + /// Gets or creates the cached for the type by method. + /// + /// + /// + public IReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) + { + if (parameter is null) + throw new ArgumentNullException(nameof(parameter)); + if (parameter.Member.Module.GetMetadataTokenSafe() != _symbol.MetadataToken) + throw new ArgumentException(nameof(parameter)); + + // create lock on demand + if (_parameterLock == null) + Interlocked.CompareExchange(ref _parameterLock, new ReaderWriterLockSlim(), null); + + using (_parameterLock.CreateUpgradeableReadLock()) + { + var position = parameter.Position; + if (_parameterSymbols[position] == null) + using (_parameterLock.CreateWriteLock()) + return _parameterSymbols[position] ??= new ReflectionParameterSymbol(_symbol.Context, _symbol, _symbol.ResolveMethodBaseSymbol((MethodBase)parameter.Member), parameter); + else + return _parameterSymbols[position] ?? throw new InvalidOperationException(); + } + } + + /// + /// Gets or creates the cached for the type by method. + /// + /// + /// + public IReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter) + { + if (parameter is null) + throw new ArgumentNullException(nameof(parameter)); + if (parameter.GetModuleBuilder().GetMetadataTokenSafe() != _symbol.MetadataToken) + throw new ArgumentException(nameof(parameter)); + + // create lock on demand + if (_parameterLock == null) + Interlocked.CompareExchange(ref _parameterLock, new ReaderWriterLockSlim(), null); + + using (_parameterLock.CreateUpgradeableReadLock()) + { + var position = parameter.Position; + if (_parameterSymbols[position] == null) + using (_parameterLock.CreateWriteLock()) + return (IReflectionParameterSymbolBuilder)(_parameterSymbols[position] ??= new ReflectionParameterSymbolBuilder(_symbol.Context, _symbol, _symbol.ResolveMethodSymbol(parameter.GetMethodBuilder()), parameter)); + else + return (IReflectionParameterSymbolBuilder?)_parameterSymbols[position] ?? throw new InvalidOperationException(); + } + } + + /// + /// Gets or creates the cached for the module by type. + /// + /// + /// + IReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type genericParameterType) + { + if (genericParameterType is null) + throw new ArgumentNullException(nameof(genericParameterType)); + if (genericParameterType.Module.GetMetadataTokenSafe() != _symbol.MetadataToken) + throw new ArgumentException(nameof(genericParameterType)); + + // create lock on demand + if (_genericParameterLock == null) + Interlocked.CompareExchange(ref _genericParameterLock, new ReaderWriterLockSlim(), null); + + using (_genericParameterLock.CreateUpgradeableReadLock()) + { + var hnd = MetadataTokens.GenericParameterHandle(genericParameterType.GetMetadataTokenSafe()); + var row = MetadataTokens.GetRowNumber(hnd); + if (_genericParameterSymbols[row] == null) + using (_genericParameterLock.CreateWriteLock()) + if (genericParameterType is GenericTypeParameterBuilder builder) + return _genericParameterSymbols[row] ??= new ReflectionGenericTypeParameterSymbolBuilder(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(genericParameterType.DeclaringType), _symbol.ResolveMethodSymbol((MethodInfo?)genericParameterType.DeclaringMethod), builder); + else + return _genericParameterSymbols[row] ??= new ReflectionGenericTypeParameterSymbol(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(genericParameterType.DeclaringType), _symbol.ResolveMethodSymbol((MethodInfo?)genericParameterType.DeclaringMethod), genericParameterType); + else + { + return _genericParameterSymbols[row] ?? throw new InvalidOperationException(); + } + } + } + + /// + /// Gets or creates the cached for the module. + /// + /// + /// + IReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeParameterSymbol(GenericTypeParameterBuilder genericParameterType) + { + return (IReflectionGenericTypeParameterSymbolBuilder)GetOrCreateGenericTypeParameterSymbol((Type)genericParameterType); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs index 57717f7bc..bd247f2e7 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs @@ -1,13 +1,9 @@ using System; -using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; -using System.Reflection.Metadata.Ecma335; -using System.Threading; -using IKVM.CoreLib.Collections; -using IKVM.CoreLib.Threading; +using IKVM.CoreLib.Symbols.Reflection.Emit; namespace IKVM.CoreLib.Symbols.Reflection { @@ -15,525 +11,211 @@ namespace IKVM.CoreLib.Symbols.Reflection /// /// Implementation of derived from System.Reflection. /// - class ReflectionModuleSymbol : ReflectionSymbol, IModuleSymbol + class ReflectionModuleSymbol : ReflectionSymbol, IReflectionModuleSymbol { - /// - /// Returns true if the given is a TypeDef. That is, not a modified or substituted or generic parameter type. - /// - /// - /// - static bool IsTypeDefinition(Type type) - { -#if NET - return type.IsTypeDefinition; -#else - return type.HasElementType == false && type.IsConstructedGenericType == false && type.IsGenericParameter == false; -#endif - } - - const int MAX_CAPACITY = 65536 * 2; - const BindingFlags DefaultBindingFlags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance; - readonly ReflectionAssemblySymbol _containingAssembly; - Module _module; - - IndexRangeDictionary _typeSymbols = new(maxCapacity: MAX_CAPACITY); - ReaderWriterLockSlim? _typeLock; - - IndexRangeDictionary _methodSymbols = new(maxCapacity: MAX_CAPACITY); - ReaderWriterLockSlim? _methodLock; - - IndexRangeDictionary _fieldSymbols = new(maxCapacity: MAX_CAPACITY); - ReaderWriterLockSlim? _fieldLock; - - IndexRangeDictionary _propertySymbols = new(maxCapacity: MAX_CAPACITY); - ReaderWriterLockSlim? _propertyLock; - - IndexRangeDictionary _eventSymbols = new(maxCapacity: MAX_CAPACITY); - ReaderWriterLockSlim? _eventLock; - - IndexRangeDictionary _parameterSymbols = new(maxCapacity: MAX_CAPACITY); - ReaderWriterLockSlim? _parameterLock; - - IndexRangeDictionary _genericParameterSymbols = new(maxCapacity: MAX_CAPACITY); - ReaderWriterLockSlim? _genericParameterLock; + readonly IReflectionAssemblySymbol _resolvingAssembly; + readonly Module _module; + ReflectionModuleMetadata _impl; /// /// Initializes a new instance. /// /// - /// + /// /// /// - public ReflectionModuleSymbol(ReflectionSymbolContext context, ReflectionAssemblySymbol containingAssembly, Module module) : + public ReflectionModuleSymbol(ReflectionSymbolContext context, IReflectionAssemblySymbol resolvingAssembly, Module module) : base(context) { - _containingAssembly = containingAssembly ?? throw new ArgumentNullException(nameof(containingAssembly)); + _resolvingAssembly = resolvingAssembly ?? throw new ArgumentNullException(nameof(resolvingAssembly)); _module = module ?? throw new ArgumentNullException(nameof(module)); + _impl = new ReflectionModuleMetadata(this); } - /// - /// Gets the which contains the metadata of this member. - /// - internal ReflectionAssemblySymbol ContainingAssembly => _containingAssembly; - - /// - /// Gets the wrapped . - /// - internal Module ReflectionObject => _module; - - /// - /// Gets or creates the cached for the module by type. - /// - /// - /// - /// - internal ReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) - { - if (type is null) - throw new ArgumentNullException(nameof(type)); - - Debug.Assert(type.Module == _module); - - // type is a generic parameter (GenericParam) - if (type.IsGenericParameter) - return GetOrCreateGenericParameterSymbol(type); - - // type is not a type definition (TypeDef) - if (IsTypeDefinition(type) == false) - return GetOrCreateTypeSymbolForSpecification(type); - - // create lock on demand - if (_typeLock == null) - Interlocked.CompareExchange(ref _typeLock, new ReaderWriterLockSlim(), null); - - using (_typeLock.CreateUpgradeableReadLock()) - { - var row = type.GetMetadataTokenRowNumberSafe(); - if (_typeSymbols[row] == null) - using (_typeLock.CreateWriteLock()) - return _typeSymbols[row] ??= new ReflectionTypeSymbol(Context, this, type); - else - return _typeSymbols[row] ?? throw new InvalidOperationException(); - } - } - - /// - /// Gets or creates a for the specification type: array, pointer, etc. - /// - /// - /// - /// - /// - ReflectionTypeSymbol GetOrCreateTypeSymbolForSpecification(Type type) - { - if (type is null) - throw new ArgumentNullException(nameof(type)); - - Debug.Assert(type.Module == _module); - - if (type.GetElementType() is { } elementType) - { - var elementTypeSymbol = ResolveTypeSymbol(elementType); - - // handles both SZ arrays and normal arrays - if (type.IsArray) - return (ReflectionTypeSymbol)elementTypeSymbol.MakeArrayType(type.GetArrayRank()); - - if (type.IsPointer) - return (ReflectionTypeSymbol)elementTypeSymbol.MakePointerType(); - - if (type.IsByRef) - return (ReflectionTypeSymbol)elementTypeSymbol.MakeByRefType(); - - throw new InvalidOperationException(); - } - - if (type.IsGenericType) - { - var definitionTypeSymbol = ResolveTypeSymbol(type.GetGenericTypeDefinition()); - return definitionTypeSymbol.GetOrCreateGenericTypeSymbol(ResolveTypeSymbols(type.GetGenericArguments())); - } - - throw new InvalidOperationException(); - } - - /// - /// Gets or creates the cached for the type by method. - /// - /// - /// - internal ReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method) - { - if (method is null) - throw new ArgumentNullException(nameof(method)); - - Debug.Assert(method.Module.GetMetadataTokenSafe() == _module.GetMetadataTokenSafe()); - - // they are methods, but they are associated differently - if (method is DynamicMethod) - throw new ArgumentException("Dynamic methods cannot be attached to context."); - - // create lock on demand - if (_methodLock == null) - Interlocked.CompareExchange(ref _methodLock, new ReaderWriterLockSlim(), null); - - using (_methodLock.CreateUpgradeableReadLock()) - { - var row = method.GetMetadataTokenRowNumberSafe(); - if (_methodSymbols[row] == null) - using (_methodLock.CreateWriteLock()) - if (method is ConstructorInfo c) - return _methodSymbols[row] ??= new ReflectionConstructorSymbol(Context, ResolveTypeSymbol(c.DeclaringType ?? throw new InvalidOperationException()), c); - else if (method is MethodInfo m) - if (method.DeclaringType is { } dt) - return _methodSymbols[row] ??= new ReflectionMethodSymbol(Context, ResolveTypeSymbol(dt), m); - else - return _methodSymbols[row] ??= new ReflectionMethodSymbol(Context, this, m); - else - throw new InvalidOperationException(); - else - return _methodSymbols[row] ?? throw new InvalidOperationException(); - } - } - - /// - /// Gets or creates the cached for the type by ctor. - /// - /// - /// - internal ReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) - { - return (ReflectionConstructorSymbol)GetOrCreateMethodBaseSymbol(ctor); - } - - /// - /// Gets or creates the cached for the type by method. - /// - /// - /// - internal ReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) - { - return (ReflectionMethodSymbol)GetOrCreateMethodBaseSymbol(method); - } - - /// - /// Gets or creates the cached for the type by field. - /// - /// - /// - /// - internal ReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) - { - if (field is null) - throw new ArgumentNullException(nameof(field)); - - Debug.Assert(field.Module == _module); - - // create lock on demand - if (_fieldLock == null) - Interlocked.CompareExchange(ref _fieldLock, new ReaderWriterLockSlim(), null); - - using (_fieldLock.CreateUpgradeableReadLock()) - { - var row = field.GetMetadataTokenRowNumberSafe(); - if (_fieldSymbols[row] == null) - using (_fieldLock.CreateWriteLock()) - if (field.DeclaringType is { } dt) - return _fieldSymbols[row] ??= new ReflectionFieldSymbol(Context, ResolveTypeSymbol(dt), field); - else - return _fieldSymbols[row] ??= new ReflectionFieldSymbol(Context, this, field); - else - return _fieldSymbols[row] ?? throw new InvalidOperationException(); - } - } - - /// - /// Gets or creates the cached for the type by property. - /// - /// - /// - /// - internal ReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) - { - if (property is null) - throw new ArgumentNullException(nameof(property)); - - Debug.Assert(property.Module == _module); - - // create lock on demand - if (_propertyLock == null) - Interlocked.CompareExchange(ref _propertyLock, new ReaderWriterLockSlim(), null); - - using (_propertyLock.CreateUpgradeableReadLock()) - { - var row = property.GetMetadataTokenRowNumberSafe(); - if (_propertySymbols[row] == null) - using (_propertyLock.CreateWriteLock()) - return _propertySymbols[row] ??= new ReflectionPropertySymbol(Context, ResolveTypeSymbol(property.DeclaringType!), property); - else - return _propertySymbols[row] ?? throw new InvalidOperationException(); - } - } - - /// - /// Gets or creates the cached for the type by event. - /// - /// - /// - /// - internal ReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) - { - if (@event is null) - throw new ArgumentNullException(nameof(@event)); - - Debug.Assert(@event.Module == _module); - - // create lock on demand - if (_eventLock == null) - Interlocked.CompareExchange(ref _eventLock, new ReaderWriterLockSlim(), null); - - using (_eventLock.CreateUpgradeableReadLock()) - { - var row = @event.GetMetadataTokenRowNumberSafe(); - if (_eventSymbols[row] == null) - using (_eventLock.CreateWriteLock()) - return _eventSymbols[row] ??= new ReflectionEventSymbol(Context, ResolveTypeSymbol(@event.DeclaringType!), @event); - else - return _eventSymbols[row] ?? throw new InvalidOperationException(); - } - } - - /// - /// Gets or creates the cached for the type by method. - /// - /// - /// - internal ReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) - { - if (parameter is null) - throw new ArgumentNullException(nameof(parameter)); - - Debug.Assert(parameter.Member.Module == _module); - - // create lock on demand - if (_parameterLock == null) - Interlocked.CompareExchange(ref _parameterLock, new ReaderWriterLockSlim(), null); - - using (_parameterLock.CreateUpgradeableReadLock()) - { - var position = parameter.Position; - if (_parameterSymbols[position] == null) - using (_parameterLock.CreateWriteLock()) - return _parameterSymbols[position] ??= new ReflectionParameterSymbol(Context, ResolveMethodBaseSymbol((MethodBase)parameter.Member), parameter); - else - return _parameterSymbols[position] ?? throw new InvalidOperationException(); - } - } - - /// - /// Gets or creates the cached for the module by type. - /// - /// - /// - /// - internal ReflectionTypeSymbol GetOrCreateGenericParameterSymbol(Type genericParameterType) - { - if (genericParameterType is null) - throw new ArgumentNullException(nameof(genericParameterType)); - - Debug.Assert(genericParameterType.Module == _module); + /// + public Module UnderlyingModule => _module; - // create lock on demand - if (_genericParameterLock == null) - Interlocked.CompareExchange(ref _genericParameterLock, new ReaderWriterLockSlim(), null); + /// + public IReflectionAssemblySymbol ResolvingAssembly => _resolvingAssembly; - using (_genericParameterLock.CreateUpgradeableReadLock()) - { - var hnd = MetadataTokens.GenericParameterHandle(genericParameterType.GetMetadataTokenSafe()); - var row = MetadataTokens.GetRowNumber(hnd); - if (_genericParameterSymbols[row] == null) - using (_genericParameterLock.CreateWriteLock()) - return _genericParameterSymbols[row] ??= new ReflectionTypeSymbol(Context, this, genericParameterType); - else - return _genericParameterSymbols[row] ?? throw new InvalidOperationException(); - } - } + #region IModuleSymbol /// - public IAssemblySymbol Assembly => Context.GetOrCreateAssemblySymbol(_module.Assembly); + public IAssemblySymbol Assembly => ResolveAssemblySymbol(UnderlyingModule.Assembly); /// - public string FullyQualifiedName => _module.FullyQualifiedName; + public string FullyQualifiedName => UnderlyingModule.FullyQualifiedName; /// - public int MetadataToken => _module.MetadataToken; + public int MetadataToken => UnderlyingModule.MetadataToken; /// - public Guid ModuleVersionId => _module.ModuleVersionId; + public Guid ModuleVersionId => UnderlyingModule.ModuleVersionId; /// - public string Name => _module.Name; + public string Name => UnderlyingModule.Name; /// - public string ScopeName => _module.ScopeName; + public string ScopeName => UnderlyingModule.ScopeName; /// public IFieldSymbol? GetField(string name) { - return _module.GetField(name) is { } f ? ResolveFieldSymbol(f) : null; + return ResolveFieldSymbol(UnderlyingModule.GetField(name)); } /// public IFieldSymbol? GetField(string name, BindingFlags bindingAttr) { - return _module.GetField(name, bindingAttr) is { } f ? ResolveFieldSymbol(f) : null; + return ResolveFieldSymbol(UnderlyingModule.GetField(name, bindingAttr)); } /// public IFieldSymbol[] GetFields(BindingFlags bindingFlags) { - return ResolveFieldSymbols(_module.GetFields(bindingFlags)); + return ResolveFieldSymbols(UnderlyingModule.GetFields(bindingFlags))!; } /// public IFieldSymbol[] GetFields() { - return ResolveFieldSymbols(_module.GetFields()); + return ResolveFieldSymbols(UnderlyingModule.GetFields())!; } /// public IMethodSymbol? GetMethod(string name) { - return _module.GetMethod(name) is { } m ? ResolveMethodSymbol(m) : null; + return ResolveMethodSymbol(UnderlyingModule.GetMethod(name)); } /// public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) { - return _module.GetMethod(name, types.Unpack()) is { } m ? ResolveMethodSymbol(m) : null; + return ResolveMethodSymbol(UnderlyingModule.GetMethod(name, types.Unpack())); } /// public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers) { - return _module.GetMethod(name, bindingAttr, null, callConvention, types.Unpack(), modifiers) is { } m ? ResolveMethodSymbol(m) : null; + return ResolveMethodSymbol(UnderlyingModule.GetMethod(name, bindingAttr, null, callConvention, types.Unpack(), modifiers)); } /// public IMethodSymbol[] GetMethods() { - return ResolveMethodSymbols(_module.GetMethods()); + return ResolveMethodSymbols(UnderlyingModule.GetMethods())!; } /// public IMethodSymbol[] GetMethods(BindingFlags bindingFlags) { - return ResolveMethodSymbols(_module.GetMethods(bindingFlags)); + return ResolveMethodSymbols(UnderlyingModule.GetMethods(bindingFlags))!; } /// public ITypeSymbol? GetType(string className) { - return _module.GetType(className) is { } t ? ResolveTypeSymbol(t) : null; + return ResolveTypeSymbol(UnderlyingModule.GetType(className)); } /// public ITypeSymbol? GetType(string className, bool ignoreCase) { - return _module.GetType(className, ignoreCase) is { } t ? ResolveTypeSymbol(t) : null; + return ResolveTypeSymbol(UnderlyingModule.GetType(className, ignoreCase)); } /// public ITypeSymbol? GetType(string className, bool throwOnError, bool ignoreCase) { - return _module.GetType(className, throwOnError, ignoreCase) is { } t ? ResolveTypeSymbol(t) : null; + return ResolveTypeSymbol(UnderlyingModule.GetType(className, throwOnError, ignoreCase)); } /// public ITypeSymbol[] GetTypes() { - return ResolveTypeSymbols(_module.GetTypes()); + return ResolveTypeSymbols(UnderlyingModule.GetTypes())!; } /// public bool IsResource() { - return _module.IsResource(); + return UnderlyingModule.IsResource(); } /// public IFieldSymbol? ResolveField(int metadataToken) { - return _module.ResolveField(metadataToken) is { } f ? ResolveFieldSymbol(f) : null; + return ResolveFieldSymbol(UnderlyingModule.ResolveField(metadataToken)); } /// public IFieldSymbol? ResolveField(int metadataToken, ITypeSymbol[]? genericTypeArguments, ITypeSymbol[]? genericMethodArguments) { - return _module.ResolveField(metadataToken, genericTypeArguments?.Unpack(), genericMethodArguments?.Unpack()) is { } f ? ResolveFieldSymbol(f) : null; + return ResolveFieldSymbol(UnderlyingModule.ResolveField(metadataToken, genericTypeArguments?.Unpack(), genericMethodArguments?.Unpack())); } /// public IMemberSymbol? ResolveMember(int metadataToken) { - return _module.ResolveMember(metadataToken) is { } m ? ResolveMemberSymbol(m) : null; + return ResolveMemberSymbol(UnderlyingModule.ResolveMember(metadataToken)); } /// public IMemberSymbol? ResolveMember(int metadataToken, ITypeSymbol[]? genericTypeArguments, ITypeSymbol[]? genericMethodArguments) { - return _module.ResolveMember(metadataToken, genericTypeArguments?.Unpack(), genericMethodArguments?.Unpack()) is { } m ? ResolveMemberSymbol(m) : null; + return ResolveMemberSymbol(UnderlyingModule.ResolveMember(metadataToken, genericTypeArguments?.Unpack(), genericMethodArguments?.Unpack())); } /// public IMethodBaseSymbol? ResolveMethod(int metadataToken, ITypeSymbol[]? genericTypeArguments, ITypeSymbol[]? genericMethodArguments) { - return _module.ResolveMethod(metadataToken, genericTypeArguments?.Unpack(), genericMethodArguments?.Unpack()) is { } m ? ResolveMethodBaseSymbol(m) : null; + return ResolveMethodBaseSymbol(UnderlyingModule.ResolveMethod(metadataToken, genericTypeArguments?.Unpack(), genericMethodArguments?.Unpack())); } /// public IMethodBaseSymbol? ResolveMethod(int metadataToken) { - return _module.ResolveMethod(metadataToken) is { } m ? ResolveMethodBaseSymbol(m) : null; + return ResolveMethodBaseSymbol(UnderlyingModule.ResolveMethod(metadataToken)); } /// public byte[] ResolveSignature(int metadataToken) { - return _module.ResolveSignature(metadataToken); + return UnderlyingModule.ResolveSignature(metadataToken); } /// public string ResolveString(int metadataToken) { - return _module.ResolveString(metadataToken); + return UnderlyingModule.ResolveString(metadataToken); } /// public ITypeSymbol ResolveType(int metadataToken) { - return ResolveTypeSymbol(_module.ResolveType(metadataToken)); + return ResolveTypeSymbol(UnderlyingModule.ResolveType(metadataToken)); } /// public ITypeSymbol ResolveType(int metadataToken, ITypeSymbol[]? genericTypeArguments, ITypeSymbol[]? genericMethodArguments) { - return ResolveTypeSymbol(_module.ResolveType(metadataToken, genericTypeArguments?.Unpack(), genericMethodArguments?.Unpack())); + return ResolveTypeSymbol(UnderlyingModule.ResolveType(metadataToken, genericTypeArguments?.Unpack(), genericMethodArguments?.Unpack())); } /// public CustomAttribute[] GetCustomAttributes(bool inherit = false) { - return ResolveCustomAttributes(_module.GetCustomAttributesData()); + return ResolveCustomAttributes(UnderlyingModule.GetCustomAttributesData()); } /// public CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) { - return ResolveCustomAttributes(_module.GetCustomAttributesData().Where(i => i.AttributeType == ((ReflectionTypeSymbol)attributeType).ReflectionObject)); + var _attributeType = attributeType.Unpack(); + return ResolveCustomAttributes(UnderlyingModule.GetCustomAttributesData().Where(i => i.AttributeType == _attributeType).ToArray()); } /// @@ -545,17 +227,93 @@ public CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inh /// public bool IsDefined(ITypeSymbol attributeType, bool inherit = false) { - return _module.IsDefined(((ReflectionTypeSymbol)attributeType).ReflectionObject, false); + return UnderlyingModule.IsDefined(attributeType.Unpack(), false); } - /// - /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. - /// - /// - internal void Complete(Module module) + #endregion + + /// + public IReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) + { + return _impl.GetOrCreateTypeSymbol(type); + } + + /// + public IReflectionTypeSymbolBuilder GetOrCreateTypeSymbol(TypeBuilder type) + { + return _impl.GetOrCreateTypeSymbol(type); + } + + /// + public IReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) + { + return _impl.GetOrCreateConstructorSymbol(ctor); + } + + /// + public IReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor) + { + return _impl.GetOrCreateConstructorSymbol(ctor); + } + + /// + public IReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) + { + return _impl.GetOrCreateMethodSymbol(method); + } + + /// + public IReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method) + { + return _impl.GetOrCreateMethodSymbol(method); + } + + /// + public IReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) + { + return _impl.GetOrCreateFieldSymbol(field); + } + + /// + public IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field) + { + return _impl.GetOrCreateFieldSymbol(field); + } + + /// + public IReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) + { + return _impl.GetOrCreatePropertySymbol(property); + } + + /// + public IReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property) + { + return _impl.GetOrCreatePropertySymbol(property); + } + + /// + public IReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) + { + return _impl.GetOrCreateEventSymbol(@event); + } + + /// + public IReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event) + { + return _impl.GetOrCreateEventSymbol(@event); + } + + /// + public IReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) + { + return _impl.GetOrCreateParameterSymbol(parameter); + } + + /// + public IReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter) { - ResolveModuleSymbol(_module = module); - ContainingAssembly.Complete(_module.Assembly); + return _impl.GetOrCreateParameterSymbol(parameter); } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterSymbol.cs index 931bb03ce..22628fd9d 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterSymbol.cs @@ -2,16 +2,15 @@ using System.Linq; using System.Reflection; -using IKVM.CoreLib.Symbols.Reflection.Emit; - namespace IKVM.CoreLib.Symbols.Reflection { - class ReflectionParameterSymbol : ReflectionSymbol, IParameterSymbol + class ReflectionParameterSymbol : ReflectionSymbol, IReflectionParameterSymbol { - readonly ReflectionMethodBaseSymbol _containingMethod; - ParameterInfo _parameter; + readonly IReflectionModuleSymbol _resolvingModule; + readonly IReflectionMethodBaseSymbol _resolvingMethod; + readonly ParameterInfo _parameter; CustomAttribute[]? _customAttributes; @@ -19,60 +18,71 @@ class ReflectionParameterSymbol : ReflectionSymbol, IParameterSymbol /// Initializes a new instance. /// /// - /// + /// + /// /// - public ReflectionParameterSymbol(ReflectionSymbolContext context, ReflectionMethodBaseSymbol containingMethod, ParameterInfo parameter) : + public ReflectionParameterSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionMethodBaseSymbol resolvingMethod, ParameterInfo parameter) : base(context) { - _containingMethod = containingMethod ?? throw new ArgumentNullException(nameof(containingMethod)); + _resolvingModule = resolvingModule ?? throw new ArgumentNullException(nameof(resolvingModule)); + _resolvingMethod = resolvingMethod ?? throw new ArgumentNullException(nameof(resolvingMethod)); _parameter = parameter ?? throw new ArgumentNullException(nameof(parameter)); } - internal ReflectionMethodBaseSymbol ContainingMethod => _containingMethod; + /// + public IReflectionModuleSymbol ResolvingModule => _resolvingModule; + + /// + public IReflectionMethodBaseSymbol ResolvingMethod => _resolvingMethod; + + /// + public ParameterInfo UnderlyingParameter => _parameter; + + #region IParameterSymbol /// - public ParameterAttributes Attributes => _parameter.Attributes; + public ParameterAttributes Attributes => UnderlyingParameter.Attributes; /// - public object? DefaultValue => _parameter.DefaultValue; + public object? DefaultValue => UnderlyingParameter.DefaultValue; /// - public bool HasDefaultValue => _parameter.HasDefaultValue; + public bool HasDefaultValue => UnderlyingParameter.HasDefaultValue; /// - public bool IsIn => _parameter.IsIn; + public bool IsIn => UnderlyingParameter.IsIn; /// - public bool IsLcid => _parameter.IsLcid; + public bool IsLcid => UnderlyingParameter.IsLcid; /// - public bool IsOptional => _parameter.IsOptional; + public bool IsOptional => UnderlyingParameter.IsOptional; /// - public bool IsOut => _parameter.IsOut; + public bool IsOut => UnderlyingParameter.IsOut; /// - public bool IsRetval => _parameter.IsRetval; + public bool IsRetval => UnderlyingParameter.IsRetval; /// - public IMemberSymbol Member => ResolveMemberSymbol(_parameter.Member); + public IMemberSymbol Member => ResolveMemberSymbol(UnderlyingParameter.Member); /// - public int MetadataToken => _parameter.MetadataToken; + public int MetadataToken => UnderlyingParameter.MetadataToken; /// - public string? Name => _parameter.Name; + public string? Name => UnderlyingParameter.Name; /// - public ITypeSymbol ParameterType => ResolveTypeSymbol(_parameter.ParameterType); + public ITypeSymbol ParameterType => ResolveTypeSymbol(UnderlyingParameter.ParameterType); /// - public int Position => _parameter.Position; + public int Position => UnderlyingParameter.Position; /// public CustomAttribute[] GetCustomAttributes(bool inherit = false) { - return _customAttributes ??= ResolveCustomAttributes(_parameter.GetCustomAttributesData()); + return _customAttributes ??= ResolveCustomAttributes(UnderlyingParameter.GetCustomAttributesData()); } /// @@ -90,30 +100,22 @@ public virtual CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, /// public virtual bool IsDefined(ITypeSymbol attributeType, bool inherit = false) { - return _parameter.IsDefined(((ReflectionTypeSymbol)attributeType).ReflectionObject, inherit); + return UnderlyingParameter.IsDefined(attributeType.Unpack(), inherit); } /// public ITypeSymbol[] GetOptionalCustomModifiers() { - return ResolveTypeSymbols(_parameter.GetOptionalCustomModifiers()); + return ResolveTypeSymbols(UnderlyingParameter.GetOptionalCustomModifiers()); } /// public ITypeSymbol[] GetRequiredCustomModifiers() { - return ResolveTypeSymbols(_parameter.GetRequiredCustomModifiers()); + return ResolveTypeSymbols(UnderlyingParameter.GetRequiredCustomModifiers()); } - /// - /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. - /// - /// - internal void Complete(ParameterInfo parameter) - { - ResolveParameterSymbol(_parameter = parameter); - _customAttributes = null; - } + #endregion } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionPropertySymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionPropertySymbol.cs index 8e39abaeb..e0f003674 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionPropertySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionPropertySymbol.cs @@ -4,95 +4,94 @@ namespace IKVM.CoreLib.Symbols.Reflection { - class ReflectionPropertySymbol : ReflectionMemberSymbol, IPropertySymbol + class ReflectionPropertySymbol : ReflectionMemberSymbol, IReflectionPropertySymbol { - PropertyInfo _property; + readonly PropertyInfo _property; /// /// Initializes a new instance. /// /// + /// /// /// - public ReflectionPropertySymbol(ReflectionSymbolContext context, ReflectionTypeSymbol type, PropertyInfo property) : - base(context, type, property) + public ReflectionPropertySymbol(ReflectionSymbolContext context, IReflectionModuleSymbol module, IReflectionTypeSymbol type, PropertyInfo property) : + base(context, module, type, property) { _property = property ?? throw new ArgumentNullException(nameof(property)); } - /// - /// Gets the underlying wrapped by this symbol. - /// - internal new PropertyInfo ReflectionObject => _property; + /// + public PropertyInfo UnderlyingProperty => _property; /// - public PropertyAttributes Attributes => _property.Attributes; + public PropertyAttributes Attributes => UnderlyingProperty.Attributes; /// - public bool CanRead => _property.CanRead; + public bool CanRead => UnderlyingProperty.CanRead; /// - public bool CanWrite => _property.CanWrite; + public bool CanWrite => UnderlyingProperty.CanWrite; /// - public bool IsSpecialName => _property.IsSpecialName; + public bool IsSpecialName => UnderlyingProperty.IsSpecialName; /// - public ITypeSymbol PropertyType => ResolveTypeSymbol(_property.PropertyType); + public ITypeSymbol PropertyType => ResolveTypeSymbol(UnderlyingProperty.PropertyType); /// - public IMethodSymbol? GetMethod => _property.GetMethod is { } m ? ResolveMethodSymbol(m) : null; + public IMethodSymbol? GetMethod => ResolveMethodSymbol(UnderlyingProperty.GetMethod); /// - public IMethodSymbol? SetMethod => _property.SetMethod is { } m ? ResolveMethodSymbol(m) : null; + public IMethodSymbol? SetMethod => ResolveMethodSymbol(UnderlyingProperty.SetMethod); /// public object? GetRawConstantValue() { - return _property.GetRawConstantValue(); + return UnderlyingProperty.GetRawConstantValue(); } /// public IMethodSymbol[] GetAccessors() { - return ResolveMethodSymbols(_property.GetAccessors()); + return ResolveMethodSymbols(UnderlyingProperty.GetAccessors()); } /// public IMethodSymbol[] GetAccessors(bool nonPublic) { - return ResolveMethodSymbols(_property.GetAccessors(nonPublic)); + return ResolveMethodSymbols(UnderlyingProperty.GetAccessors(nonPublic)); } /// public IParameterSymbol[] GetIndexParameters() { - return ResolveParameterSymbols(_property.GetIndexParameters()); + return ResolveParameterSymbols(UnderlyingProperty.GetIndexParameters()); } /// public IMethodSymbol? GetGetMethod() { - return _property.GetGetMethod() is MethodInfo m ? ResolveMethodSymbol(m) : null; + return ResolveMethodSymbol(UnderlyingProperty.GetGetMethod()); } /// public IMethodSymbol? GetGetMethod(bool nonPublic) { - return _property.GetGetMethod(nonPublic) is MethodInfo m ? ResolveMethodSymbol(m) : null; + return ResolveMethodSymbol(UnderlyingProperty.GetGetMethod(nonPublic)); } /// public IMethodSymbol? GetSetMethod() { - return _property.GetSetMethod() is MethodInfo m ? ResolveMethodSymbol(m) : null; + return ResolveMethodSymbol(UnderlyingProperty.GetSetMethod()); } /// public IMethodSymbol? GetSetMethod(bool nonPublic) { - return _property.GetSetMethod(nonPublic) is MethodInfo m ? ResolveMethodSymbol(m) : null; + return ResolveMethodSymbol(UnderlyingProperty.GetSetMethod(nonPublic)); } /// @@ -104,23 +103,13 @@ public ITypeSymbol GetModifiedPropertyType() /// public ITypeSymbol[] GetOptionalCustomModifiers() { - return ResolveTypeSymbols(_property.GetOptionalCustomModifiers()); + return ResolveTypeSymbols(UnderlyingProperty.GetOptionalCustomModifiers()); } /// public ITypeSymbol[] GetRequiredCustomModifiers() { - return ResolveTypeSymbols(_property.GetRequiredCustomModifiers()); - } - - /// - /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. - /// - /// - internal void Complete(PropertyInfo property) - { - ResolvePropertySymbol(_property = property); - base.Complete(_property); + return ResolveTypeSymbols(UnderlyingProperty.GetRequiredCustomModifiers()); } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbol.cs index 5ad5fe2ab..bf9c87d3e 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbol.cs @@ -1,7 +1,11 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; +using System.Diagnostics.CodeAnalysis; using System.Reflection; +using System.Reflection.Emit; + +using IKVM.CoreLib.Symbols.Reflection.Emit; namespace IKVM.CoreLib.Symbols.Reflection { @@ -9,7 +13,7 @@ namespace IKVM.CoreLib.Symbols.Reflection /// /// Base class for managed symbols. /// - abstract class ReflectionSymbol : ISymbol + abstract class ReflectionSymbol : IReflectionSymbol { readonly ReflectionSymbolContext _context; @@ -26,301 +30,400 @@ public ReflectionSymbol(ReflectionSymbolContext context) /// /// Gets the associated . /// - protected ReflectionSymbolContext Context => _context; + public ReflectionSymbolContext Context => _context; /// - public bool IsMissing => false; + public virtual bool IsMissing => false; /// - public bool ContainsMissing => false; + public virtual bool ContainsMissing => false; - /// - /// Resolves the symbol for the specified type. - /// - /// - /// - protected virtual internal ReflectionModuleSymbol ResolveModuleSymbol(Module module) + /// + public virtual bool IsComplete => true; + + /// + [return: NotNullIfNotNull(nameof(assembly))] + public virtual IReflectionAssemblySymbol? ResolveAssemblySymbol(Assembly? assembly) + { + return assembly == null ? null : _context.GetOrCreateAssemblySymbol(assembly); + } + + /// + [return: NotNullIfNotNull(nameof(assembly))] + public virtual IReflectionAssemblySymbolBuilder ResolveAssemblySymbol(AssemblyBuilder assembly) + { + if (assembly is null) + throw new ArgumentNullException(nameof(assembly)); + + return _context.GetOrCreateAssemblySymbol(assembly); + } + + /// + [return: NotNullIfNotNull(nameof(assemblies))] + public virtual IReflectionAssemblySymbol[]? ResolveAssemblySymbols(Assembly[]? assemblies) + { + if (assemblies == null) + return null; + if (assemblies.Length == 0) + return []; + + var a = new IReflectionAssemblySymbol[assemblies.Length]; + for (int i = 0; i < assemblies.Length; i++) + if (ResolveAssemblySymbol(assemblies[i]) is { } symbol) + a[i] = symbol; + + return a; + } + + /// + [return: NotNullIfNotNull(nameof(module))] + public virtual IReflectionModuleSymbol? ResolveModuleSymbol(Module? module) + { + return module == null ? null : _context.GetOrCreateModuleSymbol(module); + } + + /// + [return: NotNullIfNotNull(nameof(module))] + public virtual IReflectionModuleSymbolBuilder ResolveModuleSymbol(ModuleBuilder module) { + if (module is null) + throw new ArgumentNullException(nameof(module)); + return _context.GetOrCreateModuleSymbol(module); } - /// - /// Resolves the symbols for the specified modules. - /// - /// - /// - protected internal ReflectionModuleSymbol[] ResolveModuleSymbols(Module[] modules) + /// + [return: NotNullIfNotNull(nameof(modules))] + public virtual IReflectionModuleSymbol[]? ResolveModuleSymbols(Module[]? modules) { - var a = new ReflectionModuleSymbol[modules.Length]; + if (modules == null) + return null; + if (modules.Length == 0) + return []; + + var a = new IReflectionModuleSymbol[modules.Length]; for (int i = 0; i < modules.Length; i++) - a[i] = ResolveModuleSymbol(modules[i]); + if (ResolveModuleSymbol(modules[i]) is { } symbol) + a[i] = symbol; return a; } - /// - /// Resolves the symbols for the specified modules. - /// - /// - /// - protected internal IEnumerable ResolveModuleSymbols(IEnumerable modules) + /// + public virtual IEnumerable ResolveModuleSymbols(IEnumerable modules) { foreach (var module in modules) - yield return ResolveModuleSymbol(module); + if (ResolveModuleSymbol(module) is { } symbol) + yield return symbol; } - /// - /// Resolves the symbol for the specified type. - /// - /// - /// - protected virtual ReflectionMemberSymbol ResolveMemberSymbol(MemberInfo member) + /// + [return: NotNullIfNotNull(nameof(member))] + public virtual IReflectionMemberSymbol? ResolveMemberSymbol(MemberInfo? member) { - return member.MemberType switch + if (member == null) + return null; + + return member switch { - MemberTypes.Constructor => ResolveConstructorSymbol((ConstructorInfo)member), - MemberTypes.Event => ResolveEventSymbol((EventInfo)member), - MemberTypes.Field => ResolveFieldSymbol((FieldInfo)member), - MemberTypes.Method => ResolveMethodSymbol((MethodInfo)member), - MemberTypes.Property => ResolvePropertySymbol((PropertyInfo)member), - MemberTypes.TypeInfo => ResolveTypeSymbol((Type)member), - MemberTypes.NestedType => ResolveTypeSymbol((Type)member), - MemberTypes.Custom => throw new NotImplementedException(), - MemberTypes.All => throw new NotImplementedException(), + ConstructorInfo ctor => ResolveConstructorSymbol(ctor), + EventInfo @event => ResolveEventSymbol(@event), + FieldInfo field => ResolveFieldSymbol(field), + MethodInfo method => ResolveMethodSymbol(method), + PropertyInfo property => ResolvePropertySymbol(property), + Type type => ResolveTypeSymbol(type), _ => throw new InvalidOperationException(), }; } - /// - /// Resolves the symbols for the specified types. - /// - /// - /// - protected internal ReflectionMemberSymbol[] ResolveMemberSymbols(MemberInfo[] types) + /// + [return: NotNullIfNotNull(nameof(members))] + public virtual IReflectionMemberSymbol[]? ResolveMemberSymbols(MemberInfo[]? members) { - var a = new ReflectionMemberSymbol[types.Length]; - for (int i = 0; i < types.Length; i++) - a[i] = ResolveMemberSymbol(types[i]); + if (members == null) + return null; + if (members.Length == 0) + return []; + + var a = new IReflectionMemberSymbol[members.Length]; + for (int i = 0; i < members.Length; i++) + if (ResolveMemberSymbol(members[i]) is { } symbol) + a[i] = symbol; return a; } - /// - /// Resolves the symbol for the specified type. - /// - /// - /// - protected virtual internal ReflectionTypeSymbol ResolveTypeSymbol(Type type) + /// + [return: NotNullIfNotNull(nameof(type))] + public virtual IReflectionTypeSymbol? ResolveTypeSymbol(Type? type) + { + return type == null ? null : _context.GetOrCreateTypeSymbol(type); + } + + /// + [return: NotNullIfNotNull(nameof(type))] + public virtual IReflectionTypeSymbolBuilder ResolveTypeSymbol(TypeBuilder type) { + if (type is null) + throw new ArgumentNullException(nameof(type)); + return _context.GetOrCreateTypeSymbol(type); } - /// - /// Resolves the symbols for the specified types. - /// - /// - /// - protected internal ReflectionTypeSymbol[] ResolveTypeSymbols(Type[] types) + /// + [return: NotNullIfNotNull(nameof(types))] + public virtual IReflectionTypeSymbol[]? ResolveTypeSymbols(Type[]? types) { - var a = new ReflectionTypeSymbol[types.Length]; + if (types == null) + return null; + if (types.Length == 0) + return []; + + var a = new IReflectionTypeSymbol[types.Length]; for (int i = 0; i < types.Length; i++) - a[i] = ResolveTypeSymbol(types[i]); + if (ResolveTypeSymbol(types[i]) is { } symbol) + a[i] = symbol; return a; } - /// - /// Resolves the symbols for the specified types. - /// - /// - /// - protected internal IEnumerable ResolveTypeSymbols(IEnumerable types) + /// + public virtual IEnumerable ResolveTypeSymbols(IEnumerable types) { foreach (var type in types) - yield return ResolveTypeSymbol(type); + if (ResolveTypeSymbol(type) is { } symbol) + yield return symbol; } - /// - /// Resolves the symbol for the specified method. - /// - /// - /// - protected virtual internal ReflectionMethodBaseSymbol ResolveMethodBaseSymbol(MethodBase method) + /// + [return: NotNullIfNotNull(nameof(method))] + public virtual IReflectionMethodBaseSymbol? ResolveMethodBaseSymbol(MethodBase? method) { - if (method.IsConstructor) - return ResolveConstructorSymbol((ConstructorInfo)method); - else - return ResolveMethodSymbol((MethodInfo)method); + return method switch + { + ConstructorInfo ctor => ResolveConstructorSymbol(ctor), + MethodInfo method_ => ResolveMethodSymbol(method_), + _ => null, + }; } - /// - /// Resolves the symbol for the specified constructor. - /// - /// - /// - protected virtual internal ReflectionConstructorSymbol ResolveConstructorSymbol(ConstructorInfo ctor) + /// + [return: NotNullIfNotNull(nameof(ctor))] + public virtual IReflectionConstructorSymbol? ResolveConstructorSymbol(ConstructorInfo? ctor) { + return ctor == null ? null : _context.GetOrCreateConstructorSymbol(ctor); + } + + /// + [return: NotNullIfNotNull(nameof(ctor))] + public virtual IReflectionConstructorSymbolBuilder ResolveConstructorSymbol(ConstructorBuilder ctor) + { + if (ctor is null) + throw new ArgumentNullException(nameof(ctor)); + return _context.GetOrCreateConstructorSymbol(ctor); } - /// - /// Resolves the symbols for the specified constructors. - /// - /// - /// - protected internal ReflectionConstructorSymbol[] ResolveConstructorSymbols(ConstructorInfo[] ctors) + /// + [return: NotNullIfNotNull(nameof(ctors))] + public virtual IReflectionConstructorSymbol[]? ResolveConstructorSymbols(ConstructorInfo[]? ctors) { - var a = new ReflectionConstructorSymbol[ctors.Length]; + if (ctors == null) + return null; + if (ctors.Length == 0) + return []; + + var a = new IReflectionConstructorSymbol[ctors.Length]; for (int i = 0; i < ctors.Length; i++) - a[i] = ResolveConstructorSymbol(ctors[i]); + if (ResolveConstructorSymbol(ctors[i]) is { } symbol) + a[i] = symbol; return a; } - /// - /// Resolves the symbol for the specified method. - /// - /// - /// - protected virtual internal ReflectionMethodSymbol ResolveMethodSymbol(MethodInfo method) + /// + [return: NotNullIfNotNull(nameof(method))] + public virtual IReflectionMethodSymbol? ResolveMethodSymbol(MethodInfo? method) { + return method == null ? null : _context.GetOrCreateMethodSymbol(method); + } + + /// + [return: NotNullIfNotNull(nameof(method))] + public virtual IReflectionMethodSymbolBuilder ResolveMethodSymbol(MethodBuilder method) + { + if (method is null) + throw new ArgumentNullException(nameof(method)); + return _context.GetOrCreateMethodSymbol(method); } - /// - /// Resolves the symbols for the specified methods. - /// - /// - /// - protected internal ReflectionMethodSymbol[] ResolveMethodSymbols(MethodInfo[] methods) + /// + [return: NotNullIfNotNull(nameof(methods))] + public virtual IReflectionMethodSymbol[]? ResolveMethodSymbols(MethodInfo[]? methods) { - var a = new ReflectionMethodSymbol[methods.Length]; + if (methods == null) + return null; + if (methods.Length == 0) + return []; + + var a = new IReflectionMethodSymbol[methods.Length]; for (int i = 0; i < methods.Length; i++) - a[i] = ResolveMethodSymbol(methods[i]); + if (ResolveMethodSymbol(methods[i]) is { } symbol) + a[i] = symbol; return a; } - /// - /// Resolves the symbol for the specified field. - /// - /// - /// - protected virtual internal ReflectionFieldSymbol ResolveFieldSymbol(FieldInfo field) + /// + [return: NotNullIfNotNull(nameof(field))] + public virtual IReflectionFieldSymbol? ResolveFieldSymbol(FieldInfo? field) { + return field == null ? null : _context.GetOrCreateFieldSymbol(field); + } + + /// + [return: NotNullIfNotNull(nameof(field))] + public virtual IReflectionFieldSymbolBuilder ResolveFieldSymbol(FieldBuilder field) + { + if (field is null) + throw new ArgumentNullException(nameof(field)); + return _context.GetOrCreateFieldSymbol(field); } - /// - /// Resolves the symbols for the specified fields. - /// - /// - /// - protected internal ReflectionFieldSymbol[] ResolveFieldSymbols(FieldInfo[] fields) + /// + [return: NotNullIfNotNull(nameof(fields))] + public virtual IReflectionFieldSymbol[]? ResolveFieldSymbols(FieldInfo[]? fields) { - var a = new ReflectionFieldSymbol[fields.Length]; + if (fields == null) + return null; + if (fields.Length == 0) + return []; + + var a = new IReflectionFieldSymbol[fields.Length]; for (int i = 0; i < fields.Length; i++) - a[i] = ResolveFieldSymbol(fields[i]); + if (ResolveFieldSymbol(fields[i]) is { } symbol) + a[i] = symbol; return a; } - /// - /// Resolves the symbol for the specified field. - /// - /// - /// - protected virtual internal ReflectionPropertySymbol ResolvePropertySymbol(PropertyInfo property) + /// + [return: NotNullIfNotNull(nameof(property))] + public virtual IReflectionPropertySymbol? ResolvePropertySymbol(PropertyInfo? property) { + return property == null ? null : _context.GetOrCreatePropertySymbol(property); + } + + /// + [return: NotNullIfNotNull(nameof(property))] + public virtual IReflectionPropertySymbolBuilder ResolvePropertySymbol(PropertyBuilder property) + { + if (property is null) + throw new ArgumentNullException(nameof(property)); + return _context.GetOrCreatePropertySymbol(property); } - /// - /// Resolves the symbols for the specified properties. - /// - /// - /// - protected internal ReflectionPropertySymbol[] ResolvePropertySymbols(PropertyInfo[] properties) + /// + [return: NotNullIfNotNull(nameof(properties))] + public virtual IReflectionPropertySymbol[]? ResolvePropertySymbols(PropertyInfo[]? properties) { - var a = new ReflectionPropertySymbol[properties.Length]; + if (properties == null) + return null; + if (properties.Length == 0) + return []; + + var a = new IReflectionPropertySymbol[properties.Length]; for (int i = 0; i < properties.Length; i++) - a[i] = ResolvePropertySymbol(properties[i]); + if (ResolvePropertySymbol(properties[i]) is { } symbol) + a[i] = symbol; return a; } - /// - /// Resolves the symbol for the specified event. - /// - /// - /// - protected virtual internal ReflectionEventSymbol ResolveEventSymbol(EventInfo @event) + /// + [return: NotNullIfNotNull(nameof(@event))] + public virtual IReflectionEventSymbol? ResolveEventSymbol(EventInfo? @event) + { + return @event == null ? null : _context.GetOrCreateEventSymbol(@event); + } + + /// + [return: NotNullIfNotNull(nameof(@event))] + public virtual IReflectionEventSymbolBuilder ResolveEventSymbol(EventBuilder @event) { + if (@event is null) + throw new ArgumentNullException(nameof(@event)); + return _context.GetOrCreateEventSymbol(@event); } - /// - /// Resolves the symbols for the specified events. - /// - /// - /// - protected internal ReflectionEventSymbol[] ResolveEventSymbols(EventInfo[] events) + /// + [return: NotNullIfNotNull(nameof(events))] + public virtual IReflectionEventSymbol[]? ResolveEventSymbols(EventInfo[]? events) { - var a = new ReflectionEventSymbol[events.Length]; + if (@events == null) + return null; + if (@events.Length == 0) + return []; + + var a = new IReflectionEventSymbol[events.Length]; for (int i = 0; i < events.Length; i++) - a[i] = ResolveEventSymbol(events[i]); + if (ResolveEventSymbol(events[i]) is { } symbol) + a[i] = symbol; return a; } - /// - /// Resolves the symbol for the specified parameter. - /// - /// - /// - protected virtual internal ReflectionParameterSymbol ResolveParameterSymbol(ParameterInfo parameter) + /// + [return: NotNullIfNotNull(nameof(parameter))] + public virtual IReflectionParameterSymbol? ResolveParameterSymbol(ParameterInfo? parameter) { - return _context.GetOrCreateParameterSymbol(parameter); + return parameter == null ? null : _context.GetOrCreateParameterSymbol(parameter); } - /// - /// Resolves the symbols for the specified parameters. - /// - /// - /// - protected internal ReflectionParameterSymbol[] ResolveParameterSymbols(ParameterInfo[] parameters) + /// + [return: NotNullIfNotNull(nameof(parameter))] + public virtual IReflectionParameterSymbolBuilder ResolveParameterSymbol(ParameterBuilder parameter) { - var a = new ReflectionParameterSymbol[parameters.Length]; - for (int i = 0; i < parameters.Length; i++) - a[i] = ResolveParameterSymbol(parameters[i]); + if (parameter is null) + throw new ArgumentNullException(nameof(parameter)); - return a; + return _context.GetOrCreateParameterSymbol(parameter); } - /// - /// Resolves the symbols for the specified parameters. - /// - /// - /// - protected internal ReflectionParameterSymbol[] ResolveGenericParameterSymbols(ParameterInfo[] parameters) + /// + [return: NotNullIfNotNull(nameof(parameters))] + public virtual IReflectionParameterSymbol[]? ResolveParameterSymbols(ParameterInfo[]? parameters) { - var a = new ReflectionParameterSymbol[parameters.Length]; + if (parameters == null) + return null; + if (parameters.Length == 0) + return []; + + var a = new IReflectionParameterSymbol[parameters.Length]; for (int i = 0; i < parameters.Length; i++) - a[i] = ResolveParameterSymbol(parameters[i]); + if (ResolveParameterSymbol(parameters[i]) is { } symbol) + a[i] = symbol; return a; } - /// - /// Transforms a custom set of custom attribute data records to a symbol record. - /// - /// - /// - protected internal CustomAttribute[] ResolveCustomAttributes(IList attributes) + /// + [return: NotNullIfNotNull(nameof(attributes))] + public virtual CustomAttribute[]? ResolveCustomAttributes(IList? attributes) { + if (attributes == null) + return null; + if (attributes.Count == 0) + return []; + var a = new CustomAttribute[attributes.Count]; for (int i = 0; i < attributes.Count; i++) - a[i] = ResolveCustomAttribute(attributes[i]); + if (ResolveCustomAttribute(attributes[i]) is { } v) + a[i] = v; return a; } @@ -330,11 +433,15 @@ protected internal CustomAttribute[] ResolveCustomAttributes(IList /// /// - protected internal CustomAttribute[] ResolveCustomAttributes(IEnumerable attributes) + public virtual IEnumerable ResolveCustomAttributes(IEnumerable attributes) { + if (attributes is null) + throw new ArgumentNullException(nameof(attributes)); + var a = new List(); foreach (var i in attributes) - a.Add(ResolveCustomAttribute(i)); + if (ResolveCustomAttribute(i) is { } v) + a.Add(v); return a.ToArray(); } @@ -344,12 +451,15 @@ protected internal CustomAttribute[] ResolveCustomAttributes(IEnumerable /// /// - /// - protected internal CustomAttribute ResolveCustomAttribute(CustomAttributeData customAttributeData) + [return: NotNullIfNotNull(nameof(customAttributeData))] + public virtual CustomAttribute? ResolveCustomAttribute(CustomAttributeData? customAttributeData) { + if (customAttributeData == null) + return null; + return new CustomAttribute( - ResolveTypeSymbol(customAttributeData.AttributeType), - ResolveConstructorSymbol(customAttributeData.Constructor), + ResolveTypeSymbol(customAttributeData.AttributeType)!, + ResolveConstructorSymbol(customAttributeData.Constructor)!, ResolveCustomAttributeTypedArguments(customAttributeData.ConstructorArguments), ResolveCustomAttributeNamedArguments(customAttributeData.NamedArguments)); } @@ -359,8 +469,13 @@ protected internal CustomAttribute ResolveCustomAttribute(CustomAttributeData cu /// /// /// - ImmutableArray ResolveCustomAttributeTypedArguments(IList args) + public ImmutableArray ResolveCustomAttributeTypedArguments(IList args) { + if (args is null) + throw new ArgumentNullException(nameof(args)); + if (args.Count == 0) + return []; + var a = new CustomAttributeTypedArgument[args.Count]; for (int i = 0; i < args.Count; i++) a[i] = ResolveCustomAttributeTypedArgument(args[i]); @@ -373,9 +488,11 @@ ImmutableArray ResolveCustomAttributeTypedArgument /// /// /// - CustomAttributeTypedArgument ResolveCustomAttributeTypedArgument(System.Reflection.CustomAttributeTypedArgument arg) + public CustomAttributeTypedArgument ResolveCustomAttributeTypedArgument(System.Reflection.CustomAttributeTypedArgument arg) { - return new CustomAttributeTypedArgument(ResolveTypeSymbol(arg.ArgumentType), ResolveCustomAttributeTypedValue(arg.Value)); + return new CustomAttributeTypedArgument( + ResolveTypeSymbol(arg.ArgumentType)!, + ResolveCustomAttributeTypedValue(arg.Value)); } /// @@ -383,12 +500,13 @@ CustomAttributeTypedArgument ResolveCustomAttributeTypedArgument(System.Reflecti /// /// /// - object? ResolveCustomAttributeTypedValue(object? value) + public object? ResolveCustomAttributeTypedValue(object? value) { - if (value is System.Type v) - return ResolveTypeSymbol(v); - - return value; + return value switch + { + Type v => ResolveTypeSymbol(v), + _ => value + }; } /// @@ -396,8 +514,13 @@ CustomAttributeTypedArgument ResolveCustomAttributeTypedArgument(System.Reflecti /// /// /// - ImmutableArray ResolveCustomAttributeNamedArguments(IList args) + public ImmutableArray ResolveCustomAttributeNamedArguments(IList args) { + if (args is null) + throw new ArgumentNullException(nameof(args)); + if (args.Count == 0) + return []; + var a = new CustomAttributeNamedArgument[args.Count]; for (int i = 0; i < args.Count; i++) a[i] = ResolveCustomAttributeNamedArgument(args[i]); @@ -410,9 +533,13 @@ ImmutableArray ResolveCustomAttributeNamedArgument /// /// /// - CustomAttributeNamedArgument ResolveCustomAttributeNamedArgument(System.Reflection.CustomAttributeNamedArgument arg) + public CustomAttributeNamedArgument ResolveCustomAttributeNamedArgument(System.Reflection.CustomAttributeNamedArgument arg) { - return new CustomAttributeNamedArgument(arg.IsField, ResolveMemberSymbol(arg.MemberInfo), arg.MemberName, ResolveCustomAttributeTypedArgument(arg.TypedValue)); + return new CustomAttributeNamedArgument( + arg.IsField, + ResolveMemberSymbol(arg.MemberInfo)!, + arg.MemberName, + ResolveCustomAttributeTypedArgument(arg.TypedValue)); } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs index f4e809e2f..cbd65e7c9 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs @@ -5,6 +5,7 @@ using System.Runtime.CompilerServices; using IKVM.CoreLib.Reflection; +using IKVM.CoreLib.Symbols.Emit; using IKVM.CoreLib.Symbols.Reflection.Emit; namespace IKVM.CoreLib.Symbols.Reflection @@ -13,11 +14,11 @@ namespace IKVM.CoreLib.Symbols.Reflection /// /// Holds references to symbols derived from System.Reflection. /// - class ReflectionSymbolContext + class ReflectionSymbolContext : ISymbolContext { - readonly ConcurrentDictionary> _symbolByName = new(AssemblyNameEqualityComparer.Instance); - readonly ConditionalWeakTable _symbolByAssembly = new(); + readonly ConcurrentDictionary> _symbolByName = new(AssemblyNameEqualityComparer.Instance); + readonly ConditionalWeakTable _symbolByAssembly = new(); /// /// Initializes a new instance. @@ -28,150 +29,267 @@ public ReflectionSymbolContext() } /// - /// Gets or creates a indexed based on the assembly's name. + /// Gets or creates a indexed based on the assembly's name. /// /// /// - ReflectionAssemblySymbol GetOrCreateAssemblySymbolByName(Assembly assembly) + IReflectionAssemblySymbol GetOrCreateAssemblySymbolByName(Assembly assembly) { - var r = _symbolByName.GetOrAdd(assembly.GetName(), _ => new WeakReference(new ReflectionAssemblySymbol(this, assembly))); + var r = _symbolByName.GetOrAdd(assembly.GetName(), _ => new(null)); - // reference has valid symbol - if (r.TryGetTarget(out var s)) - return s; - - // no valid symbol, must have been released, lock to restore lock (r) { - // still gone, recreate - if (r.TryGetTarget(out s) == false) - r.SetTarget(s = new ReflectionAssemblySymbol(this, assembly)); + // reference has no target, reset + if (r.TryGetTarget(out var s) == false) + { + if (assembly is AssemblyBuilder builder) + { + // we were passed in a builder, so generate a symbol builder and set it as the builder and symbol. + var a = builder.GetRuntimeAssembly(); + r.SetTarget(s = new ReflectionAssemblySymbolBuilder(this, builder)); + } + else + { + // we were passed a non builder, so generate a symbol and set it to the symbol + // TODO the weakness here is if we pass it the RuntimeAssembly from a non-associated builder + r.SetTarget(s = new ReflectionAssemblySymbol(this, assembly)); + } + } - return s; + return s ?? throw new InvalidOperationException(); } } /// - /// Gets or creates a for the specified . + /// Gets or creates a indexed based on the assembly's name. + /// + /// + /// + IReflectionAssemblySymbolBuilder GetOrCreateAssemblySymbolByName(AssemblyBuilder assembly) + { + return (IReflectionAssemblySymbolBuilder)GetOrCreateAssemblySymbolByName((Assembly)assembly); + } + + /// + /// Gets or creates a for the specified . /// /// /// - public ReflectionAssemblySymbol GetOrCreateAssemblySymbol(Assembly assembly) + public IReflectionAssemblySymbol GetOrCreateAssemblySymbol(Assembly assembly) { return _symbolByAssembly.GetValue(assembly, GetOrCreateAssemblySymbolByName); } /// - /// Gets or creates a for the specified . + /// Gets or creates a for the specified . + /// + /// + /// + public IReflectionAssemblySymbolBuilder GetOrCreateAssemblySymbol(AssemblyBuilder assembly) + { + return (IReflectionAssemblySymbolBuilder)_symbolByAssembly.GetValue(assembly, GetOrCreateAssemblySymbolByName); + } + + /// + /// Gets or creates a for the specified . + /// + /// + /// + public IReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) + { + if (module is ModuleBuilder builder) + return GetOrCreateModuleSymbol(builder); + else + return GetOrCreateAssemblySymbol(module.Assembly).GetOrCreateModuleSymbol(module); + } + + /// + /// Gets or creates a for the specified . /// /// /// - public ReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) + public IReflectionModuleSymbolBuilder GetOrCreateModuleSymbol(ModuleBuilder module) { return GetOrCreateAssemblySymbol(module.Assembly).GetOrCreateModuleSymbol(module); } /// - /// Gets or creates a for the specified . + /// Gets or creates a for the specified . /// /// /// - public ReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) + public IReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) + { + if (type is TypeBuilder builder) + return GetOrCreateTypeSymbol(builder); + else + return GetOrCreateModuleSymbol(type.Module).GetOrCreateTypeSymbol(type); + } + + /// + /// Gets or creates a for the specified . + /// + /// + /// + public IReflectionTypeSymbolBuilder GetOrCreateTypeSymbol(TypeBuilder type) { return GetOrCreateModuleSymbol(type.Module).GetOrCreateTypeSymbol(type); } /// - /// Gets or creates a for the specified . + /// Gets or creates a for the specified . /// - /// + /// /// - public ReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method) + public IReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) { - if (method is ConstructorInfo ctor) - return GetOrCreateConstructorSymbol(ctor); + if (ctor is ConstructorBuilder builder) + return GetOrCreateConstructorSymbol(builder); else - return GetOrCreateMethodSymbol((MethodInfo)method); + return GetOrCreateModuleSymbol(ctor.Module).GetOrCreateConstructorSymbol(ctor); } /// - /// Gets or creates a for the specified . + /// Gets or creates a for the specified . /// /// /// - public ReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) + public IReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor) { return GetOrCreateModuleSymbol(ctor.Module).GetOrCreateConstructorSymbol(ctor); } /// - /// Gets or creates a for the specified . + /// Gets or creates a for the specified . /// /// /// - public ReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) + public IReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) + { + if (method is MethodBuilder builder) + return GetOrCreateMethodSymbol(builder); + else + return GetOrCreateModuleSymbol(method.Module).GetOrCreateMethodSymbol(method); + } + + /// + /// Gets or creates a for the specified . + /// + /// + /// + public IReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method) { return GetOrCreateModuleSymbol(method.Module).GetOrCreateMethodSymbol(method); } /// - /// Gets or creates a for the specified . + /// Gets or creates a for the specified . /// /// /// - public ReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) + public IReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) { return GetOrCreateModuleSymbol(parameter.Member.Module).GetOrCreateParameterSymbol(parameter); } /// - /// Gets or creates a for the specified . + /// Gets or creates a for the specified . + /// + /// + /// + public IReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter) + { + return GetOrCreateModuleSymbol(parameter.GetModuleBuilder()).GetOrCreateParameterSymbol(parameter); + } + + /// + /// Gets or creates a for the specified . /// /// /// - public ReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) + public IReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) + { + if (field is FieldBuilder builder) + return GetOrCreateFieldSymbol(builder); + else + return GetOrCreateModuleSymbol(field.Module).GetOrCreateFieldSymbol(field); + } + + /// + /// Gets or creates a for the specified . + /// + /// + /// + public IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field) { return GetOrCreateModuleSymbol(field.Module).GetOrCreateFieldSymbol(field); } /// - /// Gets or creates a for the specified . + /// Gets or creates a for the specified . /// /// /// - public ReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) + public IReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) { - return GetOrCreateModuleSymbol(property.Module).GetOrCreatePropertySymbol(property); + if (property is PropertyBuilder builder) + return GetOrCreatePropertySymbol(builder); + else + return GetOrCreateModuleSymbol(property.Module).GetOrCreatePropertySymbol(property); } /// - /// Gets or creates a for the specified . + /// Gets or creates a for the specified . /// - /// + /// /// - public ReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) + public IReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property) { - return GetOrCreateModuleSymbol(@event.Module).GetOrCreateEventSymbol(@event); + return GetOrCreateModuleSymbol(property.Module).GetOrCreatePropertySymbol(property); } /// - /// Gets or creates a for the specified . + /// Gets or creates a for the specified . /// /// /// - public ReflectionEventSymbol GetOrCreateEventSymbol(EventBuilder @event) + public IReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) { - return GetOrCreateEventSymbol(new ReflectionEventBuilderInfo(@event)); + return GetOrCreateModuleSymbol(@event.Module).GetOrCreateEventSymbol(@event); } /// - /// Gets or creates a for the specified . + /// Gets or creates a for the specified . /// /// /// - public ReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterBuilder parameter) + public IReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event) + { + return GetOrCreateModuleSymbol(@event.GetModuleBuilder()).GetOrCreateEventSymbol(@event); + } + + /// + public ICustomAttributeBuilder CreateCustomAttribute(IConstructorSymbol con, object?[] constructorArgs) + { + return new ReflectionCustomAttributeBuilder(new CustomAttributeBuilder(con.Unpack(), constructorArgs)); + } + + /// + public ICustomAttributeBuilder CreateCustomAttribute(IConstructorSymbol con, object?[] constructorArgs, IFieldSymbol[] namedFields, object?[] fieldValues) + { + return new ReflectionCustomAttributeBuilder(new CustomAttributeBuilder(con.Unpack(), constructorArgs, namedFields.Unpack(), fieldValues)); + } + + /// + public ICustomAttributeBuilder CreateCustomAttribute(IConstructorSymbol con, object?[] constructorArgs, IPropertySymbol[] namedProperties, object?[] propertyValues) + { + return new ReflectionCustomAttributeBuilder(new CustomAttributeBuilder(con.Unpack(), constructorArgs, namedProperties.Unpack(), propertyValues)); + } + + /// + public ICustomAttributeBuilder CreateCustomAttribute(IConstructorSymbol con, object?[] constructorArgs, IPropertySymbol[] namedProperties, object?[] propertyValues, IFieldSymbol[] namedFields, object?[] fieldValues) { - return GetOrCreateParameterSymbol(new ReflectionParameterBuilderInfo(parameter)); + return new ReflectionCustomAttributeBuilder(new CustomAttributeBuilder(con.Unpack(), constructorArgs, namedProperties.Unpack(), propertyValues, namedFields.Unpack(), fieldValues)); } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolExtensions.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolExtensions.cs new file mode 100644 index 000000000..55b1fd5ef --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolExtensions.cs @@ -0,0 +1,11 @@ +namespace IKVM.CoreLib.Symbols.Reflection +{ + + static class ReflectionSymbolExtensions + { + + + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeImpl.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeImpl.cs new file mode 100644 index 000000000..e08a8a2c9 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeImpl.cs @@ -0,0 +1,633 @@ +using System; +using System.Collections.Concurrent; +using System.Reflection; +using System.Threading; + +namespace IKVM.CoreLib.Symbols.Reflection +{ + + /// + /// Provides common operations against a . + /// + struct ReflectionTypeImpl + { + + readonly IReflectionTypeSymbol _symbol; + + ReflectionTypeSymbol?[]? _asArray; + ReflectionTypeSymbol? _asSZArray; + ReflectionTypeSymbol? _asPointer; + ReflectionTypeSymbol? _asByRef; + ConcurrentDictionary? _genericTypeSymbols; + + /// + /// Initializes a new instance. + /// + /// + /// + public ReflectionTypeImpl(IReflectionTypeSymbol symbol) + { + _symbol = symbol ?? throw new ArgumentNullException(nameof(symbol)); + } + + /// + /// Gets or creates the cached for the generic parameter type. + /// + /// + /// + public IReflectionTypeSymbol GetOrCreateGenericTypeSymbol(ITypeSymbol[] genericTypeArguments) + { + if (genericTypeArguments is null) + throw new ArgumentNullException(nameof(genericTypeArguments)); + + if (_symbol.UnderlyingType.IsGenericTypeDefinition == false) + throw new InvalidOperationException(); + + if (_genericTypeSymbols == null) + Interlocked.CompareExchange(ref _genericTypeSymbols, new ConcurrentDictionary(TypeSymbolListEqualityComparer.Instance), null); + + var __symbol = _symbol; + return _genericTypeSymbols.GetOrAdd(genericTypeArguments, _ => new ReflectionTypeSymbol(__symbol.Context, __symbol.ResolvingModule, __symbol.UnderlyingType.MakeGenericType(genericTypeArguments.Unpack()))); + } + + /// + public readonly IAssemblySymbol Assembly => _symbol.ResolveAssemblySymbol(_symbol.UnderlyingType.Assembly); + + /// + public readonly string? AssemblyQualifiedName => _symbol.UnderlyingType.AssemblyQualifiedName; + + /// + public readonly TypeAttributes Attributes => _symbol.UnderlyingType.Attributes; + + /// + public readonly ITypeSymbol? BaseType => _symbol.ResolveTypeSymbol(_symbol.UnderlyingType.BaseType); + + /// + public readonly bool ContainsGenericParameters => _symbol.UnderlyingType.ContainsGenericParameters; + + /// + public readonly IMethodBaseSymbol? DeclaringMethod => _symbol.ResolveMethodBaseSymbol(_symbol.UnderlyingType.DeclaringMethod); + + /// + public readonly string? FullName => _symbol.UnderlyingType.FullName; + + /// + public readonly string? Namespace => _symbol.UnderlyingType.Namespace; + + /// + public readonly GenericParameterAttributes GenericParameterAttributes => _symbol.UnderlyingType.GenericParameterAttributes; + + /// + public readonly int GenericParameterPosition => _symbol.UnderlyingType.GenericParameterPosition; + + /// + public readonly ITypeSymbol[] GenericTypeArguments => _symbol.ResolveTypeSymbols(_symbol.UnderlyingType.GenericTypeArguments); + + /// + public readonly bool HasElementType => _symbol.UnderlyingType.HasElementType; + + /// + public readonly TypeCode TypeCode => Type.GetTypeCode(_symbol.UnderlyingType); + + /// + public readonly bool IsAbstract => _symbol.UnderlyingType.IsAbstract; + +#if NETFRAMEWORK + + /// + /// + /// There's no API to distinguish an array of rank 1 from a vector, + /// so we check if the type name ends in [], which indicates it's a vector + /// (non-vectors will have [*] or [,]). + /// + public readonly bool IsSZArray => _symbol.UnderlyingType.IsArray && _symbol.UnderlyingType.Name.EndsWith("[]"); + +#else + + /// + public readonly bool IsSZArray => _symbol.UnderlyingType.IsSZArray; + +#endif + + /// + public readonly bool IsArray => _symbol.UnderlyingType.IsArray; + + /// + public readonly bool IsAutoLayout => _symbol.UnderlyingType.IsAutoLayout; + + /// + public readonly bool IsExplicitLayout => _symbol.UnderlyingType.IsExplicitLayout; + + /// + public readonly bool IsByRef => _symbol.UnderlyingType.IsByRef; + + /// + public readonly bool IsClass => _symbol.UnderlyingType.IsClass; + + /// + public readonly bool IsEnum => _symbol.UnderlyingType.IsEnum; + + /// + public readonly bool IsInterface => _symbol.UnderlyingType.IsInterface; + + /// + public readonly bool IsConstructedGenericType => _symbol.UnderlyingType.IsConstructedGenericType; + + /// + public readonly bool IsGenericParameter => _symbol.UnderlyingType.IsGenericParameter; + + /// + public readonly bool IsGenericType => _symbol.UnderlyingType.IsGenericType; + + /// + public readonly bool IsGenericTypeDefinition => _symbol.UnderlyingType.IsGenericTypeDefinition; + + /// + public readonly bool IsLayoutSequential => _symbol.UnderlyingType.IsLayoutSequential; + + /// + public readonly bool IsNested => _symbol.UnderlyingType.IsNested; + + /// + public readonly bool IsNestedAssembly => _symbol.UnderlyingType.IsNestedAssembly; + + /// + public readonly bool IsNestedFamANDAssem => _symbol.UnderlyingType.IsNestedFamANDAssem; + + /// + public readonly bool IsNestedFamORAssem => _symbol.UnderlyingType.IsNestedFamORAssem; + + /// + public readonly bool IsNestedFamily => _symbol.UnderlyingType.IsNestedFamily; + + /// + public readonly bool IsNestedPrivate => _symbol.UnderlyingType.IsNestedPrivate; + + /// + public readonly bool IsNestedPublic => _symbol.UnderlyingType.IsNestedPublic; + + /// + public readonly bool IsNotPublic => _symbol.UnderlyingType.IsNotPublic; + + /// + public readonly bool IsPointer => _symbol.UnderlyingType.IsPointer; + +#if NET8_0_OR_GREATER + + /// + public readonly bool IsFunctionPointer => _symbol.UnderlyingType.IsFunctionPointer; + + /// + public readonly bool IsUnmanagedFunctionPointer => _symbol.UnderlyingType.IsUnmanagedFunctionPointer; + +#else + + /// + public readonly bool IsFunctionPointer => throw new NotImplementedException(); + + /// + public readonly bool IsUnmanagedFunctionPointer => throw new NotImplementedException(); + +#endif + + /// + public readonly bool IsPrimitive => _symbol.UnderlyingType.IsPrimitive; + + /// + public readonly bool IsPublic => _symbol.UnderlyingType.IsPublic; + + /// + public readonly bool IsSealed => _symbol.UnderlyingType.IsSealed; + +#pragma warning disable SYSLIB0050 // Type or member is obsolete + /// + public readonly bool IsSerializable => _symbol.UnderlyingType.IsSerializable; +#pragma warning restore SYSLIB0050 // Type or member is obsolete + + /// + public readonly bool IsValueType => _symbol.UnderlyingType.IsValueType; + + /// + public readonly bool IsVisible => _symbol.UnderlyingType.IsVisible; + +#if NET6_0_OR_GREATER + + /// + public readonly bool IsSignatureType => _symbol.UnderlyingType.IsSignatureType; + +#else + + /// + public readonly bool IsSignatureType => throw new NotImplementedException(); + +#endif + + /// + public readonly bool IsSpecialName => _symbol.UnderlyingType.IsSpecialName; + + /// + public readonly IConstructorSymbol? TypeInitializer => _symbol.ResolveConstructorSymbol(_symbol.UnderlyingType.TypeInitializer); + + /// + public readonly int GetArrayRank() + { + return _symbol.UnderlyingType.GetArrayRank(); + } + + /// + public readonly IConstructorSymbol? GetConstructor(BindingFlags bindingAttr, ITypeSymbol[] types) + { + return _symbol.ResolveConstructorSymbol(_symbol.UnderlyingType.GetConstructor(bindingAttr, binder: null, types.Unpack(), modifiers: null)); + } + + /// + public readonly IConstructorSymbol? GetConstructor(ITypeSymbol[] types) + { + return _symbol.ResolveConstructorSymbol(_symbol.UnderlyingType.GetConstructor(types.Unpack())); + } + + /// + public readonly IConstructorSymbol[] GetConstructors() + { + return _symbol.ResolveConstructorSymbols(_symbol.UnderlyingType.GetConstructors()); + } + + /// + public readonly IConstructorSymbol[] GetConstructors(BindingFlags bindingAttr) + { + return _symbol.ResolveConstructorSymbols(_symbol.UnderlyingType.GetConstructors(bindingAttr)); + } + + /// + public readonly IMemberSymbol[] GetDefaultMembers() + { + return _symbol.ResolveMemberSymbols(_symbol.UnderlyingType.GetDefaultMembers()); + } + + /// + public readonly ITypeSymbol? GetElementType() + { + return _symbol.ResolveTypeSymbol(_symbol.UnderlyingType.GetElementType()); + } + + /// + public readonly string? GetEnumName(object value) + { + return _symbol.UnderlyingType.GetEnumName(value); + } + + /// + public readonly string[] GetEnumNames() + { + return _symbol.UnderlyingType.GetEnumNames(); + } + + /// + public readonly ITypeSymbol GetEnumUnderlyingType() + { + return _symbol.ResolveTypeSymbol(_symbol.UnderlyingType.GetEnumUnderlyingType()); + } + + /// + public readonly Array GetEnumValues() + { + return _symbol.UnderlyingType.GetEnumValues(); + } + + /// + public readonly IEventSymbol? GetEvent(string name) + { + return _symbol.ResolveEventSymbol(_symbol.UnderlyingType.GetEvent(name)); + } + + /// + public readonly IEventSymbol? GetEvent(string name, BindingFlags bindingAttr) + { + return _symbol.ResolveEventSymbol(_symbol.UnderlyingType.GetEvent(name, bindingAttr)); + } + + /// + public readonly IEventSymbol[] GetEvents() + { + return _symbol.ResolveEventSymbols(_symbol.UnderlyingType.GetEvents()); + } + + /// + public readonly IEventSymbol[] GetEvents(BindingFlags bindingAttr) + { + return _symbol.ResolveEventSymbols(_symbol.UnderlyingType.GetEvents(bindingAttr)); + } + + /// + public readonly IFieldSymbol? GetField(string name) + { + return _symbol.ResolveFieldSymbol(_symbol.UnderlyingType.GetField(name)); + } + + /// + public readonly IFieldSymbol? GetField(string name, BindingFlags bindingAttr) + { + return _symbol.ResolveFieldSymbol(_symbol.UnderlyingType.GetField(name, bindingAttr)); + } + + /// + public readonly IFieldSymbol[] GetFields() + { + return _symbol.ResolveFieldSymbols(_symbol.UnderlyingType.GetFields()); + } + + /// + public readonly IFieldSymbol[] GetFields(BindingFlags bindingAttr) + { + return _symbol.ResolveFieldSymbols(_symbol.UnderlyingType.GetFields(bindingAttr)); + } + + /// + public readonly ITypeSymbol[] GetGenericArguments() + { + return _symbol.ResolveTypeSymbols(_symbol.UnderlyingType.GetGenericArguments()); + } + + /// + public readonly ITypeSymbol[] GetGenericParameterConstraints() + { + return _symbol.ResolveTypeSymbols(_symbol.UnderlyingType.GetGenericParameterConstraints()); + } + + /// + public readonly ITypeSymbol GetGenericTypeDefinition() + { + return _symbol.ResolveTypeSymbol(_symbol.UnderlyingType.GetGenericTypeDefinition()); + } + + /// + public readonly ITypeSymbol? GetInterface(string name) + { + return _symbol.ResolveTypeSymbol(_symbol.UnderlyingType.GetInterface(name)); + } + + /// + public readonly ITypeSymbol? GetInterface(string name, bool ignoreCase) + { + return _symbol.ResolveTypeSymbol(_symbol.UnderlyingType.GetInterface(name, ignoreCase)); + } + + /// + public readonly InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) + { + throw new NotImplementedException(); + } + + /// + public readonly ITypeSymbol[] GetInterfaces(bool inherit = true) + { + if (inherit) + return _symbol.ResolveTypeSymbols(_symbol.UnderlyingType.GetInterfaces()); + else + throw new NotImplementedException(); + } + + /// + public readonly IMemberSymbol[] GetMember(string name) + { + return _symbol.ResolveMemberSymbols(_symbol.UnderlyingType.GetMember(name)); + } + + /// + public readonly IMemberSymbol[] GetMember(string name, BindingFlags bindingAttr) + { + return _symbol.ResolveMemberSymbols(_symbol.UnderlyingType.GetMember(name, bindingAttr)); + } + + /// + public readonly IMemberSymbol[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) + { + return _symbol.ResolveMemberSymbols(_symbol.UnderlyingType.GetMember(name, type, bindingAttr)); + } + + /// + public readonly IMemberSymbol[] GetMembers(BindingFlags bindingAttr) + { + return _symbol.ResolveMemberSymbols(_symbol.UnderlyingType.GetMembers(bindingAttr)); + } + + /// + public readonly IMemberSymbol[] GetMembers() + { + return _symbol.ResolveMemberSymbols(_symbol.UnderlyingType.GetMembers()); + } + + /// + public readonly IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr) + { + return _symbol.ResolveMethodSymbol(_symbol.UnderlyingType.GetMethod(name, bindingAttr)); + } + + /// + public readonly IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) + { + return _symbol.ResolveMethodSymbol(_symbol.UnderlyingType.GetMethod(name, types.Unpack())); + } + + /// + public readonly IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types) + { + return _symbol.ResolveMethodSymbol(_symbol.UnderlyingType.GetMethod(name, bindingAttr, null, types.Unpack(), null)); + } + + /// + public readonly IMethodSymbol? GetMethod(string name) + { + return _symbol.ResolveMethodSymbol(_symbol.UnderlyingType.GetMethod(name)); + } + + /// + public readonly IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers) + { + return _symbol.ResolveMethodSymbol(_symbol.UnderlyingType.GetMethod(name, bindingAttr, null, callConvention, types.Unpack(), modifiers)); + } + + /// + public readonly IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers) + { +#if NETFRAMEWORK + throw new NotImplementedException(); +#else + return _symbol.ResolveMethodSymbol(_symbol.UnderlyingType.GetMethod(name, genericParameterCount, bindingAttr, null, callConvention, types.Unpack(), modifiers)); +#endif + } + + /// + public readonly IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, ITypeSymbol[] types, ParameterModifier[]? modifiers) + { +#if NETFRAMEWORK + throw new NotImplementedException(); +#else + return _symbol.ResolveMethodSymbol(_symbol.UnderlyingType.GetMethod(name, genericParameterCount, bindingAttr, null, types.Unpack(), modifiers)); +#endif + } + + /// + public readonly IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types, ParameterModifier[]? modifiers) + { + return _symbol.ResolveMethodSymbol(_symbol.UnderlyingType.GetMethod(name, bindingAttr, null, types.Unpack(), modifiers)); + } + + /// + public readonly IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, ParameterModifier[]? modifiers) + { +#if NETFRAMEWORK + throw new NotImplementedException(); +#else + return _symbol.ResolveMethodSymbol(_symbol.UnderlyingType.GetMethod(name, genericParameterCount, types.Unpack(), modifiers)); +#endif + } + + /// + public readonly IMethodSymbol[] GetMethods(BindingFlags bindingAttr) + { + return _symbol.ResolveMethodSymbols(_symbol.UnderlyingType.GetMethods(bindingAttr)); + } + + /// + public readonly IMethodSymbol[] GetMethods() + { + return _symbol.ResolveMethodSymbols(_symbol.UnderlyingType.GetMethods()); + } + + /// + public readonly ITypeSymbol? GetNestedType(string name) + { + return _symbol.ResolveTypeSymbol(_symbol.UnderlyingType.GetNestedType(name)); + } + + /// + public readonly ITypeSymbol? GetNestedType(string name, BindingFlags bindingAttr) + { + return _symbol.ResolveTypeSymbol(_symbol.UnderlyingType.GetNestedType(name, bindingAttr)); + } + + /// + public readonly ITypeSymbol[] GetNestedTypes() + { + return _symbol.ResolveTypeSymbols(_symbol.UnderlyingType.GetNestedTypes()); + } + + /// + public readonly ITypeSymbol[] GetNestedTypes(BindingFlags bindingAttr) + { + return _symbol.ResolveTypeSymbols(_symbol.UnderlyingType.GetNestedTypes(bindingAttr)); + } + + /// + public readonly IPropertySymbol[] GetProperties() + { + return _symbol.ResolvePropertySymbols(_symbol.UnderlyingType.GetProperties()); + } + + /// + public readonly IPropertySymbol[] GetProperties(BindingFlags bindingAttr) + { + return _symbol.ResolvePropertySymbols(_symbol.UnderlyingType.GetProperties(bindingAttr)); + } + + /// + public readonly IPropertySymbol? GetProperty(string name, ITypeSymbol[] types) + { + return _symbol.ResolvePropertySymbol(_symbol.UnderlyingType.GetProperty(name, types.Unpack())); + } + + /// + public readonly IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types) + { + return _symbol.ResolvePropertySymbol(_symbol.UnderlyingType.GetProperty(name, returnType?.Unpack(), types.Unpack())); + } + + /// + public readonly IPropertySymbol? GetProperty(string name, BindingFlags bindingAttr) + { + return _symbol.ResolvePropertySymbol(_symbol.UnderlyingType.GetProperty(name, bindingAttr)); + } + + /// + public readonly IPropertySymbol? GetProperty(string name) + { + return _symbol.ResolvePropertySymbol(_symbol.UnderlyingType.GetProperty(name)); + } + + /// + public readonly IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) + { + return _symbol.ResolvePropertySymbol(_symbol.UnderlyingType.GetProperty(name, returnType?.Unpack())); + } + + /// + public readonly bool IsAssignableFrom(ITypeSymbol? c) + { + return _symbol.UnderlyingType.IsAssignableFrom(c?.Unpack()); + } + + /// + public readonly bool IsEnumDefined(object value) + { + return _symbol.UnderlyingType.IsEnumDefined(value); + } + + /// + public readonly bool IsSubclassOf(ITypeSymbol c) + { + return _symbol.UnderlyingType.IsSubclassOf(c.Unpack()); + } + + /// + public IReflectionTypeSymbol MakeArrayType() + { + if (_asSZArray == null) + Interlocked.CompareExchange(ref _asSZArray, new ReflectionTypeSymbol(_symbol.Context, _symbol.ResolvingModule, _symbol.UnderlyingType.MakeArrayType()), null); + + return _asSZArray; + } + + /// + public IReflectionTypeSymbol MakeArrayType(int rank) + { + if (rank == 1) + return MakeArrayType(); + + if (_asArray == null) + Interlocked.CompareExchange(ref _asArray, new ReflectionTypeSymbol?[32], null); + + ref var asArray = ref _asArray[rank]; + if (asArray == null) + Interlocked.CompareExchange(ref asArray, new ReflectionTypeSymbol(_symbol.Context, _symbol.ResolvingModule, _symbol.UnderlyingType.MakeArrayType(rank)), null); + + return asArray; + } + + /// + public IReflectionTypeSymbol MakeByRefType() + { + if (_asByRef == null) + Interlocked.CompareExchange(ref _asByRef, new ReflectionTypeSymbol(_symbol.Context, _symbol.ResolvingModule, _symbol.UnderlyingType.MakeByRefType()), null); + + return _asByRef; + } + + /// + public IReflectionTypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments) + { + return GetOrCreateGenericTypeSymbol(typeArguments); + } + + /// + public IReflectionTypeSymbol MakePointerType() + { + if (_asPointer == null) + Interlocked.CompareExchange(ref _asPointer, new ReflectionTypeSymbol(_symbol.Context, _symbol.ResolvingModule, _symbol.UnderlyingType.MakePointerType()), null); + + return _asPointer; + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbol.cs index d59075d06..1ff52d680 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbol.cs @@ -1,67 +1,39 @@ using System; -using System.Collections.Concurrent; -using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Reflection; -using System.Threading; namespace IKVM.CoreLib.Symbols.Reflection { - class ReflectionTypeSymbol : ReflectionMemberSymbol, ITypeSymbol + class ReflectionTypeSymbol : ReflectionMemberSymbol, IReflectionTypeSymbol { - const int MAX_CAPACITY = 65536 * 2; - - const BindingFlags DefaultBindingFlags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance; - - Type _type; - - ReflectionTypeSymbol?[]? _asArray; - ReflectionTypeSymbol? _asSZArray; - ReflectionTypeSymbol? _asPointer; - ReflectionTypeSymbol? _asByRef; - ConcurrentDictionary? _genericTypeSymbols; + readonly Type _type; + ReflectionTypeImpl _impl; /// /// Initializes a new instance. /// /// - /// + /// /// - public ReflectionTypeSymbol(ReflectionSymbolContext context, ReflectionModuleSymbol module, Type type) : - base(context, module, type) + public ReflectionTypeSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, Type type) : + base(context, resolvingModule, null, type) { - Debug.Assert(module.ReflectionObject == type.Module); _type = type ?? throw new ArgumentNullException(nameof(type)); + _impl = new ReflectionTypeImpl(this); } - /// - /// Gets or creates the cached for the generic parameter type. - /// - /// - /// - internal ReflectionTypeSymbol GetOrCreateGenericTypeSymbol(ITypeSymbol[] genericTypeArguments) - { - if (genericTypeArguments is null) - throw new ArgumentNullException(nameof(genericTypeArguments)); - - if (_type.IsGenericTypeDefinition == false) - throw new InvalidOperationException(); - - if (_genericTypeSymbols == null) - Interlocked.CompareExchange(ref _genericTypeSymbols, new ConcurrentDictionary(TypeSymbolListEqualityComparer.Instance), null); - - return _genericTypeSymbols.GetOrAdd( - genericTypeArguments, - _ => new ReflectionTypeSymbol(Context, ContainingModule, _type.MakeGenericType(genericTypeArguments.Unpack()))); - } + /// + public Type UnderlyingType => _type; /// /// Resolves the symbol for the specified type. /// /// /// - protected internal override ReflectionTypeSymbol ResolveTypeSymbol(Type type) + [return: NotNullIfNotNull(nameof(type))] + public override IReflectionTypeSymbol? ResolveTypeSymbol(Type? type) { if (type == _type) return this; @@ -69,616 +41,510 @@ protected internal override ReflectionTypeSymbol ResolveTypeSymbol(Type type) return base.ResolveTypeSymbol(type); } - /// - /// Gets the wrapped . - /// - internal new Type ReflectionObject => _type; + #region ITypeSymbol /// - public IAssemblySymbol Assembly => Context.GetOrCreateAssemblySymbol(_type.Assembly); + public TypeAttributes Attributes => _impl.Attributes; /// - public string? AssemblyQualifiedName => _type.AssemblyQualifiedName; + public IAssemblySymbol Assembly => _impl.Assembly; /// - public TypeAttributes Attributes => _type.Attributes; + public IMethodBaseSymbol? DeclaringMethod => _impl.DeclaringMethod; /// - public ITypeSymbol? BaseType => _type.BaseType != null ? ResolveTypeSymbol(_type.BaseType) : null; + public string? AssemblyQualifiedName => _impl.AssemblyQualifiedName; /// - public bool ContainsGenericParameters => _type.ContainsGenericParameters; + public string? FullName => _impl.FullName; /// - public IMethodBaseSymbol? DeclaringMethod => _type.DeclaringMethod is MethodInfo m ? ResolveMethodSymbol(m) : null; + public string? Namespace => _impl.Namespace; /// - public string? FullName => _type.FullName; + public TypeCode TypeCode => _impl.TypeCode; /// - public string? Namespace => _type.Namespace; + public ITypeSymbol? BaseType => _impl.BaseType; /// - public GenericParameterAttributes GenericParameterAttributes => _type.GenericParameterAttributes; + public bool ContainsGenericParameters => _impl.ContainsGenericParameters; /// - public int GenericParameterPosition => _type.GenericParameterPosition; + public GenericParameterAttributes GenericParameterAttributes => _impl.GenericParameterAttributes; /// - public ITypeSymbol[] GenericTypeArguments => ResolveTypeSymbols(_type.GenericTypeArguments); + public int GenericParameterPosition => _impl.GenericParameterPosition; /// - public bool HasElementType => _type.HasElementType; + public ITypeSymbol[] GenericTypeArguments => _impl.GenericTypeArguments; /// - public TypeCode TypeCode => Type.GetTypeCode(_type); + public bool IsConstructedGenericType => _impl.IsConstructedGenericType; /// - public bool IsAbstract => _type.IsAbstract; - -#if NETFRAMEWORK + public bool IsGenericType => _impl.IsGenericType; /// - /// - /// There's no API to distinguish an array of rank 1 from a vector, - /// so we check if the type name ends in [], which indicates it's a vector - /// (non-vectors will have [*] or [,]). - /// - public bool IsSZArray => _type.IsArray && _type.Name.EndsWith("[]"); - -#else + public bool IsGenericTypeDefinition => _impl.IsGenericTypeDefinition; /// - public bool IsSZArray => _type.IsSZArray; - -#endif + public bool IsGenericParameter => _impl.IsGenericParameter; /// - public bool IsArray => _type.IsArray; + public bool IsAutoLayout => _impl.IsAutoLayout; /// - public bool IsAutoLayout => _type.IsAutoLayout; + public bool IsExplicitLayout => _impl.IsExplicitLayout; /// - public bool IsExplicitLayout => _type.IsExplicitLayout; + public bool IsLayoutSequential => _impl.IsLayoutSequential; /// - public bool IsByRef => _type.IsByRef; + public bool HasElementType => _impl.HasElementType; /// - public bool IsClass => _type.IsClass; + public bool IsClass => _impl.IsClass; /// - public bool IsEnum => _type.IsEnum; + public bool IsValueType => _impl.IsValueType; /// - public bool IsInterface => _type.IsInterface; + public bool IsInterface => _impl.IsInterface; /// - public bool IsConstructedGenericType => _type.IsConstructedGenericType; + public bool IsPrimitive => _impl.IsPrimitive; /// - public bool IsGenericParameter => _type.IsGenericParameter; + public bool IsSZArray => _impl.IsSZArray; /// - public bool IsGenericType => _type.IsGenericType; + public bool IsArray => _impl.IsArray; /// - public bool IsGenericTypeDefinition => _type.IsGenericTypeDefinition; + public bool IsEnum => _impl.IsEnum; /// - public bool IsLayoutSequential => _type.IsLayoutSequential; + public bool IsPointer => _impl.IsPointer; /// - public bool IsNested => _type.IsNested; + public bool IsFunctionPointer => _impl.IsFunctionPointer; /// - public bool IsNestedAssembly => _type.IsNestedAssembly; + public bool IsUnmanagedFunctionPointer => _impl.IsUnmanagedFunctionPointer; /// - public bool IsNestedFamANDAssem => _type.IsNestedFamANDAssem; + public bool IsByRef => _impl.IsByRef; /// - public bool IsNestedFamORAssem => _type.IsNestedFamORAssem; + public bool IsAbstract => _impl.IsAbstract; /// - public bool IsNestedFamily => _type.IsNestedFamily; + public bool IsSealed => _impl.IsSealed; /// - public bool IsNestedPrivate => _type.IsNestedPrivate; + public bool IsVisible => _impl.IsVisible; /// - public bool IsNestedPublic => _type.IsNestedPublic; + public bool IsPublic => _impl.IsPublic; /// - public bool IsNotPublic => _type.IsNotPublic; + public bool IsNotPublic => _impl.IsNotPublic; /// - public bool IsPointer => _type.IsPointer; - -#if NET8_0_OR_GREATER + public bool IsNested => _impl.IsNested; /// - public bool IsFunctionPointer => _type.IsFunctionPointer; + public bool IsNestedAssembly => _impl.IsNestedAssembly; /// - public bool IsUnmanagedFunctionPointer => _type.IsUnmanagedFunctionPointer; - -#else + public bool IsNestedFamANDAssem => _impl.IsNestedFamANDAssem; /// - public bool IsFunctionPointer => throw new NotImplementedException(); + public bool IsNestedFamily => _impl.IsNestedFamily; /// - public bool IsUnmanagedFunctionPointer => throw new NotImplementedException(); - -#endif + public bool IsNestedFamORAssem => _impl.IsNestedFamORAssem; /// - public bool IsPrimitive => _type.IsPrimitive; + public bool IsNestedPrivate => _impl.IsNestedPrivate; /// - public bool IsPublic => _type.IsPublic; + public bool IsNestedPublic => _impl.IsNestedPublic; /// - public bool IsSealed => _type.IsSealed; + public bool IsSerializable => _impl.IsSerializable; -#pragma warning disable SYSLIB0050 // Type or member is obsolete /// - public bool IsSerializable => _type.IsSerializable; -#pragma warning restore SYSLIB0050 // Type or member is obsolete + public bool IsSignatureType => _impl.IsSignatureType; /// - public bool IsValueType => _type.IsValueType; + public bool IsSpecialName => _impl.IsSpecialName; /// - public bool IsVisible => _type.IsVisible; - -#if NET6_0_OR_GREATER - - /// - public bool IsSignatureType => _type.IsSignatureType; - -#else - - /// - public bool IsSignatureType => throw new NotImplementedException(); - -#endif - - /// - public bool IsSpecialName => _type.IsSpecialName; - - /// - public IConstructorSymbol? TypeInitializer => _type.TypeInitializer is ConstructorInfo ctor ? ResolveConstructorSymbol(ctor) : null; + public IConstructorSymbol? TypeInitializer => throw new NotImplementedException(); /// public int GetArrayRank() { - return _type.GetArrayRank(); - } - - /// - public IConstructorSymbol? GetConstructor(BindingFlags bindingAttr, ITypeSymbol[] types) - { - return _type.GetConstructor(bindingAttr, binder: null, types.Unpack(), modifiers: null) is ConstructorInfo ctor ? ResolveConstructorSymbol(ctor) : null; - } - - /// - public IConstructorSymbol? GetConstructor(ITypeSymbol[] types) - { - return _type.GetConstructor(types.Unpack()) is ConstructorInfo ctor ? ResolveConstructorSymbol(ctor) : null; - } - - /// - public IConstructorSymbol[] GetConstructors() - { - return ResolveConstructorSymbols(_type.GetConstructors()); - } - - /// - public IConstructorSymbol[] GetConstructors(BindingFlags bindingAttr) - { - return ResolveConstructorSymbols(_type.GetConstructors(bindingAttr)); + return _impl.GetArrayRank(); } /// public IMemberSymbol[] GetDefaultMembers() { - return ResolveMemberSymbols(_type.GetDefaultMembers()); + return _impl.GetDefaultMembers(); } /// public ITypeSymbol? GetElementType() { - return _type.GetElementType() is Type t ? ResolveTypeSymbol(t) : null; + return _impl.GetElementType(); } /// public string? GetEnumName(object value) { - return _type.GetEnumName(value); + return _impl.GetEnumName(value); } /// public string[] GetEnumNames() { - return _type.GetEnumNames(); + return _impl.GetEnumNames(); } /// public ITypeSymbol GetEnumUnderlyingType() { - return ResolveTypeSymbol(_type.GetEnumUnderlyingType()); + return _impl.GetEnumUnderlyingType(); } /// - public Array GetEnumValues() - { - return _type.GetEnumValues(); - } - - /// - public IEventSymbol? GetEvent(string name, BindingFlags bindingAttr) + public ITypeSymbol[] GetGenericArguments() { - throw new NotImplementedException(); + return _impl.GetGenericArguments(); } /// - public IEventSymbol? GetEvent(string name) + public ITypeSymbol[] GetGenericParameterConstraints() { - return _type.GetEvent(name) is { } f ? ResolveEventSymbol(f) : null; + return _impl.GetGenericParameterConstraints(); } /// - public IEventSymbol[] GetEvents() + public ITypeSymbol GetGenericTypeDefinition() { - return ResolveEventSymbols(_type.GetEvents()); + return _impl.GetGenericTypeDefinition(); } /// - public IEventSymbol[] GetEvents(BindingFlags bindingAttr) + public ITypeSymbol? GetInterface(string name) { - return ResolveEventSymbols(_type.GetEvents(bindingAttr)); + return _impl.GetInterface(name); } /// - public IFieldSymbol? GetField(string name) + public ITypeSymbol? GetInterface(string name, bool ignoreCase) { - return _type.GetField(name) is FieldInfo f ? ResolveFieldSymbol(f) : null; + return _impl.GetInterface(name, ignoreCase); } /// - public IFieldSymbol? GetField(string name, BindingFlags bindingAttr) + public ITypeSymbol[] GetInterfaces(bool inherit = true) { - return _type.GetField(name, bindingAttr) is FieldInfo f ? ResolveFieldSymbol(f) : null; + return _impl.GetInterfaces(inherit); } /// - public IFieldSymbol[] GetFields() + public InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) { - return ResolveFieldSymbols(_type.GetFields()); + return _impl.GetInterfaceMap(interfaceType); } /// - public IFieldSymbol[] GetFields(BindingFlags bindingAttr) + public IMemberSymbol[] GetMember(string name) { - return ResolveFieldSymbols(_type.GetFields(bindingAttr)); + return _impl.GetMember(name); } /// - public ITypeSymbol[] GetGenericArguments() + public IMemberSymbol[] GetMember(string name, BindingFlags bindingAttr) { - return ResolveTypeSymbols(_type.GetGenericArguments()); + return _impl.GetMember(name, bindingAttr); } /// - public ITypeSymbol[] GetGenericParameterConstraints() + public IMemberSymbol[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) { - return ResolveTypeSymbols(_type.GetGenericParameterConstraints()); + return _impl.GetMember(name, type, bindingAttr); } /// - public ITypeSymbol GetGenericTypeDefinition() + public IMemberSymbol[] GetMembers() { - return ResolveTypeSymbol(_type.GetGenericTypeDefinition()); + return _impl.GetMembers(); } /// - public ITypeSymbol? GetInterface(string name) + public IMemberSymbol[] GetMembers(BindingFlags bindingAttr) { - return _type.GetInterface(name) is { } i ? ResolveTypeSymbol(i) : null; + return _impl.GetMembers(bindingAttr); } - /// - public ITypeSymbol? GetInterface(string name, bool ignoreCase) + public IConstructorSymbol? GetConstructor(ITypeSymbol[] types) { - return _type.GetInterface(name, ignoreCase) is { } i ? ResolveTypeSymbol(i) : null; + return _impl.GetConstructor(types); } /// - public InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) + public IConstructorSymbol? GetConstructor(BindingFlags bindingAttr, ITypeSymbol[] types) { - throw new NotImplementedException(); + return _impl.GetConstructor(bindingAttr, types); } /// - public ITypeSymbol[] GetInterfaces(bool inherit = true) + public IConstructorSymbol[] GetConstructors() { - if (inherit) - return ResolveTypeSymbols(_type.GetInterfaces()); - else - throw new NotImplementedException(); + return _impl.GetConstructors(); } /// - public IMemberSymbol[] GetMember(string name) + public IConstructorSymbol[] GetConstructors(BindingFlags bindingAttr) { - return ResolveMemberSymbols(_type.GetMember(name)); + return _impl.GetConstructors(bindingAttr); } /// - public IMemberSymbol[] GetMember(string name, BindingFlags bindingAttr) + public IFieldSymbol? GetField(string name) { - return ResolveMemberSymbols(_type.GetMember(name, bindingAttr)); + return _impl.GetField(name); } /// - public IMemberSymbol[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) + public IFieldSymbol? GetField(string name, BindingFlags bindingAttr) { - return ResolveMemberSymbols(_type.GetMember(name, type, bindingAttr)); + return _impl.GetField(name, bindingAttr); } /// - public IMemberSymbol[] GetMembers(BindingFlags bindingAttr) + public IFieldSymbol[] GetFields() { - return ResolveMemberSymbols(_type.GetMembers(bindingAttr)); + return _impl.GetFields(); } /// - public IMemberSymbol[] GetMembers() + public IFieldSymbol[] GetFields(BindingFlags bindingAttr) { - return ResolveMemberSymbols(_type.GetMembers()); + return _impl.GetFields(bindingAttr); } /// - public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr) + public IMethodSymbol? GetMethod(string name) { - return _type.GetMethod(name, bindingAttr) is { } m ? ResolveMethodSymbol(m) : null; + return _impl.GetMethod(name); } /// public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) { - return _type.GetMethod(name, types.Unpack()) is { } m ? ResolveMethodSymbol(m) : null; + return _impl.GetMethod(name, types); } /// - public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types) + public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr) { - return _type.GetMethod(name, bindingAttr, null, types.Unpack(), null) is { } m ? ResolveMethodSymbol(m) : null; + return _impl.GetMethod(name, bindingAttr); } /// - public IMethodSymbol? GetMethod(string name) + public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types) { - return _type.GetMethod(name) is { } m ? ResolveMethodSymbol(m) : null; + return _impl.GetMethod(name, bindingAttr, types); } /// public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers) { - return _type.GetMethod(name, bindingAttr, null, callConvention, types.Unpack(), modifiers) is { } m ? ResolveMethodSymbol(m) : null; + return _impl.GetMethod(name, bindingAttr, callConvention, types, modifiers); } /// public IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers) { -#if NETFRAMEWORK - throw new NotImplementedException(); -#else - return _type.GetMethod(name, genericParameterCount, bindingAttr, null, callConvention, types.Unpack(), modifiers) is { } m ? ResolveMethodSymbol(m) : null; -#endif + return _impl.GetMethod(name, genericParameterCount, bindingAttr, callConvention, types, modifiers); } /// public IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, ITypeSymbol[] types, ParameterModifier[]? modifiers) { -#if NETFRAMEWORK - throw new NotImplementedException(); -#else - return _type.GetMethod(name, genericParameterCount, bindingAttr, null, types.Unpack(), modifiers) is { } m ? ResolveMethodSymbol(m) : null; -#endif + return _impl.GetMethod(name, genericParameterCount, bindingAttr, types, modifiers); } /// public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types, ParameterModifier[]? modifiers) { - return _type.GetMethod(name, bindingAttr, null, types.Unpack(), modifiers) is { } m ? ResolveMethodSymbol(m) : null; + return _impl.GetMethod(name, bindingAttr, types, modifiers); } /// public IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, ParameterModifier[]? modifiers) { -#if NETFRAMEWORK - throw new NotImplementedException(); -#else - return _type.GetMethod(name, genericParameterCount, types.Unpack(), modifiers) is { } m ? ResolveMethodSymbol(m) : null; -#endif + return _impl.GetMethod(name, genericParameterCount, types, modifiers); + } + + /// + public IMethodSymbol[] GetMethods() + { + return _impl.GetMethods(); } /// public IMethodSymbol[] GetMethods(BindingFlags bindingAttr) { - return ResolveMethodSymbols(_type.GetMethods(bindingAttr)); + return _impl.GetMethods(bindingAttr); } /// - public IMethodSymbol[] GetMethods() + public IPropertySymbol? GetProperty(string name) { - return ResolveMethodSymbols(_type.GetMethods()); + return _impl.GetProperty(name); } /// - public ITypeSymbol? GetNestedType(string name) + public IPropertySymbol? GetProperty(string name, BindingFlags bindingAttr) { - return _type.GetNestedType(name) is Type t ? ResolveTypeSymbol(t) : null; + return _impl.GetProperty(name, bindingAttr); } /// - public ITypeSymbol? GetNestedType(string name, BindingFlags bindingAttr) + public IPropertySymbol? GetProperty(string name, ITypeSymbol[] types) { - return _type.GetNestedType(name, bindingAttr) is Type t ? ResolveTypeSymbol(t) : null; + return _impl.GetProperty(name, types); } /// - public ITypeSymbol[] GetNestedTypes() + public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types) { - return ResolveTypeSymbols(_type.GetNestedTypes()); + return _impl.GetProperty(name, returnType, types); } /// - public ITypeSymbol[] GetNestedTypes(BindingFlags bindingAttr) + public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) { - return ResolveTypeSymbols(_type.GetNestedTypes(bindingAttr)); + return _impl.GetProperty(name, returnType); } /// public IPropertySymbol[] GetProperties() { - return ResolvePropertySymbols(_type.GetProperties()); + return _impl.GetProperties(); } /// public IPropertySymbol[] GetProperties(BindingFlags bindingAttr) { - return ResolvePropertySymbols(_type.GetProperties(bindingAttr)); + return _impl.GetProperties(bindingAttr); } /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol[] types) + public IEventSymbol? GetEvent(string name) { - return _type.GetProperty(name, types.Unpack()) is { } p ? ResolvePropertySymbol(p) : null; + return _impl.GetEvent(name); } /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types) + public IEventSymbol? GetEvent(string name, BindingFlags bindingAttr) { - return _type.GetProperty(name, returnType?.Unpack(), types.Unpack()) is { } p ? ResolvePropertySymbol(p) : null; + return _impl.GetEvent(name, bindingAttr); } /// - public IPropertySymbol? GetProperty(string name, BindingFlags bindingAttr) + public IEventSymbol[] GetEvents() { - return _type.GetProperty(name, bindingAttr) is { } p ? ResolvePropertySymbol(p) : null; + return _impl.GetEvents(); } /// - public IPropertySymbol? GetProperty(string name) + public IEventSymbol[] GetEvents(BindingFlags bindingAttr) { - return _type.GetProperty(name) is { } p ? ResolvePropertySymbol(p) : null; + return _impl.GetEvents(bindingAttr); } /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) + public ITypeSymbol? GetNestedType(string name) { - return _type.GetProperty(name, returnType?.Unpack()) is { } p ? ResolvePropertySymbol(p) : null; + return _impl.GetNestedType(name); } /// - public bool IsAssignableFrom(ITypeSymbol? c) + public ITypeSymbol? GetNestedType(string name, BindingFlags bindingAttr) { - return _type.IsAssignableFrom(c?.Unpack()); + return _impl.GetNestedType(name, bindingAttr); } /// - public bool IsEnumDefined(object value) + public ITypeSymbol[] GetNestedTypes() { - return _type.IsEnumDefined(value); + return _impl.GetNestedTypes(); } /// - public bool IsSubclassOf(ITypeSymbol c) + public ITypeSymbol[] GetNestedTypes(BindingFlags bindingAttr) { - return _type.IsSubclassOf(c.Unpack()); + return _impl.GetNestedTypes(); } /// - public ITypeSymbol MakeArrayType() + public bool IsAssignableFrom(ITypeSymbol? c) { - if (_asSZArray == null) - Interlocked.CompareExchange(ref _asSZArray, new ReflectionTypeSymbol(Context, ContainingModule, _type.MakeArrayType()), null); - - return _asSZArray; + return _impl.IsAssignableFrom(c); } /// - public ITypeSymbol MakeArrayType(int rank) + public bool IsSubclassOf(ITypeSymbol c) { - if (rank == 1) - return MakeArrayType(); - - if (_asArray == null) - Interlocked.CompareExchange(ref _asArray, new ReflectionTypeSymbol?[32], null); - - ref var asArray = ref _asArray[rank]; - if (asArray == null) - Interlocked.CompareExchange(ref asArray, new ReflectionTypeSymbol(Context, ContainingModule, _type.MakeArrayType(rank)), null); + return _impl.IsSubclassOf(c); + } - return asArray; + /// + public bool IsEnumDefined(object value) + { + return _impl.IsEnumDefined(value); } /// - public ITypeSymbol MakeByRefType() + public ITypeSymbol MakeArrayType() { - if (_asByRef == null) - Interlocked.CompareExchange(ref _asByRef, new ReflectionTypeSymbol(Context, ContainingModule, _type.MakeByRefType()), null); + return _impl.MakeArrayType(); + } - return _asByRef; + /// + public ITypeSymbol MakeArrayType(int rank) + { + return _impl.MakeArrayType(rank); } /// public ITypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments) { - return GetOrCreateGenericTypeSymbol(typeArguments); + return _impl.MakeGenericType(typeArguments); } /// public ITypeSymbol MakePointerType() { - if (_asPointer == null) - Interlocked.CompareExchange(ref _asPointer, new ReflectionTypeSymbol(Context, ContainingModule, _type.MakePointerType()), null); - - return _asPointer; + return _impl.MakePointerType(); } - /// - /// Sets the reflection type. Used by the builder infrastructure to complete a symbol. - /// - /// - internal void Complete(Type type) + /// + public ITypeSymbol MakeByRefType() { - ResolveTypeSymbol(_type = type); - base.Complete(_type); - - ContainingModule.Complete(_type.Module); - - foreach (var i in _type.GetConstructors(DefaultBindingFlags)) - ResolveConstructorSymbol(i).Complete(i); - - foreach (var i in _type.GetMethods(DefaultBindingFlags)) - ResolveMethodSymbol(i).Complete(i); - - foreach (var i in _type.GetFields(DefaultBindingFlags)) - ResolveFieldSymbol(i).Complete(i); - - foreach (var i in _type.GetProperties(DefaultBindingFlags)) - ResolvePropertySymbol(i).Complete(i); - - foreach (var i in _type.GetEvents(DefaultBindingFlags)) - ResolveEventSymbol(i).Complete(i); + return _impl.MakeByRefType(); } + #endregion + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionUtil.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionUtil.cs index 30d988167..fd823ad8e 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionUtil.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionUtil.cs @@ -14,7 +14,10 @@ static class ReflectionUtil /// public static Module Unpack(this IModuleSymbol module) { - return ((ReflectionModuleSymbol)module).ReflectionObject; + if (module is IReflectionModuleSymbol symbol) + return symbol.UnderlyingModule; + + throw new InvalidOperationException(); } /// @@ -38,7 +41,10 @@ public static Module[] Unpack(this IModuleSymbol[] modules) /// public static Type Unpack(this ITypeSymbol type) { - return ((ReflectionTypeSymbol)type).ReflectionObject; + if (type is IReflectionTypeSymbol symbol) + return symbol.UnderlyingType; + + throw new InvalidOperationException(); } /// @@ -76,7 +82,10 @@ public static Type[][] Unpack(this ITypeSymbol[][] types) /// public static MemberInfo Unpack(this IMemberSymbol member) { - return ((ReflectionMemberSymbol)member).ReflectionObject; + if (member is IReflectionMemberSymbol symbol) + return symbol.UnderlyingMember; + + throw new InvalidOperationException(); } /// @@ -100,7 +109,10 @@ public static MemberInfo[] Unpack(this IMemberSymbol[] members) /// public static ConstructorInfo Unpack(this IConstructorSymbol ctor) { - return ((ReflectionConstructorSymbol)ctor).ReflectionObject; + if (ctor is IReflectionConstructorSymbol symbol) + return symbol.UnderlyingConstructor; + + throw new InvalidOperationException(); } /// @@ -124,7 +136,10 @@ public static ConstructorInfo[] Unpack(this IConstructorSymbol[] ctor) /// public static MethodInfo Unpack(this IMethodSymbol ctor) { - return ((ReflectionMethodSymbol)ctor).ReflectionObject; + if (ctor is IReflectionMethodSymbol symbol) + return symbol.UnderlyingMethod; + + throw new InvalidOperationException(); } /// @@ -141,6 +156,60 @@ public static MethodInfo[] Unpack(this IMethodSymbol[] ctor) return a; } + /// + /// Unpacks the symbol into their original type. + /// + /// + /// + public static FieldInfo Unpack(this IFieldSymbol field) + { + if (field is IReflectionFieldSymbol symbol) + return symbol.UnderlyingField; + + throw new InvalidOperationException(); + } + + /// + /// Unpacks the symbols into their original type. + /// + /// + /// + public static FieldInfo[] Unpack(this IFieldSymbol[] fields) + { + var a = new FieldInfo[fields.Length]; + for (int i = 0; i < fields.Length; i++) + a[i] = fields[i].Unpack(); + + return a; + } + + /// + /// Unpacks the symbol into their original type. + /// + /// + /// + public static PropertyInfo Unpack(this IPropertySymbol property) + { + if (property is IReflectionPropertySymbol symbol) + return symbol.UnderlyingProperty; + + throw new InvalidOperationException(); + } + + /// + /// Unpacks the symbols into their original type. + /// + /// + /// + public static PropertyInfo[] Unpack(this IPropertySymbol[] properties) + { + var a = new PropertyInfo[properties.Length]; + for (int i = 0; i < properties.Length; i++) + a[i] = properties[i].Unpack(); + + return a; + } + } } diff --git a/src/IKVM.Runtime/Annotation.cs b/src/IKVM.Runtime/Annotation.cs index 9a53b8cb6..9e4d156f4 100644 --- a/src/IKVM.Runtime/Annotation.cs +++ b/src/IKVM.Runtime/Annotation.cs @@ -26,6 +26,7 @@ Jeroen Frijters using IKVM.Attributes; using IKVM.CoreLib.Symbols; +using IKVM.CoreLib.Symbols.Emit; #if IMPORTER || EXPORTER using IKVM.Reflection.Emit; @@ -308,14 +309,14 @@ private static object[] ValueQualifyClassNames(RuntimeClassLoader loader, object } } - internal abstract void Apply(RuntimeClassLoader loader, TypeBuilder tb, object annotation); - internal abstract void Apply(RuntimeClassLoader loader, MethodBuilder mb, object annotation); - internal abstract void Apply(RuntimeClassLoader loader, FieldBuilder fb, object annotation); - internal abstract void Apply(RuntimeClassLoader loader, ParameterBuilder pb, object annotation); - internal abstract void Apply(RuntimeClassLoader loader, AssemblyBuilder ab, object annotation); - internal abstract void Apply(RuntimeClassLoader loader, PropertyBuilder pb, object annotation); + internal abstract void Apply(RuntimeClassLoader loader, ITypeSymbolBuilder tb, object annotation); + internal abstract void Apply(RuntimeClassLoader loader, IMethodSymbolBuilder mb, object annotation); + internal abstract void Apply(RuntimeClassLoader loader, IFieldSymbolBuilder fb, object annotation); + internal abstract void Apply(RuntimeClassLoader loader, IParameterSymbolBuilder pb, object annotation); + internal abstract void Apply(RuntimeClassLoader loader, IAssemblySymbolBuilder ab, object annotation); + internal abstract void Apply(RuntimeClassLoader loader, IPropertySymbolBuilder pb, object annotation); - internal virtual void ApplyReturnValue(RuntimeClassLoader loader, MethodBuilder mb, ref ParameterBuilder pb, object annotation) + internal virtual void ApplyReturnValue(RuntimeClassLoader loader, IMethodSymbolBuilder mb, ref IParameterSymbolBuilder pb, object annotation) { } diff --git a/src/IKVM.Runtime/AttributeHelper.cs b/src/IKVM.Runtime/AttributeHelper.cs index 12e0e0bbc..cea132a71 100644 --- a/src/IKVM.Runtime/AttributeHelper.cs +++ b/src/IKVM.Runtime/AttributeHelper.cs @@ -33,15 +33,12 @@ Jeroen Frijters using IKVM.ByteCode.Decoding; using IKVM.ByteCode.Encoding; using IKVM.CoreLib.Symbols; +using IKVM.CoreLib.Symbols.Emit; +using IKVM.CoreLib.Symbols.IkvmReflection; -#if IMPORTER || EXPORTER -using IKVM.Reflection; -using IKVM.Reflection.Emit; -using Type = IKVM.Reflection.Type; +#if IMPORTER || EXPORTER #else -using System.Reflection; -using System.Reflection.Emit; #endif #if IMPORTER @@ -61,10 +58,10 @@ class AttributeHelper #if IMPORTER - CustomAttributeBuilder compilerGeneratedAttribute; - CustomAttributeBuilder ghostInterfaceAttribute; - CustomAttributeBuilder deprecatedAttribute; - CustomAttributeBuilder editorBrowsableNever; + ICustomAttributeBuilder compilerGeneratedAttribute; + ICustomAttributeBuilder ghostInterfaceAttribute; + ICustomAttributeBuilder deprecatedAttribute; + ICustomAttributeBuilder editorBrowsableNever; IConstructorSymbol implementsAttribute; IConstructorSymbol throwsAttribute; IConstructorSymbol sourceFileAttribute; @@ -75,7 +72,7 @@ class AttributeHelper IConstructorSymbol methodParametersAttribute; IConstructorSymbol runtimeVisibleTypeAnnotationsAttribute; IConstructorSymbol constantPoolAttribute; - CustomAttributeBuilder paramArrayAttribute; + ICustomAttributeBuilder paramArrayAttribute; IConstructorSymbol nonNestedInnerClassAttribute; IConstructorSymbol nonNestedOuterClassAttribute; @@ -108,8 +105,8 @@ class AttributeHelper ITypeSymbol typeofRuntimeVisibleTypeAnnotationsAttribute; ITypeSymbol typeofConstantPoolAttribute; ITypeSymbol typeofDebuggableAttribute; - CustomAttributeBuilder hideFromJavaAttribute; - CustomAttributeBuilder hideFromReflection; + ICustomAttributeBuilder hideFromJavaAttribute; + ICustomAttributeBuilder hideFromReflection; IConstructorSymbol debuggableAttribute; #if IMPORTER @@ -168,9 +165,9 @@ class AttributeHelper ITypeSymbol TypeOfDebuggableAttribute => typeofDebuggableAttribute ??= context.Resolver.ResolveCoreType(typeof(DebuggableAttribute).FullName); - CustomAttributeBuilder HideFromJavaAttributeBuilder => hideFromJavaAttribute ??= new CustomAttributeBuilder(TypeOfHideFromJavaAttribute.GetConstructor([]).AsReflection(), []); + ICustomAttributeBuilder HideFromJavaAttributeBuilder => hideFromJavaAttribute ??= context.Resolver.Symbols.CreateCustomAttribute(TypeOfHideFromJavaAttribute.GetConstructor([]), []); - CustomAttributeBuilder HideFromReflectionBuilder => hideFromReflection ??= new CustomAttributeBuilder(TypeOfHideFromJavaAttribute.GetConstructor([TypeOfHideFromJavaFlags]).AsReflection(), [HideFromJavaFlags.Reflection | HideFromJavaFlags.StackTrace | HideFromJavaFlags.StackWalk]); + ICustomAttributeBuilder HideFromReflectionBuilder => hideFromReflection ??= context.Resolver.Symbols.CreateCustomAttribute(TypeOfHideFromJavaAttribute.GetConstructor([TypeOfHideFromJavaFlags]), [HideFromJavaFlags.Reflection | HideFromJavaFlags.StackTrace | HideFromJavaFlags.StackWalk]); /// /// Loads the given managed type from the runtime assembly. @@ -253,32 +250,32 @@ object ParseValue(RuntimeClassLoader loader, RuntimeJavaType tw, string val) } } - internal void SetCustomAttribute(RuntimeClassLoader loader, TypeBuilder tb, IKVM.Tools.Importer.MapXml.Attribute attr) + internal void SetCustomAttribute(RuntimeClassLoader loader, ITypeSymbolBuilder tb, IKVM.Tools.Importer.MapXml.Attribute attr) { tb.SetCustomAttribute(CreateCustomAttribute(loader, attr)); } - internal void SetCustomAttribute(RuntimeClassLoader loader, FieldBuilder fb, IKVM.Tools.Importer.MapXml.Attribute attr) + internal void SetCustomAttribute(RuntimeClassLoader loader, IFieldSymbolBuilder fb, IKVM.Tools.Importer.MapXml.Attribute attr) { fb.SetCustomAttribute(CreateCustomAttribute(loader, attr)); } - internal void SetCustomAttribute(RuntimeClassLoader loader, ParameterBuilder pb, IKVM.Tools.Importer.MapXml.Attribute attr) + internal void SetCustomAttribute(RuntimeClassLoader loader, IParameterSymbolBuilder pb, IKVM.Tools.Importer.MapXml.Attribute attr) { pb.SetCustomAttribute(CreateCustomAttribute(loader, attr)); } - internal void SetCustomAttribute(RuntimeClassLoader loader, MethodBuilder mb, IKVM.Tools.Importer.MapXml.Attribute attr) + internal void SetCustomAttribute(RuntimeClassLoader loader, IMethodSymbolBuilder mb, IKVM.Tools.Importer.MapXml.Attribute attr) { mb.SetCustomAttribute(CreateCustomAttribute(loader, attr)); } - internal void SetCustomAttribute(RuntimeClassLoader loader, PropertyBuilder pb, IKVM.Tools.Importer.MapXml.Attribute attr) + internal void SetCustomAttribute(RuntimeClassLoader loader, IPropertySymbolBuilder pb, IKVM.Tools.Importer.MapXml.Attribute attr) { pb.SetCustomAttribute(CreateCustomAttribute(loader, attr)); } - internal void SetCustomAttribute(RuntimeClassLoader loader, AssemblyBuilder ab, IKVM.Tools.Importer.MapXml.Attribute attr) + internal void SetCustomAttribute(RuntimeClassLoader loader, IAssemblySymbolBuilder ab, IKVM.Tools.Importer.MapXml.Attribute attr) { ab.SetCustomAttribute(CreateCustomAttribute(loader, attr)); } @@ -312,7 +309,7 @@ void GetAttributeArgsAndTypes(RuntimeClassLoader loader, IKVM.Tools.Importer.Map } } - CustomAttributeBuilder CreateCustomAttribute(RuntimeClassLoader loader, IKVM.Tools.Importer.MapXml.Attribute attr) + ICustomAttributeBuilder CreateCustomAttribute(RuntimeClassLoader loader, IKVM.Tools.Importer.MapXml.Attribute attr) { // TODO add error handling GetAttributeArgsAndTypes(loader, attr, out var argTypes, out var args); @@ -351,7 +348,7 @@ CustomAttributeBuilder CreateCustomAttribute(RuntimeClassLoader loader, IKVM.Too } } - return new CustomAttributeBuilder(ci.AsReflection(), args, namedProperties.AsReflection(), propertyValues, namedFields.AsReflection(), fieldValues); + return context.Resolver.Symbols.CreateCustomAttribute(ci, args, namedProperties, propertyValues, namedFields, fieldValues); } else { @@ -383,153 +380,142 @@ CustomAttributeBuilder CreateCustomAttribute(RuntimeClassLoader loader, IKVM.Too mw.Link(); var ci = (mw.GetMethod() as IConstructorSymbol) ?? ((IConstructorSymbol)mw.GetMethod()); - return new CustomAttributeBuilder(ci.AsReflection(), args, namedFields.AsReflection(), fieldValues); + return context.Resolver.Symbols.CreateCustomAttribute(ci, args, namedFields, fieldValues); } } - CustomAttributeBuilder GetEditorBrowsableNever() + ICustomAttributeBuilder GetEditorBrowsableNever() { if (editorBrowsableNever == null) { - var typeofEditorBrowsableAttribute = context.Resolver.ResolveCoreType(typeof(EditorBrowsableAttribute).FullName).AsReflection(); - var typeofEditorBrowsableState = context.Resolver.ResolveCoreType(typeof(EditorBrowsableState).FullName).AsReflection(); - var ctor = (ConstructorInfo)typeofEditorBrowsableAttribute.__CreateMissingMethod(ConstructorInfo.ConstructorName, CallingConventions.Standard | CallingConventions.HasThis, null, default, new Type[] { typeofEditorBrowsableState }, null); - editorBrowsableNever = CustomAttributeBuilder.__FromBlob(ctor, new byte[] { 01, 00, 01, 00, 00, 00, 00, 00 }); + var typeofEditorBrowsableAttribute = context.Resolver.ResolveCoreType(typeof(EditorBrowsableAttribute).FullName); + var typeofEditorBrowsableState = context.Resolver.ResolveCoreType(typeof(EditorBrowsableState).FullName); + var ctor = typeofEditorBrowsableAttribute.GetConstructor([typeofEditorBrowsableState]); + editorBrowsableNever = context.Resolver.Symbols.CreateCustomAttribute(ctor, [EditorBrowsableState.Never]); } return editorBrowsableNever; } - internal void SetCompilerGenerated(TypeBuilder tb) + internal void SetCompilerGenerated(ITypeSymbolBuilder tb) { - compilerGeneratedAttribute ??= new CustomAttributeBuilder(context.Resolver.ResolveCoreType(typeof(CompilerGeneratedAttribute).FullName).AsReflection().GetConstructor([]), Array.Empty()); + compilerGeneratedAttribute ??= context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveCoreType(typeof(CompilerGeneratedAttribute).FullName).GetConstructor([]), []); tb.SetCustomAttribute(compilerGeneratedAttribute); } - internal void SetCompilerGenerated(MethodBuilder mb) + internal void SetCompilerGenerated(IMethodSymbolBuilder mb) { - compilerGeneratedAttribute ??= new CustomAttributeBuilder(context.Resolver.ResolveCoreType(typeof(CompilerGeneratedAttribute).FullName).AsReflection().GetConstructor([]), Array.Empty()); + compilerGeneratedAttribute ??= context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveCoreType(typeof(CompilerGeneratedAttribute).FullName).GetConstructor([]), []); mb.SetCustomAttribute(compilerGeneratedAttribute); } - internal void SetEditorBrowsableNever(TypeBuilder tb) + internal void SetEditorBrowsableNever(ITypeSymbolBuilder tb) { tb.SetCustomAttribute(GetEditorBrowsableNever()); } - internal void SetEditorBrowsableNever(MethodBuilder mb) + internal void SetEditorBrowsableNever(IMethodSymbolBuilder mb) { mb.SetCustomAttribute(GetEditorBrowsableNever()); } - internal void SetEditorBrowsableNever(PropertyBuilder pb) + internal void SetEditorBrowsableNever(IPropertySymbolBuilder pb) { pb.SetCustomAttribute(GetEditorBrowsableNever()); } - internal void SetDeprecatedAttribute(MethodBuilder mb) + internal void SetDeprecatedAttribute(IMethodSymbolBuilder mb) { - if (deprecatedAttribute == null) - deprecatedAttribute = new CustomAttributeBuilder(context.Resolver.ResolveCoreType(typeof(ObsoleteAttribute).FullName).GetConstructor([]).AsReflection(), []); - + deprecatedAttribute ??= context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveCoreType(typeof(ObsoleteAttribute).FullName).GetConstructor([]), []); mb.SetCustomAttribute(deprecatedAttribute); } - internal void SetDeprecatedAttribute(TypeBuilder tb) + internal void SetDeprecatedAttribute(ITypeSymbolBuilder tb) { - if (deprecatedAttribute == null) - { - deprecatedAttribute = new CustomAttributeBuilder(context.Resolver.ResolveCoreType(typeof(ObsoleteAttribute).FullName).GetConstructor([]).AsReflection(), []); - } - + deprecatedAttribute ??= context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveCoreType(typeof(ObsoleteAttribute).FullName).GetConstructor([]), []); tb.SetCustomAttribute(deprecatedAttribute); } - internal void SetDeprecatedAttribute(FieldBuilder fb) + internal void SetDeprecatedAttribute(IFieldSymbolBuilder fb) { - if (deprecatedAttribute == null) - deprecatedAttribute = new CustomAttributeBuilder(context.Resolver.ResolveCoreType(typeof(ObsoleteAttribute).FullName).GetConstructor([]).AsReflection(), []); - + deprecatedAttribute ??= context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveCoreType(typeof(ObsoleteAttribute).FullName).GetConstructor([]), []); fb.SetCustomAttribute(deprecatedAttribute); } - internal void SetDeprecatedAttribute(PropertyBuilder pb) + internal void SetDeprecatedAttribute(IPropertySymbolBuilder pb) { - if (deprecatedAttribute == null) - { - deprecatedAttribute = new CustomAttributeBuilder(context.Resolver.ResolveCoreType(typeof(ObsoleteAttribute).FullName).GetConstructor([]).AsReflection(), []); - } + deprecatedAttribute ??= context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveCoreType(typeof(ObsoleteAttribute).FullName).GetConstructor([]), []); pb.SetCustomAttribute(deprecatedAttribute); } - internal void SetThrowsAttribute(MethodBuilder mb, string[] exceptions) + internal void SetThrowsAttribute(IMethodSymbolBuilder mb, string[] exceptions) { if (exceptions != null && exceptions.Length != 0) { throwsAttribute ??= TypeOfThrowsAttribute.GetConstructor([context.Resolver.ResolveCoreType(typeof(string).FullName).MakeArrayType()]); exceptions = UnicodeUtil.EscapeInvalidSurrogates(exceptions); - mb.SetCustomAttribute(new CustomAttributeBuilder(throwsAttribute.AsReflection(), [exceptions])); + mb.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(throwsAttribute, [exceptions])); } } - internal void SetGhostInterface(TypeBuilder typeBuilder) + internal void SetGhostInterface(ITypeSymbolBuilder typeBuilder) { - ghostInterfaceAttribute ??= new CustomAttributeBuilder(TypeOfGhostInterfaceAttribute.GetConstructor([]).AsReflection(), []); + ghostInterfaceAttribute ??= context.Resolver.Symbols.CreateCustomAttribute(TypeOfGhostInterfaceAttribute.GetConstructor([]), []); typeBuilder.SetCustomAttribute(ghostInterfaceAttribute); } - internal void SetNonNestedInnerClass(TypeBuilder typeBuilder, string className) + internal void SetNonNestedInnerClass(ITypeSymbolBuilder typeBuilder, string className) { nonNestedInnerClassAttribute ??= TypeOfNonNestedInnerClassAttribute.GetConstructor([context.Types.String]); - typeBuilder.SetCustomAttribute(new CustomAttributeBuilder(nonNestedInnerClassAttribute.AsReflection(), [UnicodeUtil.EscapeInvalidSurrogates(className)])); + typeBuilder.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(nonNestedInnerClassAttribute, [UnicodeUtil.EscapeInvalidSurrogates(className)])); } - internal void SetNonNestedOuterClass(TypeBuilder typeBuilder, string className) + internal void SetNonNestedOuterClass(ITypeSymbolBuilder typeBuilder, string className) { nonNestedOuterClassAttribute ??= TypeOfNonNestedOuterClassAttribute.GetConstructor([context.Types.String]); - typeBuilder.SetCustomAttribute(new CustomAttributeBuilder(nonNestedOuterClassAttribute.AsReflection(), [UnicodeUtil.EscapeInvalidSurrogates(className)])); + typeBuilder.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(nonNestedOuterClassAttribute, [UnicodeUtil.EscapeInvalidSurrogates(className)])); } #endif // IMPORTER - internal void HideFromReflection(MethodBuilder mb) + internal void HideFromReflection(IMethodSymbolBuilder mb) { mb.SetCustomAttribute(HideFromReflectionBuilder); } - internal void HideFromReflection(FieldBuilder fb) + internal void HideFromReflection(IFieldSymbolBuilder fb) { fb.SetCustomAttribute(HideFromReflectionBuilder); } - internal void HideFromReflection(PropertyBuilder pb) + internal void HideFromReflection(IPropertySymbolBuilder pb) { pb.SetCustomAttribute(HideFromReflectionBuilder); } - internal void HideFromJava(TypeBuilder typeBuilder) + internal void HideFromJava(ITypeSymbolBuilder typeBuilder) { typeBuilder.SetCustomAttribute(HideFromJavaAttributeBuilder); } - internal void HideFromJava(MethodBuilder mb) + internal void HideFromJava(IMethodSymbolBuilder mb) { mb.SetCustomAttribute(HideFromJavaAttributeBuilder); } - internal void HideFromJava(MethodBuilder mb, HideFromJavaFlags flags) + internal void HideFromJava(IMethodSymbolBuilder mb, HideFromJavaFlags flags) { - mb.SetCustomAttribute(new CustomAttributeBuilder(TypeOfHideFromJavaAttribute.GetConstructor([TypeOfHideFromJavaFlags]).AsReflection(), [flags])); + mb.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(TypeOfHideFromJavaAttribute.GetConstructor([TypeOfHideFromJavaFlags]), [flags])); } - internal void HideFromJava(FieldBuilder fb) + internal void HideFromJava(IFieldSymbolBuilder fb) { fb.SetCustomAttribute(HideFromJavaAttributeBuilder); } #if IMPORTER - internal void HideFromJava(PropertyBuilder pb) + internal void HideFromJava(IPropertySymbolBuilder pb) { pb.SetCustomAttribute(HideFromJavaAttributeBuilder); } @@ -550,12 +536,12 @@ internal HideFromJavaFlags GetHideFromJavaFlags(IMemberSymbol mi) { // NOTE all privatescope fields and methods are "hideFromJava" // because Java cannot deal with the potential name clashes - var fi = mi as FieldInfo; - if (fi != null && (fi.Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.PrivateScope) + var fi = mi as IFieldSymbol; + if (fi != null && (fi.Attributes & System.Reflection.FieldAttributes.FieldAccessMask) == System.Reflection.FieldAttributes.PrivateScope) return HideFromJavaFlags.All; - var mb = mi as MethodBase; - if (mb != null && (mb.Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.PrivateScope) + var mb = mi as IMethodBaseSymbol; + if (mb != null && (mb.Attributes & System.Reflection.MethodAttributes.MemberAccessMask) == System.Reflection.MethodAttributes.PrivateScope) return HideFromJavaFlags.All; if (mi.Name.StartsWith("__<", StringComparison.Ordinal)) return HideFromJavaFlags.All; @@ -575,7 +561,7 @@ internal HideFromJavaFlags GetHideFromJavaFlags(IMemberSymbol mi) #if IMPORTER - internal void SetImplementsAttribute(TypeBuilder typeBuilder, RuntimeJavaType[] ifaceWrappers) + internal void SetImplementsAttribute(ITypeSymbolBuilder typeBuilder, RuntimeJavaType[] ifaceWrappers) { var interfaces = new string[ifaceWrappers.Length]; for (int i = 0; i < interfaces.Length; i++) @@ -584,7 +570,7 @@ internal void SetImplementsAttribute(TypeBuilder typeBuilder, RuntimeJavaType[] if (implementsAttribute == null) implementsAttribute = TypeOfImplementsAttribute.GetConstructor([context.Resolver.ResolveCoreType(typeof(string).FullName).MakeArrayType()]); - typeBuilder.SetCustomAttribute(new CustomAttributeBuilder(implementsAttribute.AsReflection(), new object[] { interfaces })); + typeBuilder.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(implementsAttribute, [interfaces])); } #endif @@ -730,86 +716,86 @@ internal ExModifiers GetModifiers(IFieldSymbol fi, bool assemblyIsPrivate) return new ExModifiers(modifiers, false); } - internal void SetDebuggingModes(AssemblyBuilder assemblyBuilder, DebuggableAttribute.DebuggingModes modes) + internal void SetDebuggingModes(IAssemblySymbolBuilder assemblyBuilder, DebuggableAttribute.DebuggingModes modes) { debuggableAttribute ??= TypeOfDebuggableAttribute.GetConstructor([TypeOfDebuggableAttribute.GetNestedType(nameof(DebuggableAttribute.DebuggingModes))]); - assemblyBuilder.SetCustomAttribute(new CustomAttributeBuilder(debuggableAttribute.AsReflection(), [modes])); + assemblyBuilder.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(debuggableAttribute, [modes])); } #if IMPORTER - internal void SetModifiers(MethodBuilder mb, Modifiers modifiers, bool isInternal) + internal void SetModifiers(IMethodSymbolBuilder mb, Modifiers modifiers, bool isInternal) { - CustomAttributeBuilder customAttributeBuilder; + ICustomAttributeBuilder customAttributeBuilder; if (isInternal) - customAttributeBuilder = new CustomAttributeBuilder(TypeOfModifiersAttribute.GetConstructor([TypeOfModifiers, context.Types.Boolean]).AsReflection(), [modifiers, isInternal]); + customAttributeBuilder = context.Resolver.Symbols.CreateCustomAttribute(TypeOfModifiersAttribute.GetConstructor([TypeOfModifiers, context.Types.Boolean]), [modifiers, isInternal]); else - customAttributeBuilder = new CustomAttributeBuilder(TypeOfModifiersAttribute.GetConstructor([TypeOfModifiers]).AsReflection(), [modifiers]); + customAttributeBuilder = context.Resolver.Symbols.CreateCustomAttribute(TypeOfModifiersAttribute.GetConstructor([TypeOfModifiers]), [modifiers]); mb.SetCustomAttribute(customAttributeBuilder); } - internal void SetModifiers(FieldBuilder fb, Modifiers modifiers, bool isInternal) + internal void SetModifiers(IFieldSymbolBuilder fb, Modifiers modifiers, bool isInternal) { - CustomAttributeBuilder customAttributeBuilder; + ICustomAttributeBuilder customAttributeBuilder; if (isInternal) - customAttributeBuilder = new CustomAttributeBuilder(TypeOfModifiersAttribute.GetConstructor([TypeOfModifiers, context.Types.Boolean]).AsReflection(), [modifiers, isInternal]); + customAttributeBuilder = context.Resolver.Symbols.CreateCustomAttribute(TypeOfModifiersAttribute.GetConstructor([TypeOfModifiers, context.Types.Boolean]), [modifiers, isInternal]); else - customAttributeBuilder = new CustomAttributeBuilder(TypeOfModifiersAttribute.GetConstructor([TypeOfModifiers]).AsReflection(), [modifiers]); + customAttributeBuilder = context.Resolver.Symbols.CreateCustomAttribute(TypeOfModifiersAttribute.GetConstructor([TypeOfModifiers]), [modifiers]); fb.SetCustomAttribute(customAttributeBuilder); } - internal void SetModifiers(PropertyBuilder pb, Modifiers modifiers, bool isInternal) + internal void SetModifiers(IPropertySymbolBuilder pb, Modifiers modifiers, bool isInternal) { - CustomAttributeBuilder customAttributeBuilder; + ICustomAttributeBuilder customAttributeBuilder; if (isInternal) - customAttributeBuilder = new CustomAttributeBuilder(TypeOfModifiersAttribute.GetConstructor([TypeOfModifiers, context.Types.Boolean]).AsReflection(), [modifiers, isInternal]); + customAttributeBuilder = context.Resolver.Symbols.CreateCustomAttribute(TypeOfModifiersAttribute.GetConstructor([TypeOfModifiers, context.Types.Boolean]), [modifiers, isInternal]); else - customAttributeBuilder = new CustomAttributeBuilder(TypeOfModifiersAttribute.GetConstructor([TypeOfModifiers]).AsReflection(), [modifiers]); + customAttributeBuilder = context.Resolver.Symbols.CreateCustomAttribute(TypeOfModifiersAttribute.GetConstructor([TypeOfModifiers]), [modifiers]); pb.SetCustomAttribute(customAttributeBuilder); } - internal void SetModifiers(TypeBuilder tb, Modifiers modifiers, bool isInternal) + internal void SetModifiers(ITypeSymbolBuilder tb, Modifiers modifiers, bool isInternal) { - CustomAttributeBuilder customAttributeBuilder; + ICustomAttributeBuilder customAttributeBuilder; if (isInternal) - customAttributeBuilder = new CustomAttributeBuilder(TypeOfModifiersAttribute.GetConstructor([TypeOfModifiers, context.Types.Boolean]).AsReflection(), [modifiers, isInternal]); + customAttributeBuilder = context.Resolver.Symbols.CreateCustomAttribute(TypeOfModifiersAttribute.GetConstructor([TypeOfModifiers, context.Types.Boolean]), [modifiers, isInternal]); else - customAttributeBuilder = new CustomAttributeBuilder(TypeOfModifiersAttribute.GetConstructor([TypeOfModifiers]).AsReflection(), [modifiers]); + customAttributeBuilder = context.Resolver.Symbols.CreateCustomAttribute(TypeOfModifiersAttribute.GetConstructor([TypeOfModifiers]), [modifiers]); tb.SetCustomAttribute(customAttributeBuilder); } - internal void SetNameSig(MethodBuilder mb, string name, string sig) + internal void SetNameSig(IMethodSymbolBuilder mb, string name, string sig) { - var customAttributeBuilder = new CustomAttributeBuilder(TypeOfNameSigAttribute.GetConstructor([context.Types.String, context.Types.String]).AsReflection(), [UnicodeUtil.EscapeInvalidSurrogates(name), UnicodeUtil.EscapeInvalidSurrogates(sig)]); + var customAttributeBuilder = context.Resolver.Symbols.CreateCustomAttribute(TypeOfNameSigAttribute.GetConstructor([context.Types.String, context.Types.String]), [UnicodeUtil.EscapeInvalidSurrogates(name), UnicodeUtil.EscapeInvalidSurrogates(sig)]); mb.SetCustomAttribute(customAttributeBuilder); } - internal void SetInnerClass(TypeBuilder typeBuilder, string innerClass, Modifiers modifiers) + internal void SetInnerClass(ITypeSymbolBuilder typeBuilder, string innerClass, Modifiers modifiers) { var argTypes = new ITypeSymbol[] { context.Types.String, TypeOfModifiers }; var args = new object[] { UnicodeUtil.EscapeInvalidSurrogates(innerClass), modifiers }; var ci = TypeOfInnerClassAttribute.GetConstructor(argTypes); - var customAttributeBuilder = new CustomAttributeBuilder(ci.AsReflection(), args); + var customAttributeBuilder = context.Resolver.Symbols.CreateCustomAttribute(ci, args); typeBuilder.SetCustomAttribute(customAttributeBuilder); } - internal void SetSourceFile(TypeBuilder typeBuilder, string filename) + internal void SetSourceFile(ITypeSymbolBuilder typeBuilder, string filename) { sourceFileAttribute ??= TypeOfSourceFileAttribute.GetConstructor([context.Types.String]); - typeBuilder.SetCustomAttribute(new CustomAttributeBuilder(sourceFileAttribute.AsReflection(), [filename])); + typeBuilder.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(sourceFileAttribute, [filename])); } - internal void SetSourceFile(ModuleBuilder moduleBuilder, string filename) + internal void SetSourceFile(IMethodSymbolBuilder moduleBuilder, string filename) { sourceFileAttribute ??= TypeOfSourceFileAttribute.GetConstructor([context.Types.String]); - moduleBuilder.SetCustomAttribute(new CustomAttributeBuilder(sourceFileAttribute.AsReflection(), new object[] { filename })); + moduleBuilder.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(sourceFileAttribute, [filename])); } - internal void SetLineNumberTable(MethodBuilder mb, IKVM.Attributes.LineNumberTableAttribute.LineNumberWriter writer) + internal void SetLineNumberTable(IMethodSymbolBuilder mb, IKVM.Attributes.LineNumberTableAttribute.LineNumberWriter writer) { object arg; IConstructorSymbol con; @@ -825,81 +811,79 @@ internal void SetLineNumberTable(MethodBuilder mb, IKVM.Attributes.LineNumberTab con = lineNumberTableAttribute1; arg = writer.ToArray(); } - mb.SetCustomAttribute(new CustomAttributeBuilder(con.AsReflection(), [arg])); + + mb.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(con, [arg])); } - internal void SetEnclosingMethodAttribute(TypeBuilder tb, string className, string methodName, string methodSig) + internal void SetEnclosingMethodAttribute(ITypeSymbolBuilder tb, string className, string methodName, string methodSig) { - if (enclosingMethodAttribute == null) - { - enclosingMethodAttribute = TypeOfEnclosingMethodAttribute.GetConstructor([context.Types.String, context.Types.String, context.Types.String]); - } - tb.SetCustomAttribute(new CustomAttributeBuilder(enclosingMethodAttribute.AsReflection(), [UnicodeUtil.EscapeInvalidSurrogates(className), UnicodeUtil.EscapeInvalidSurrogates(methodName), UnicodeUtil.EscapeInvalidSurrogates(methodSig)])); + enclosingMethodAttribute ??= TypeOfEnclosingMethodAttribute.GetConstructor([context.Types.String, context.Types.String, context.Types.String]); + tb.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(enclosingMethodAttribute, [UnicodeUtil.EscapeInvalidSurrogates(className), UnicodeUtil.EscapeInvalidSurrogates(methodName), UnicodeUtil.EscapeInvalidSurrogates(methodSig)])); } - internal void SetSignatureAttribute(TypeBuilder tb, string signature) + internal void SetSignatureAttribute(ITypeSymbolBuilder tb, string signature) { signatureAttribute ??= TypeOfSignatureAttribute.GetConstructor([context.Types.String]); - tb.SetCustomAttribute(new CustomAttributeBuilder(signatureAttribute.AsReflection(), [UnicodeUtil.EscapeInvalidSurrogates(signature)])); + tb.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(signatureAttribute, [UnicodeUtil.EscapeInvalidSurrogates(signature)])); } - internal void SetSignatureAttribute(FieldBuilder fb, string signature) + internal void SetSignatureAttribute(IFieldSymbolBuilder fb, string signature) { signatureAttribute ??= TypeOfSignatureAttribute.GetConstructor([context.Types.String]); - fb.SetCustomAttribute(new CustomAttributeBuilder(signatureAttribute.AsReflection(), [UnicodeUtil.EscapeInvalidSurrogates(signature)])); + fb.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(signatureAttribute, [UnicodeUtil.EscapeInvalidSurrogates(signature)])); } - internal void SetSignatureAttribute(MethodBuilder mb, string signature) + internal void SetSignatureAttribute(IMethodSymbolBuilder mb, string signature) { signatureAttribute ??= TypeOfSignatureAttribute.GetConstructor([context.Types.String]); - mb.SetCustomAttribute(new CustomAttributeBuilder(signatureAttribute.AsReflection(), [UnicodeUtil.EscapeInvalidSurrogates(signature)])); + mb.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(signatureAttribute, [UnicodeUtil.EscapeInvalidSurrogates(signature)])); } - internal void SetMethodParametersAttribute(MethodBuilder mb, Modifiers[] modifiers) + internal void SetMethodParametersAttribute(IMethodSymbolBuilder mb, Modifiers[] modifiers) { methodParametersAttribute ??= TypeOfMethodParametersAttribute.GetConstructor([TypeOfModifiers.MakeArrayType()]); - mb.SetCustomAttribute(new CustomAttributeBuilder(methodParametersAttribute.AsReflection(), [modifiers])); + mb.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(methodParametersAttribute, [modifiers])); } - internal void SetRuntimeVisibleTypeAnnotationsAttribute(TypeBuilder tb, ref readonly TypeAnnotationTable table) + internal void SetRuntimeVisibleTypeAnnotationsAttribute(ITypeSymbolBuilder tb, ref readonly TypeAnnotationTable table) { var builder = new BlobBuilder(); var encoder = new TypeAnnotationTableEncoder(builder); table.WriteTo(ref encoder); runtimeVisibleTypeAnnotationsAttribute ??= TypeOfRuntimeVisibleTypeAnnotationsAttribute.GetConstructor([context.Types.Byte.MakeArrayType()]); - tb.SetCustomAttribute(new CustomAttributeBuilder(runtimeVisibleTypeAnnotationsAttribute.AsReflection(), [builder.ToArray()])); + tb.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(runtimeVisibleTypeAnnotationsAttribute, [builder.ToArray()])); } - internal void SetRuntimeVisibleTypeAnnotationsAttribute(FieldBuilder fb, ref readonly TypeAnnotationTable table) + internal void SetRuntimeVisibleTypeAnnotationsAttribute(IFieldSymbolBuilder fb, ref readonly TypeAnnotationTable table) { var builder = new BlobBuilder(); var encoder = new TypeAnnotationTableEncoder(builder); table.WriteTo(ref encoder); runtimeVisibleTypeAnnotationsAttribute ??= TypeOfRuntimeVisibleTypeAnnotationsAttribute.GetConstructor([context.Types.Byte.MakeArrayType()]); - fb.SetCustomAttribute(new CustomAttributeBuilder(runtimeVisibleTypeAnnotationsAttribute.AsReflection(), [builder.ToArray()])); + fb.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(runtimeVisibleTypeAnnotationsAttribute, [builder.ToArray()])); } - internal void SetRuntimeVisibleTypeAnnotationsAttribute(MethodBuilder mb, ref readonly TypeAnnotationTable table) + internal void SetRuntimeVisibleTypeAnnotationsAttribute(IMethodSymbolBuilder mb, ref readonly TypeAnnotationTable table) { var builder = new BlobBuilder(); var encoder = new TypeAnnotationTableEncoder(builder); table.WriteTo(ref encoder); runtimeVisibleTypeAnnotationsAttribute ??= TypeOfRuntimeVisibleTypeAnnotationsAttribute.GetConstructor([context.Types.Byte.MakeArrayType()]); - mb.SetCustomAttribute(new CustomAttributeBuilder(runtimeVisibleTypeAnnotationsAttribute.AsReflection(), [builder.ToArray()])); + mb.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(runtimeVisibleTypeAnnotationsAttribute, [builder.ToArray()])); } - internal void SetConstantPoolAttribute(TypeBuilder tb, object[] constantPool) + internal void SetConstantPoolAttribute(ITypeSymbolBuilder tb, object[] constantPool) { constantPoolAttribute ??= TypeOfConstantPoolAttribute.GetConstructor([context.Types.Object.MakeArrayType()]); - tb.SetCustomAttribute(new CustomAttributeBuilder(constantPoolAttribute.AsReflection(), [constantPool])); + tb.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(constantPoolAttribute, [constantPool])); } - internal void SetParamArrayAttribute(ParameterBuilder pb) + internal void SetParamArrayAttribute(IParameterSymbolBuilder pb) { - paramArrayAttribute ??= new CustomAttributeBuilder(context.Resolver.ResolveCoreType(typeof(ParamArrayAttribute).FullName).GetConstructor([]).AsReflection(), []); + paramArrayAttribute ??= context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveCoreType(typeof(ParamArrayAttribute).FullName).GetConstructor([]), []); pb.SetCustomAttribute(paramArrayAttribute); } @@ -916,19 +900,10 @@ internal NameSigAttribute GetNameSig(IMemberSymbol member) return null; } - internal T[] DecodeArray(CoreLib.Symbols.CustomAttributeTypedArgument arg) + internal T[] DecodeArray(IKVM.CoreLib.Symbols.CustomAttributeTypedArgument arg) { - -/* Unmerged change from project 'IKVM.Tools.Exporter (net8.0)' -Before: - var elems = (IList)arg.Value; - var arr = new T[elems.Count]; -After: - var elems = (IList)arg.Value; - var arr = new T[elems.Count]; -*/ - var elems = (IList)arg.Value; - var arr = new T[elems.Count]; + var elems = (CustomAttributeTypedArgument[])arg.Value; + var arr = new T[elems.Length]; for (int i = 0; i < arr.Length; i++) arr[i] = (T)elems[i].Value; @@ -957,11 +932,11 @@ internal ThrowsAttribute GetThrows(IMethodBaseSymbol mb) } else if (args[0].ArgumentType == context.Types.Type.MakeArrayType()) { - return new ThrowsAttribute(DecodeArray(args[0])); + return new ThrowsAttribute(DecodeArray(args[0]).Unpack()); } else { - return new ThrowsAttribute((Type)args[0].Value); + return new ThrowsAttribute(((ITypeSymbol)args[0].Value).AsReflection()); } } @@ -1125,49 +1100,49 @@ internal bool HasEnclosingMethodAttribute(ITypeSymbol type) internal IKVM.Attributes.EnclosingMethodAttribute GetEnclosingMethodAttribute(ITypeSymbol type) { foreach (var cad in type.GetCustomAttributes(TypeOfEnclosingMethodAttribute)) - return new IKVM.Attributes.EnclosingMethodAttribute((string)cad.ConstructorArguments[0].Value, (string)cad.ConstructorArguments[1].Value, (string)cad.ConstructorArguments[2].Value).SetClassName(context, type.AsReflection()); + return new IKVM.Attributes.EnclosingMethodAttribute((string)cad.ConstructorArguments[0].Value, (string)cad.ConstructorArguments[1].Value, (string)cad.ConstructorArguments[2].Value).SetClassName(context, type); return null; } #if IMPORTER - internal void SetRemappedClass(AssemblyBuilder assemblyBuilder, string name, ITypeSymbol shadowType) + internal void SetRemappedClass(IAssemblySymbolBuilder assemblyBuilder, string name, ITypeSymbol shadowType) { var remappedClassAttribute = TypeOfRemappedClassAttribute.GetConstructor([context.Types.String, context.Types.Type]); - assemblyBuilder.SetCustomAttribute(new CustomAttributeBuilder(remappedClassAttribute.AsReflection(), [name, shadowType])); + assemblyBuilder.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(remappedClassAttribute, [name, shadowType])); } - internal void SetRemappedType(TypeBuilder typeBuilder, ITypeSymbol shadowType) + internal void SetRemappedType(ITypeSymbolBuilder typeBuilder, ITypeSymbol shadowType) { var remappedTypeAttribute = TypeOfRemappedTypeAttribute.GetConstructor([context.Types.Type]); - typeBuilder.SetCustomAttribute(new CustomAttributeBuilder(remappedTypeAttribute.AsReflection(), [shadowType])); + typeBuilder.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(remappedTypeAttribute, [shadowType])); } - internal void SetRemappedInterfaceMethod(TypeBuilder typeBuilder, string name, string mappedTo, string[] throws) + internal void SetRemappedInterfaceMethod(ITypeSymbolBuilder typeBuilder, string name, string mappedTo, string[] throws) { - var cab = new CustomAttributeBuilder(TypeOfRemappedInterfaceMethodAttribute.GetConstructor([context.Types.String, context.Types.String, context.Types.String.MakeArrayType()]).AsReflection(), [name, mappedTo, throws]); + var cab = context.Resolver.Symbols.CreateCustomAttribute(TypeOfRemappedInterfaceMethodAttribute.GetConstructor([context.Types.String, context.Types.String, context.Types.String.MakeArrayType()]), [name, mappedTo, throws]); typeBuilder.SetCustomAttribute(cab); } - internal void SetExceptionIsUnsafeForMapping(TypeBuilder typeBuilder) + internal void SetExceptionIsUnsafeForMapping(ITypeSymbolBuilder typeBuilder) { - var cab = new CustomAttributeBuilder(TypeOfExceptionIsUnsafeForMappingAttribute.GetConstructor([]).AsReflection(), Array.Empty()); + var cab = context.Resolver.Symbols.CreateCustomAttribute(TypeOfExceptionIsUnsafeForMappingAttribute.GetConstructor([]), []); typeBuilder.SetCustomAttribute(cab); } #endif - internal void SetRuntimeCompatibilityAttribute(AssemblyBuilder assemblyBuilder) + internal void SetRuntimeCompatibilityAttribute(IAssemblySymbolBuilder assemblyBuilder) { var runtimeCompatibilityAttribute = context.Resolver.ResolveCoreType(typeof(RuntimeCompatibilityAttribute).FullName); - assemblyBuilder.SetCustomAttribute(new CustomAttributeBuilder(runtimeCompatibilityAttribute.GetConstructor([]).AsReflection(), [], [runtimeCompatibilityAttribute.GetProperty("WrapNonExceptionThrows").AsReflection()], [true], [], [])); + assemblyBuilder.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(runtimeCompatibilityAttribute.GetConstructor([]), [], [runtimeCompatibilityAttribute.GetProperty("WrapNonExceptionThrows")], [true], [], [])); } - internal void SetInternalsVisibleToAttribute(AssemblyBuilder assemblyBuilder, string assemblyName) + internal void SetInternalsVisibleToAttribute(IAssemblySymbolBuilder assemblyBuilder, string assemblyName) { var internalsVisibleToAttribute = context.Resolver.ResolveCoreType(typeof(InternalsVisibleToAttribute).FullName); - var cab = new CustomAttributeBuilder(internalsVisibleToAttribute.GetConstructor([context.Types.String]).AsReflection(), [assemblyName]); + var cab = context.Resolver.Symbols.CreateCustomAttribute(internalsVisibleToAttribute.GetConstructor([context.Types.String]), [assemblyName]); assemblyBuilder.SetCustomAttribute(cab); } diff --git a/src/IKVM.Runtime/Attributes/EnclosingMethodAttribute.cs b/src/IKVM.Runtime/Attributes/EnclosingMethodAttribute.cs index 3eb72debc..39e1efa39 100644 --- a/src/IKVM.Runtime/Attributes/EnclosingMethodAttribute.cs +++ b/src/IKVM.Runtime/Attributes/EnclosingMethodAttribute.cs @@ -23,6 +23,7 @@ Jeroen Frijters */ using System; +using IKVM.CoreLib.Symbols; using IKVM.Runtime; #if IMPORTER || EXPORTER @@ -47,7 +48,7 @@ public EnclosingMethodAttribute(string className, string methodName, string meth this.methodSig = UnicodeUtil.UnescapeInvalidSurrogates(methodSig); } - internal EnclosingMethodAttribute SetClassName(RuntimeContext context, Type type) + internal EnclosingMethodAttribute SetClassName(RuntimeContext context, ITypeSymbol type) { className ??= context.ClassLoaderFactory.GetJavaTypeFromType(type.DeclaringType).Name; return this; diff --git a/src/IKVM.Runtime/BootstrapClassLoader.cs b/src/IKVM.Runtime/BootstrapClassLoader.cs index c847939de..1e9d42aeb 100644 --- a/src/IKVM.Runtime/BootstrapClassLoader.cs +++ b/src/IKVM.Runtime/BootstrapClassLoader.cs @@ -24,6 +24,8 @@ Jeroen Frijters using System; using System.Collections.Generic; +using IKVM.CoreLib.Symbols; + #if IMPORTER || EXPORTER using IKVM.Reflection; @@ -44,14 +46,14 @@ sealed class BootstrapClassLoader : RuntimeAssemblyClassLoader /// Initializes a new instance. /// internal BootstrapClassLoader(RuntimeContext context) : - base(context, context.Resolver.ResolveBaseAssembly().AsReflection(), [typeof(object).Assembly.FullName, typeof(Uri).Assembly.FullName]) + base(context, context.Resolver.ResolveBaseAssembly(), [typeof(object).Assembly.FullName, typeof(Uri).Assembly.FullName]) { #if FIRST_PASS == false && IMPORTER == false && EXPORTER == false RegisterNativeLibrary(LibJava.Instance.Handle); #endif } - internal override RuntimeJavaType GetJavaTypeFromAssemblyType(Type type) + internal override RuntimeJavaType GetJavaTypeFromAssemblyType(ITypeSymbol type) { // we have to special case the fake types here if (type.IsGenericType && !type.IsGenericTypeDefinition) diff --git a/src/IKVM.Runtime/CodeEmitter.cs b/src/IKVM.Runtime/CodeEmitter.cs index 0d17bb213..ec6406b17 100644 --- a/src/IKVM.Runtime/CodeEmitter.cs +++ b/src/IKVM.Runtime/CodeEmitter.cs @@ -28,6 +28,7 @@ Jeroen Frijters using System.Diagnostics; using IKVM.CoreLib.Symbols; +using IKVM.CoreLib.Symbols.Emit; #if IMPORTER using IKVM.Reflection; @@ -77,9 +78,9 @@ public CodeEmitterFactory(RuntimeContext context) /// /// /// - public CodeEmitter Create(MethodBuilder mb) + public CodeEmitter Create(IMethodSymbolBuilder mb) { - return new CodeEmitter(context, mb.GetILGenerator(), context.Resolver.ResolveType(mb.DeclaringType)); + return new CodeEmitter(context, mb.GetILGenerator(), context.Resolver.ResolveType(mb.Symbol.DeclaringType)); } #if IMPORTER == false @@ -103,7 +104,7 @@ sealed class CodeEmitter readonly RuntimeContext context; - ILGenerator ilgen_real; + IILGenerator ilgen_real; bool inFinally; Stack exceptionStack = new Stack(); IKVM.Attributes.LineNumberTableAttribute.LineNumberWriter linenums; @@ -148,7 +149,7 @@ struct OpCodeWrapper internal readonly CodeType pseudo; readonly CodeTypeFlags flags; - internal readonly OpCode opcode; + internal readonly System.Reflection.Emit.OpCode opcode; readonly object data; /// @@ -160,7 +161,7 @@ internal OpCodeWrapper(CodeType pseudo, object data) { this.pseudo = pseudo; this.flags = CodeTypeFlags.None; - this.opcode = OpCodes.Nop; + this.opcode = System.Reflection.Emit.OpCodes.Nop; this.data = data; } @@ -173,7 +174,7 @@ internal OpCodeWrapper(CodeType pseudo, CodeTypeFlags flags) { this.pseudo = pseudo; this.flags = flags; - this.opcode = OpCodes.Nop; + this.opcode = System.Reflection.Emit.OpCodes.Nop; this.data = null; } @@ -182,7 +183,7 @@ internal OpCodeWrapper(CodeType pseudo, CodeTypeFlags flags) /// /// /// - internal OpCodeWrapper(OpCode opcode, object data) + internal OpCodeWrapper(System.Reflection.Emit.OpCode opcode, object data) { this.pseudo = CodeType.OpCode; this.flags = CodeTypeFlags.None; @@ -290,7 +291,7 @@ internal ManagedCalliWrapper(CallingConventions callConv, ITypeSymbol returnType /// /// /// - public CodeEmitter(RuntimeContext context, ILGenerator ilgen, ITypeSymbol declaringType) + public CodeEmitter(RuntimeContext context, IILGenerator ilgen, ITypeSymbol declaringType) { this.context = context; this.ilgen_real = ilgen; @@ -307,7 +308,7 @@ private void EmitPseudoOpCode(CodeType type, object data) code.Add(new OpCodeWrapper(type, data)); } - private void EmitOpCode(OpCode opcode, object arg) + private void EmitOpCode(System.Reflection.Emit.OpCode opcode, object arg) { code.Add(new OpCodeWrapper(opcode, arg)); } @@ -336,7 +337,7 @@ private void RealEmitPseudoOpCode(int ilOffset, CodeType type, object data) ilgen_real.MarkSequencePoint(symbols, (int)data, 0, (int)data + 1, 0); #endif // we emit a nop to make sure we always have an instruction associated with the sequence point - ilgen_real.Emit(OpCodes.Nop); + ilgen_real.Emit(System.Reflection.Emit.OpCodes.Nop); break; case CodeType.Label: ilgen_real.MarkLabel(((CodeEmitterLabel)data).Label); @@ -345,7 +346,7 @@ private void RealEmitPseudoOpCode(int ilOffset, CodeType type, object data) ilgen_real.BeginExceptionBlock(); break; case CodeType.BeginCatchBlock: - ilgen_real.BeginCatchBlock(((ITypeSymbol)data).AsReflection()); + ilgen_real.BeginCatchBlock(((ITypeSymbol)data)); break; case CodeType.BeginFaultBlock: ilgen_real.BeginFaultBlock(); @@ -355,23 +356,23 @@ private void RealEmitPseudoOpCode(int ilOffset, CodeType type, object data) break; case CodeType.EndExceptionBlock: ilgen_real.EndExceptionBlock(); - ilgen_real.Emit(OpCodes.Br_S, (sbyte)-2); // bogus target of implicit leave + ilgen_real.Emit(System.Reflection.Emit.OpCodes.Br_S, (sbyte)-2); // bogus target of implicit leave break; case CodeType.MemoryBarrier: - ilgen_real.Emit(OpCodes.Call, context.CodeEmitterFactory.MemoryBarrierMethod.AsReflection()); + ilgen_real.Emit(System.Reflection.Emit.OpCodes.Call, context.CodeEmitterFactory.MemoryBarrierMethod); break; case CodeType.MonitorEnter: - ilgen_real.Emit(OpCodes.Call, context.CodeEmitterFactory.MonitorEnterMethod.AsReflection()); + ilgen_real.Emit(System.Reflection.Emit.OpCodes.Call, context.CodeEmitterFactory.MonitorEnterMethod); break; case CodeType.MonitorExit: - ilgen_real.Emit(OpCodes.Call, context.CodeEmitterFactory.MonitorExitMethod.AsReflection()); + ilgen_real.Emit(System.Reflection.Emit.OpCodes.Call, context.CodeEmitterFactory.MonitorExitMethod); break; case CodeType.TailCallPrevention: - ilgen_real.Emit(OpCodes.Ldnull); - ilgen_real.Emit(OpCodes.Pop); + ilgen_real.Emit(System.Reflection.Emit.OpCodes.Ldnull); + ilgen_real.Emit(System.Reflection.Emit.OpCodes.Pop); break; case CodeType.ClearStack: - ilgen_real.Emit(OpCodes.Leave_S, (byte)0); + ilgen_real.Emit(System.Reflection.Emit.OpCodes.Leave_S, (byte)0); break; default: throw new InvalidOperationException(); @@ -379,12 +380,12 @@ private void RealEmitPseudoOpCode(int ilOffset, CodeType type, object data) } /// - /// Emits the real OpCode into the underlying IL generator. + /// Emits the real System.Reflection.Emit.OpCode into the underlying IL generator. /// /// /// /// - void RealEmitOpCode(OpCode opcode, object arg) + void RealEmitOpCode(System.Reflection.Emit.OpCode opcode, object arg) { if (arg == null) { @@ -400,15 +401,15 @@ void RealEmitOpCode(OpCode opcode, object arg) } else if (arg is IMethodSymbol mi) { - ilgen_real.Emit(opcode, mi.AsReflection()); + ilgen_real.Emit(opcode, mi); } else if (arg is IConstructorSymbol ci) { - ilgen_real.Emit(opcode, ci.AsReflection()); + ilgen_real.Emit(opcode, ci); } else if (arg is IFieldSymbol fi) { - ilgen_real.Emit(opcode, fi.AsReflection()); + ilgen_real.Emit(opcode, fi); } else if (arg is sbyte sby) { @@ -436,7 +437,7 @@ void RealEmitOpCode(OpCode opcode, object arg) } else if (arg is ITypeSymbol type) { - ilgen_real.Emit(opcode, type.AsReflection()); + ilgen_real.Emit(opcode, type); } else if (arg is CodeEmitterLocal local) { @@ -448,7 +449,7 @@ void RealEmitOpCode(OpCode opcode, object arg) } else if (arg is CodeEmitterLabel[] labels) { - var real = new Label[labels.Length]; + var real = new ILabel[labels.Length]; for (int i = 0; i < labels.Length; i++) real[i] = labels[i].Label; @@ -456,11 +457,11 @@ void RealEmitOpCode(OpCode opcode, object arg) } else if (arg is ManagedCalliWrapper margs) { - ilgen_real.EmitCalli(opcode, margs.callConv, margs.returnType.AsReflection(), margs.parameterTypes.AsReflection(), margs.optionalParameterTypes.AsReflection()); + ilgen_real.EmitCalli(opcode, margs.callConv, margs.returnType, margs.parameterTypes, margs.optionalParameterTypes); } else if (arg is CalliWrapper args) { - ilgen_real.EmitCalli(opcode, args.unmanagedCallConv, args.returnType.AsReflection(), args.parameterTypes.AsReflection()); + ilgen_real.EmitCalli(opcode, args.unmanagedCallConv, args.returnType, args.parameterTypes); } else { @@ -474,7 +475,7 @@ void RemoveJumpNext() { if (code[i].pseudo == CodeType.Label) { - if (code[i - 1].opcode == OpCodes.Br + if (code[i - 1].opcode == System.Reflection.Emit.OpCodes.Br && code[i - 1].MatchLabel(code[i])) { code.RemoveAt(i - 1); @@ -482,7 +483,7 @@ void RemoveJumpNext() } else if (i >= 2 && code[i - 1].pseudo == CodeType.LineNumber - && code[i - 2].opcode == OpCodes.Br + && code[i - 2].opcode == System.Reflection.Emit.OpCodes.Br && code[i - 2].MatchLabel(code[i])) { code.RemoveAt(i - 2); @@ -496,13 +497,13 @@ void AnnihilateStoreReleaseTempLocals() { for (int i = 1; i < code.Count; i++) { - if (code[i].opcode == OpCodes.Stloc) + if (code[i].opcode == System.Reflection.Emit.OpCodes.Stloc) { if (code[i + 1].pseudo == CodeType.ReleaseTempLocal && code[i].Local == code[i + 1].Local) { - code[i] = new OpCodeWrapper(OpCodes.Pop, null); + code[i] = new OpCodeWrapper(System.Reflection.Emit.OpCodes.Pop, null); } - else if (code[i + 1].opcode == OpCodes.Ldloc && code[i + 1].Local == code[i].Local && code[i + 2].pseudo == CodeType.ReleaseTempLocal && code[i + 2].Local == code[i].Local) + else if (code[i + 1].opcode == System.Reflection.Emit.OpCodes.Ldloc && code[i + 1].Local == code[i].Local && code[i + 2].pseudo == CodeType.ReleaseTempLocal && code[i + 2].Local == code[i].Local) { code.RemoveRange(i, 2); } @@ -514,7 +515,7 @@ void AnnihilatePops() { for (int i = 1; i < code.Count; i++) { - if (code[i].opcode == OpCodes.Pop) + if (code[i].opcode == System.Reflection.Emit.OpCodes.Pop) { // search backwards for a candidate push to annihilate int stack = 0; @@ -531,20 +532,20 @@ void AnnihilatePops() } stack++; } - else if (code[j].opcode == OpCodes.Stloc) + else if (code[j].opcode == System.Reflection.Emit.OpCodes.Stloc) { stack--; } - else if (code[j].opcode == OpCodes.Shl || code[j].opcode == OpCodes.And || code[j].opcode == OpCodes.Add || code[j].opcode == OpCodes.Sub) + else if (code[j].opcode == System.Reflection.Emit.OpCodes.Shl || code[j].opcode == System.Reflection.Emit.OpCodes.And || code[j].opcode == System.Reflection.Emit.OpCodes.Add || code[j].opcode == System.Reflection.Emit.OpCodes.Sub) { if (stack == 0) break; stack--; } - else if (code[j].opcode == OpCodes.Conv_Ovf_I4 - || code[j].opcode == OpCodes.Conv_I8 - || code[j].opcode == OpCodes.Ldlen) + else if (code[j].opcode == System.Reflection.Emit.OpCodes.Conv_Ovf_I4 + || code[j].opcode == System.Reflection.Emit.OpCodes.Conv_I8 + || code[j].opcode == System.Reflection.Emit.OpCodes.Ldlen) { if (stack == 0) { @@ -568,15 +569,15 @@ void AnnihilatePops() /// bool IsSideEffectFreePush(int index) { - if (code[index].opcode == OpCodes.Ldstr) + if (code[index].opcode == System.Reflection.Emit.OpCodes.Ldstr) { return true; } - else if (code[index].opcode == OpCodes.Ldnull) + else if (code[index].opcode == System.Reflection.Emit.OpCodes.Ldnull) { return true; } - else if (code[index].opcode == OpCodes.Ldsfld) + else if (code[index].opcode == System.Reflection.Emit.OpCodes.Ldsfld) { var field = code[index].FieldInfo; if (field != null) @@ -598,47 +599,47 @@ bool IsSideEffectFreePush(int index) } return false; } - else if (code[index].opcode == OpCodes.Ldc_I4) + else if (code[index].opcode == System.Reflection.Emit.OpCodes.Ldc_I4) { return true; } - else if (code[index].opcode == OpCodes.Ldc_I8) + else if (code[index].opcode == System.Reflection.Emit.OpCodes.Ldc_I8) { return true; } - else if (code[index].opcode == OpCodes.Ldc_R4) + else if (code[index].opcode == System.Reflection.Emit.OpCodes.Ldc_R4) { return true; } - else if (code[index].opcode == OpCodes.Ldc_R8) + else if (code[index].opcode == System.Reflection.Emit.OpCodes.Ldc_R8) { return true; } - else if (code[index].opcode == OpCodes.Ldloc) + else if (code[index].opcode == System.Reflection.Emit.OpCodes.Ldloc) { return true; } - else if (code[index].opcode == OpCodes.Ldarg) + else if (code[index].opcode == System.Reflection.Emit.OpCodes.Ldarg) { return true; } - else if (code[index].opcode == OpCodes.Ldarg_S) + else if (code[index].opcode == System.Reflection.Emit.OpCodes.Ldarg_S) { return true; } - else if (code[index].opcode == OpCodes.Ldarg_0) + else if (code[index].opcode == System.Reflection.Emit.OpCodes.Ldarg_0) { return true; } - else if (code[index].opcode == OpCodes.Ldarg_1) + else if (code[index].opcode == System.Reflection.Emit.OpCodes.Ldarg_1) { return true; } - else if (code[index].opcode == OpCodes.Ldarg_2) + else if (code[index].opcode == System.Reflection.Emit.OpCodes.Ldarg_2) { return true; } - else if (code[index].opcode == OpCodes.Ldarg_3) + else if (code[index].opcode == System.Reflection.Emit.OpCodes.Ldarg_3) { return true; } @@ -653,59 +654,59 @@ void OptimizePatterns() SetLabelRefCounts(); for (int i = 1; i < code.Count; i++) { - if (code[i].opcode == OpCodes.Isinst - && code[i + 1].opcode == OpCodes.Ldnull - && code[i + 2].opcode == OpCodes.Cgt_Un - && (code[i + 3].opcode == OpCodes.Brfalse || code[i + 3].opcode == OpCodes.Brtrue)) + if (code[i].opcode == System.Reflection.Emit.OpCodes.Isinst + && code[i + 1].opcode == System.Reflection.Emit.OpCodes.Ldnull + && code[i + 2].opcode == System.Reflection.Emit.OpCodes.Cgt_Un + && (code[i + 3].opcode == System.Reflection.Emit.OpCodes.Brfalse || code[i + 3].opcode == System.Reflection.Emit.OpCodes.Brtrue)) { code.RemoveRange(i + 1, 2); } - else if (code[i].opcode == OpCodes.Ldelem_I1 - && code[i + 1].opcode == OpCodes.Ldc_I4 && code[i + 1].ValueInt32 == 255 - && code[i + 2].opcode == OpCodes.And) + else if (code[i].opcode == System.Reflection.Emit.OpCodes.Ldelem_I1 + && code[i + 1].opcode == System.Reflection.Emit.OpCodes.Ldc_I4 && code[i + 1].ValueInt32 == 255 + && code[i + 2].opcode == System.Reflection.Emit.OpCodes.And) { - code[i] = new OpCodeWrapper(OpCodes.Ldelem_U1, null); + code[i] = new OpCodeWrapper(System.Reflection.Emit.OpCodes.Ldelem_U1, null); code.RemoveRange(i + 1, 2); } - else if (code[i].opcode == OpCodes.Ldelem_I1 - && code[i + 1].opcode == OpCodes.Conv_I8 - && code[i + 2].opcode == OpCodes.Ldc_I8 && code[i + 2].ValueInt64 == 255 - && code[i + 3].opcode == OpCodes.And) + else if (code[i].opcode == System.Reflection.Emit.OpCodes.Ldelem_I1 + && code[i + 1].opcode == System.Reflection.Emit.OpCodes.Conv_I8 + && code[i + 2].opcode == System.Reflection.Emit.OpCodes.Ldc_I8 && code[i + 2].ValueInt64 == 255 + && code[i + 3].opcode == System.Reflection.Emit.OpCodes.And) { - code[i] = new OpCodeWrapper(OpCodes.Ldelem_U1, null); + code[i] = new OpCodeWrapper(System.Reflection.Emit.OpCodes.Ldelem_U1, null); code.RemoveRange(i + 2, 2); } - else if (code[i].opcode == OpCodes.Ldc_I4 - && code[i + 1].opcode == OpCodes.Ldc_I4 - && code[i + 2].opcode == OpCodes.And) + else if (code[i].opcode == System.Reflection.Emit.OpCodes.Ldc_I4 + && code[i + 1].opcode == System.Reflection.Emit.OpCodes.Ldc_I4 + && code[i + 2].opcode == System.Reflection.Emit.OpCodes.And) { - code[i] = new OpCodeWrapper(OpCodes.Ldc_I4, code[i].ValueInt32 & code[i + 1].ValueInt32); + code[i] = new OpCodeWrapper(System.Reflection.Emit.OpCodes.Ldc_I4, code[i].ValueInt32 & code[i + 1].ValueInt32); code.RemoveRange(i + 1, 2); } - else if (MatchCompare(i, OpCodes.Cgt, OpCodes.Clt_Un, context.Types.Double) // dcmpl - || MatchCompare(i, OpCodes.Cgt, OpCodes.Clt_Un, context.Types.Single)) // fcmpl + else if (MatchCompare(i, System.Reflection.Emit.OpCodes.Cgt, System.Reflection.Emit.OpCodes.Clt_Un, context.Types.Double) // dcmpl + || MatchCompare(i, System.Reflection.Emit.OpCodes.Cgt, System.Reflection.Emit.OpCodes.Clt_Un, context.Types.Single)) // fcmpl { - PatchCompare(i, OpCodes.Ble_Un, OpCodes.Blt_Un, OpCodes.Bge, OpCodes.Bgt); + PatchCompare(i, System.Reflection.Emit.OpCodes.Ble_Un, System.Reflection.Emit.OpCodes.Blt_Un, System.Reflection.Emit.OpCodes.Bge, System.Reflection.Emit.OpCodes.Bgt); } - else if (MatchCompare(i, OpCodes.Cgt_Un, OpCodes.Clt, context.Types.Double) // dcmpg - || MatchCompare(i, OpCodes.Cgt_Un, OpCodes.Clt, context.Types.Single)) // fcmpg + else if (MatchCompare(i, System.Reflection.Emit.OpCodes.Cgt_Un, System.Reflection.Emit.OpCodes.Clt, context.Types.Double) // dcmpg + || MatchCompare(i, System.Reflection.Emit.OpCodes.Cgt_Un, System.Reflection.Emit.OpCodes.Clt, context.Types.Single)) // fcmpg { - PatchCompare(i, OpCodes.Ble, OpCodes.Blt, OpCodes.Bge_Un, OpCodes.Bgt_Un); + PatchCompare(i, System.Reflection.Emit.OpCodes.Ble, System.Reflection.Emit.OpCodes.Blt, System.Reflection.Emit.OpCodes.Bge_Un, System.Reflection.Emit.OpCodes.Bgt_Un); } - else if (MatchCompare(i, OpCodes.Cgt, OpCodes.Clt, context.Types.Int64)) // lcmp + else if (MatchCompare(i, System.Reflection.Emit.OpCodes.Cgt, System.Reflection.Emit.OpCodes.Clt, context.Types.Int64)) // lcmp { - PatchCompare(i, OpCodes.Ble, OpCodes.Blt, OpCodes.Bge, OpCodes.Bgt); + PatchCompare(i, System.Reflection.Emit.OpCodes.Ble, System.Reflection.Emit.OpCodes.Blt, System.Reflection.Emit.OpCodes.Bge, System.Reflection.Emit.OpCodes.Bgt); } else if (i < code.Count - 10 - && code[i].opcode == OpCodes.Ldc_I4 - && code[i + 1].opcode == OpCodes.Dup - && code[i + 2].opcode == OpCodes.Ldc_I4_M1 - && code[i + 3].opcode == OpCodes.Bne_Un - && code[i + 4].opcode == OpCodes.Pop - && code[i + 5].opcode == OpCodes.Neg - && code[i + 6].opcode == OpCodes.Br + && code[i].opcode == System.Reflection.Emit.OpCodes.Ldc_I4 + && code[i + 1].opcode == System.Reflection.Emit.OpCodes.Dup + && code[i + 2].opcode == System.Reflection.Emit.OpCodes.Ldc_I4_M1 + && code[i + 3].opcode == System.Reflection.Emit.OpCodes.Bne_Un + && code[i + 4].opcode == System.Reflection.Emit.OpCodes.Pop + && code[i + 5].opcode == System.Reflection.Emit.OpCodes.Neg + && code[i + 6].opcode == System.Reflection.Emit.OpCodes.Br && code[i + 7].pseudo == CodeType.Label && code[i + 7].MatchLabel(code[i + 3]) && code[i + 7].Label.Temp == 1 - && code[i + 8].opcode == OpCodes.Div + && code[i + 8].opcode == System.Reflection.Emit.OpCodes.Div && code[i + 9].pseudo == CodeType.Label && code[i + 9].Label == code[i + 6].Label && code[i + 9].Label.Temp == 1) { int divisor = code[i].ValueInt32; @@ -721,16 +722,16 @@ void OptimizePatterns() } } else if (i < code.Count - 11 - && code[i].opcode == OpCodes.Ldc_I8 - && code[i + 1].opcode == OpCodes.Dup - && code[i + 2].opcode == OpCodes.Ldc_I4_M1 - && code[i + 3].opcode == OpCodes.Conv_I8 - && code[i + 4].opcode == OpCodes.Bne_Un - && code[i + 5].opcode == OpCodes.Pop - && code[i + 6].opcode == OpCodes.Neg - && code[i + 7].opcode == OpCodes.Br + && code[i].opcode == System.Reflection.Emit.OpCodes.Ldc_I8 + && code[i + 1].opcode == System.Reflection.Emit.OpCodes.Dup + && code[i + 2].opcode == System.Reflection.Emit.OpCodes.Ldc_I4_M1 + && code[i + 3].opcode == System.Reflection.Emit.OpCodes.Conv_I8 + && code[i + 4].opcode == System.Reflection.Emit.OpCodes.Bne_Un + && code[i + 5].opcode == System.Reflection.Emit.OpCodes.Pop + && code[i + 6].opcode == System.Reflection.Emit.OpCodes.Neg + && code[i + 7].opcode == System.Reflection.Emit.OpCodes.Br && code[i + 8].pseudo == CodeType.Label && code[i + 8].MatchLabel(code[i + 4]) && code[i + 8].Label.Temp == 1 - && code[i + 9].opcode == OpCodes.Div + && code[i + 9].opcode == System.Reflection.Emit.OpCodes.Div && code[i + 10].pseudo == CodeType.Label && code[i + 10].MatchLabel(code[i + 7]) && code[i + 10].Label.Temp == 1) { long divisor = code[i].ValueInt64; @@ -745,26 +746,26 @@ void OptimizePatterns() code.RemoveRange(i + 2, 9); } } - else if (code[i].opcode == OpCodes.Box - && code[i + 1].opcode == OpCodes.Unbox && code[i + 1].Type == code[i].Type) + else if (code[i].opcode == System.Reflection.Emit.OpCodes.Box + && code[i + 1].opcode == System.Reflection.Emit.OpCodes.Unbox && code[i + 1].Type == code[i].Type) { CodeEmitterLocal local = new CodeEmitterLocal(code[i].Type); - code[i] = new OpCodeWrapper(OpCodes.Stloc, local); - code[i + 1] = new OpCodeWrapper(OpCodes.Ldloca, local); + code[i] = new OpCodeWrapper(System.Reflection.Emit.OpCodes.Stloc, local); + code[i + 1] = new OpCodeWrapper(System.Reflection.Emit.OpCodes.Ldloca, local); } else if (i < code.Count - 13 - && code[i + 0].opcode == OpCodes.Box - && code[i + 1].opcode == OpCodes.Dup - && code[i + 2].opcode == OpCodes.Brtrue - && code[i + 3].opcode == OpCodes.Pop - && code[i + 4].opcode == OpCodes.Ldloca && code[i + 4].Local.LocalType == code[i + 0].Type - && code[i + 5].opcode == OpCodes.Initobj && code[i + 5].Type == code[i + 0].Type - && code[i + 6].opcode == OpCodes.Ldloc && code[i + 6].Local == code[i + 4].Local + && code[i + 0].opcode == System.Reflection.Emit.OpCodes.Box + && code[i + 1].opcode == System.Reflection.Emit.OpCodes.Dup + && code[i + 2].opcode == System.Reflection.Emit.OpCodes.Brtrue + && code[i + 3].opcode == System.Reflection.Emit.OpCodes.Pop + && code[i + 4].opcode == System.Reflection.Emit.OpCodes.Ldloca && code[i + 4].Local.LocalType == code[i + 0].Type + && code[i + 5].opcode == System.Reflection.Emit.OpCodes.Initobj && code[i + 5].Type == code[i + 0].Type + && code[i + 6].opcode == System.Reflection.Emit.OpCodes.Ldloc && code[i + 6].Local == code[i + 4].Local && code[i + 7].pseudo == CodeType.ReleaseTempLocal && code[i + 7].Local == code[i + 6].Local - && code[i + 8].opcode == OpCodes.Br + && code[i + 8].opcode == System.Reflection.Emit.OpCodes.Br && code[i + 9].pseudo == CodeType.Label && code[i + 9].MatchLabel(code[i + 2]) && code[i + 9].Label.Temp == 1 - && code[i + 10].opcode == OpCodes.Unbox && code[i + 10].Type == code[i + 0].Type - && code[i + 11].opcode == OpCodes.Ldobj && code[i + 11].Type == code[i + 0].Type + && code[i + 10].opcode == System.Reflection.Emit.OpCodes.Unbox && code[i + 10].Type == code[i + 0].Type + && code[i + 11].opcode == System.Reflection.Emit.OpCodes.Ldobj && code[i + 11].Type == code[i + 0].Type && code[i + 12].pseudo == CodeType.Label && code[i + 12].MatchLabel(code[i + 8]) && code[i + 12].Label.Temp == 1) { code.RemoveRange(i, 13); @@ -773,114 +774,114 @@ void OptimizePatterns() // NOTE intentionally not an else, because we want to optimize the code generated by the earlier compare optimization if (i < code.Count - 6 && code[i].opcode.FlowControl == FlowControl.Cond_Branch - && code[i + 1].opcode == OpCodes.Ldc_I4 && code[i + 1].ValueInt32 == 1 - && code[i + 2].opcode == OpCodes.Br + && code[i + 1].opcode == System.Reflection.Emit.OpCodes.Ldc_I4 && code[i + 1].ValueInt32 == 1 + && code[i + 2].opcode == System.Reflection.Emit.OpCodes.Br && code[i + 3].pseudo == CodeType.Label && code[i + 3].MatchLabel(code[i]) && code[i + 3].Label.Temp == 1 - && code[i + 4].opcode == OpCodes.Ldc_I4 && code[i + 4].ValueInt32 == 0 + && code[i + 4].opcode == System.Reflection.Emit.OpCodes.Ldc_I4 && code[i + 4].ValueInt32 == 0 && code[i + 5].pseudo == CodeType.Label && code[i + 5].MatchLabel(code[i + 2]) && code[i + 5].Label.Temp == 1) { - if (code[i].opcode == OpCodes.Bne_Un) + if (code[i].opcode == System.Reflection.Emit.OpCodes.Bne_Un) { - code[i] = new OpCodeWrapper(OpCodes.Ceq, null); + code[i] = new OpCodeWrapper(System.Reflection.Emit.OpCodes.Ceq, null); code.RemoveRange(i + 1, 5); } - else if (code[i].opcode == OpCodes.Beq) + else if (code[i].opcode == System.Reflection.Emit.OpCodes.Beq) { - code[i + 0] = new OpCodeWrapper(OpCodes.Ceq, null); - code[i + 1] = new OpCodeWrapper(OpCodes.Ldc_I4, 0); - code[i + 2] = new OpCodeWrapper(OpCodes.Ceq, null); + code[i + 0] = new OpCodeWrapper(System.Reflection.Emit.OpCodes.Ceq, null); + code[i + 1] = new OpCodeWrapper(System.Reflection.Emit.OpCodes.Ldc_I4, 0); + code[i + 2] = new OpCodeWrapper(System.Reflection.Emit.OpCodes.Ceq, null); code.RemoveRange(i + 3, 3); } - else if (code[i].opcode == OpCodes.Ble || code[i].opcode == OpCodes.Ble_Un) + else if (code[i].opcode == System.Reflection.Emit.OpCodes.Ble || code[i].opcode == System.Reflection.Emit.OpCodes.Ble_Un) { - code[i] = new OpCodeWrapper(OpCodes.Cgt, null); + code[i] = new OpCodeWrapper(System.Reflection.Emit.OpCodes.Cgt, null); code.RemoveRange(i + 1, 5); } - else if (code[i].opcode == OpCodes.Blt) + else if (code[i].opcode == System.Reflection.Emit.OpCodes.Blt) { - code[i] = new OpCodeWrapper(OpCodes.Clt, null); - code[i + 1] = new OpCodeWrapper(OpCodes.Ldc_I4, 0); - code[i + 2] = new OpCodeWrapper(OpCodes.Ceq, null); + code[i] = new OpCodeWrapper(System.Reflection.Emit.OpCodes.Clt, null); + code[i + 1] = new OpCodeWrapper(System.Reflection.Emit.OpCodes.Ldc_I4, 0); + code[i + 2] = new OpCodeWrapper(System.Reflection.Emit.OpCodes.Ceq, null); code.RemoveRange(i + 3, 3); } - else if (code[i].opcode == OpCodes.Blt_Un) + else if (code[i].opcode == System.Reflection.Emit.OpCodes.Blt_Un) { - code[i] = new OpCodeWrapper(OpCodes.Clt_Un, null); - code[i + 1] = new OpCodeWrapper(OpCodes.Ldc_I4, 0); - code[i + 2] = new OpCodeWrapper(OpCodes.Ceq, null); + code[i] = new OpCodeWrapper(System.Reflection.Emit.OpCodes.Clt_Un, null); + code[i + 1] = new OpCodeWrapper(System.Reflection.Emit.OpCodes.Ldc_I4, 0); + code[i + 2] = new OpCodeWrapper(System.Reflection.Emit.OpCodes.Ceq, null); code.RemoveRange(i + 3, 3); } - else if (code[i].opcode == OpCodes.Bge || code[i].opcode == OpCodes.Bge_Un) + else if (code[i].opcode == System.Reflection.Emit.OpCodes.Bge || code[i].opcode == System.Reflection.Emit.OpCodes.Bge_Un) { - code[i] = new OpCodeWrapper(OpCodes.Clt, null); + code[i] = new OpCodeWrapper(System.Reflection.Emit.OpCodes.Clt, null); code.RemoveRange(i + 1, 5); } - else if (code[i].opcode == OpCodes.Bgt) + else if (code[i].opcode == System.Reflection.Emit.OpCodes.Bgt) { - code[i] = new OpCodeWrapper(OpCodes.Cgt, null); - code[i + 1] = new OpCodeWrapper(OpCodes.Ldc_I4, 0); - code[i + 2] = new OpCodeWrapper(OpCodes.Ceq, null); + code[i] = new OpCodeWrapper(System.Reflection.Emit.OpCodes.Cgt, null); + code[i + 1] = new OpCodeWrapper(System.Reflection.Emit.OpCodes.Ldc_I4, 0); + code[i + 2] = new OpCodeWrapper(System.Reflection.Emit.OpCodes.Ceq, null); code.RemoveRange(i + 3, 3); } - else if (code[i].opcode == OpCodes.Bgt_Un) + else if (code[i].opcode == System.Reflection.Emit.OpCodes.Bgt_Un) { - code[i] = new OpCodeWrapper(OpCodes.Cgt_Un, null); - code[i + 1] = new OpCodeWrapper(OpCodes.Ldc_I4, 0); - code[i + 2] = new OpCodeWrapper(OpCodes.Ceq, null); + code[i] = new OpCodeWrapper(System.Reflection.Emit.OpCodes.Cgt_Un, null); + code[i + 1] = new OpCodeWrapper(System.Reflection.Emit.OpCodes.Ldc_I4, 0); + code[i + 2] = new OpCodeWrapper(System.Reflection.Emit.OpCodes.Ceq, null); code.RemoveRange(i + 3, 3); } } } } - bool MatchCompare(int index, OpCode cmp1, OpCode cmp2, ITypeSymbol type) + bool MatchCompare(int index, System.Reflection.Emit.OpCode cmp1, System.Reflection.Emit.OpCode cmp2, ITypeSymbol type) { - return code[index].opcode == OpCodes.Stloc && code[index].Local.LocalType == type - && code[index + 1].opcode == OpCodes.Stloc && code[index + 1].Local.LocalType == type - && code[index + 2].opcode == OpCodes.Ldloc && code[index + 2].MatchLocal(code[index + 1]) - && code[index + 3].opcode == OpCodes.Ldloc && code[index + 3].MatchLocal(code[index]) + return code[index].opcode == System.Reflection.Emit.OpCodes.Stloc && code[index].Local.LocalType == type + && code[index + 1].opcode == System.Reflection.Emit.OpCodes.Stloc && code[index + 1].Local.LocalType == type + && code[index + 2].opcode == System.Reflection.Emit.OpCodes.Ldloc && code[index + 2].MatchLocal(code[index + 1]) + && code[index + 3].opcode == System.Reflection.Emit.OpCodes.Ldloc && code[index + 3].MatchLocal(code[index]) && code[index + 4].opcode == cmp1 - && code[index + 5].opcode == OpCodes.Ldloc && code[index + 5].MatchLocal(code[index + 1]) - && code[index + 6].opcode == OpCodes.Ldloc && code[index + 6].MatchLocal(code[index]) + && code[index + 5].opcode == System.Reflection.Emit.OpCodes.Ldloc && code[index + 5].MatchLocal(code[index + 1]) + && code[index + 6].opcode == System.Reflection.Emit.OpCodes.Ldloc && code[index + 6].MatchLocal(code[index]) && code[index + 7].opcode == cmp2 - && code[index + 8].opcode == OpCodes.Sub + && code[index + 8].opcode == System.Reflection.Emit.OpCodes.Sub && code[index + 9].pseudo == CodeType.ReleaseTempLocal && code[index + 9].Local == code[index].Local && code[index + 10].pseudo == CodeType.ReleaseTempLocal && code[index + 10].Local == code[index + 1].Local && ((code[index + 11].opcode.FlowControl == FlowControl.Cond_Branch && code[index + 11].HasLabel) || - (code[index + 11].opcode == OpCodes.Ldc_I4_0 + (code[index + 11].opcode == System.Reflection.Emit.OpCodes.Ldc_I4_0 && (code[index + 12].opcode.FlowControl == FlowControl.Cond_Branch && code[index + 12].HasLabel))); } - void PatchCompare(int index, OpCode ble, OpCode blt, OpCode bge, OpCode bgt) + void PatchCompare(int index, System.Reflection.Emit.OpCode ble, System.Reflection.Emit.OpCode blt, System.Reflection.Emit.OpCode bge, System.Reflection.Emit.OpCode bgt) { - if (code[index + 11].opcode == OpCodes.Brtrue) + if (code[index + 11].opcode == System.Reflection.Emit.OpCodes.Brtrue) { - code[index] = new OpCodeWrapper(OpCodes.Bne_Un, code[index + 11].Label); + code[index] = new OpCodeWrapper(System.Reflection.Emit.OpCodes.Bne_Un, code[index + 11].Label); code.RemoveRange(index + 1, 11); } - else if (code[index + 11].opcode == OpCodes.Brfalse) + else if (code[index + 11].opcode == System.Reflection.Emit.OpCodes.Brfalse) { - code[index] = new OpCodeWrapper(OpCodes.Beq, code[index + 11].Label); + code[index] = new OpCodeWrapper(System.Reflection.Emit.OpCodes.Beq, code[index + 11].Label); code.RemoveRange(index + 1, 11); } - else if (code[index + 11].opcode == OpCodes.Ldc_I4_0) + else if (code[index + 11].opcode == System.Reflection.Emit.OpCodes.Ldc_I4_0) { - if (code[index + 12].opcode == OpCodes.Ble) + if (code[index + 12].opcode == System.Reflection.Emit.OpCodes.Ble) { code[index] = new OpCodeWrapper(ble, code[index + 12].Label); code.RemoveRange(index + 1, 12); } - else if (code[index + 12].opcode == OpCodes.Blt) + else if (code[index + 12].opcode == System.Reflection.Emit.OpCodes.Blt) { code[index] = new OpCodeWrapper(blt, code[index + 12].Label); code.RemoveRange(index + 1, 12); } - else if (code[index + 12].opcode == OpCodes.Bge) + else if (code[index + 12].opcode == System.Reflection.Emit.OpCodes.Bge) { code[index] = new OpCodeWrapper(bge, code[index + 12].Label); code.RemoveRange(index + 1, 12); } - else if (code[index + 12].opcode == OpCodes.Bgt) + else if (code[index + 12].opcode == System.Reflection.Emit.OpCodes.Bgt) { code[index] = new OpCodeWrapper(bgt, code[index + 12].Label); code.RemoveRange(index + 1, 12); @@ -895,9 +896,9 @@ void OptimizeEncodings() { for (int i = 0; i < code.Count; i++) { - if (code[i].opcode == OpCodes.Ldc_I4) + if (code[i].opcode == System.Reflection.Emit.OpCodes.Ldc_I4) code[i] = OptimizeLdcI4(code[i].ValueInt32); - else if (code[i].opcode == OpCodes.Ldc_I8) + else if (code[i].opcode == System.Reflection.Emit.OpCodes.Ldc_I8) OptimizeLdcI8(i); } } @@ -912,30 +913,30 @@ OpCodeWrapper OptimizeLdcI4(int value) switch (value) { case -1: - return new OpCodeWrapper(OpCodes.Ldc_I4_M1, null); + return new OpCodeWrapper(System.Reflection.Emit.OpCodes.Ldc_I4_M1, null); case 0: - return new OpCodeWrapper(OpCodes.Ldc_I4_0, null); + return new OpCodeWrapper(System.Reflection.Emit.OpCodes.Ldc_I4_0, null); case 1: - return new OpCodeWrapper(OpCodes.Ldc_I4_1, null); + return new OpCodeWrapper(System.Reflection.Emit.OpCodes.Ldc_I4_1, null); case 2: - return new OpCodeWrapper(OpCodes.Ldc_I4_2, null); + return new OpCodeWrapper(System.Reflection.Emit.OpCodes.Ldc_I4_2, null); case 3: - return new OpCodeWrapper(OpCodes.Ldc_I4_3, null); + return new OpCodeWrapper(System.Reflection.Emit.OpCodes.Ldc_I4_3, null); case 4: - return new OpCodeWrapper(OpCodes.Ldc_I4_4, null); + return new OpCodeWrapper(System.Reflection.Emit.OpCodes.Ldc_I4_4, null); case 5: - return new OpCodeWrapper(OpCodes.Ldc_I4_5, null); + return new OpCodeWrapper(System.Reflection.Emit.OpCodes.Ldc_I4_5, null); case 6: - return new OpCodeWrapper(OpCodes.Ldc_I4_6, null); + return new OpCodeWrapper(System.Reflection.Emit.OpCodes.Ldc_I4_6, null); case 7: - return new OpCodeWrapper(OpCodes.Ldc_I4_7, null); + return new OpCodeWrapper(System.Reflection.Emit.OpCodes.Ldc_I4_7, null); case 8: - return new OpCodeWrapper(OpCodes.Ldc_I4_8, null); + return new OpCodeWrapper(System.Reflection.Emit.OpCodes.Ldc_I4_8, null); default: if (value >= -128 && value <= 127) - return new OpCodeWrapper(OpCodes.Ldc_I4_S, (sbyte)value); + return new OpCodeWrapper(System.Reflection.Emit.OpCodes.Ldc_I4_S, (sbyte)value); else - return new OpCodeWrapper(OpCodes.Ldc_I4, value); + return new OpCodeWrapper(System.Reflection.Emit.OpCodes.Ldc_I4, value); } } @@ -949,7 +950,7 @@ void OptimizeLdcI8(int index) if (value >= int.MinValue && value <= uint.MaxValue) { code[index] = OptimizeLdcI4((int)value); - code.Insert(index + 1, new OpCodeWrapper(value < 0 ? OpCodes.Conv_I8 : OpCodes.Conv_U8, null)); + code.Insert(index + 1, new OpCodeWrapper(value < 0 ? System.Reflection.Emit.OpCodes.Conv_I8 : System.Reflection.Emit.OpCodes.Conv_U8, null)); } } @@ -965,7 +966,7 @@ private void ChaseBranches() SetLabelIndexes(); for (int i = 0; i < code.Count; i++) { - if (code[i].opcode == OpCodes.Br) + if (code[i].opcode == System.Reflection.Emit.OpCodes.Br) { int target = code[i].Label.Temp + 1; if (code[target].pseudo == CodeType.LineNumber) @@ -973,36 +974,36 @@ private void ChaseBranches() // line number info on endfinally or ret is probably useless anyway target++; } - if (code[target].opcode == OpCodes.Endfinally || code[target].opcode == OpCodes.Ret) + if (code[target].opcode == System.Reflection.Emit.OpCodes.Endfinally || code[target].opcode == System.Reflection.Emit.OpCodes.Ret) { code[i] = code[target]; } else { CodeEmitterLabel label = null; - while (code[target].opcode == OpCodes.Br && target != i) + while (code[target].opcode == System.Reflection.Emit.OpCodes.Br && target != i) { label = code[target].Label; target = code[target].Label.Temp + 1; } if (label != null) { - code[i] = new OpCodeWrapper(OpCodes.Br, label); + code[i] = new OpCodeWrapper(System.Reflection.Emit.OpCodes.Br, label); } } } - else if (code[i].opcode == OpCodes.Leave) + else if (code[i].opcode == System.Reflection.Emit.OpCodes.Leave) { int target = code[i].Label.Temp + 1; CodeEmitterLabel label = null; - while ((code[target].opcode == OpCodes.Br || code[target].opcode == OpCodes.Leave) && target != i) + while ((code[target].opcode == System.Reflection.Emit.OpCodes.Br || code[target].opcode == System.Reflection.Emit.OpCodes.Leave) && target != i) { label = code[target].Label; target = code[target].Label.Temp + 1; } if (label != null) { - code[i] = new OpCodeWrapper(OpCodes.Leave, label); + code[i] = new OpCodeWrapper(System.Reflection.Emit.OpCodes.Leave, label); } } } @@ -1034,9 +1035,9 @@ private void RemoveSingletonBranches() case CodeType.OpCode: switch (code[i].opcode.FlowControl) { - case FlowControl.Branch: - case FlowControl.Return: - case FlowControl.Throw: + case System.Reflection.Emit.FlowControl.Branch: + case System.Reflection.Emit.FlowControl.Return: + case System.Reflection.Emit.FlowControl.Throw: reachable = false; break; } @@ -1062,7 +1063,7 @@ private void RemoveSingletonBranches() // now remove the unconditional branches to labels with a refcount of one for (int i = 0; i < code.Count; i++) { - if (code[i].opcode == OpCodes.Br && code[i].Label.Temp == 1) + if (code[i].opcode == System.Reflection.Emit.OpCodes.Br && code[i].Label.Temp == 1) { int target = FindLabel(code[i].Label) + 1; for (int j = target; j < code.Count; j++) @@ -1077,9 +1078,9 @@ private void RemoveSingletonBranches() } switch (code[j].opcode.FlowControl) { - case FlowControl.Branch: - case FlowControl.Return: - case FlowControl.Throw: + case System.Reflection.Emit.FlowControl.Branch: + case System.Reflection.Emit.FlowControl.Return: + case System.Reflection.Emit.FlowControl.Throw: // we've found a viable sequence of opcode to move to the branch location List range = code.GetRange(target, j - target + 1); if (target < i) @@ -1214,7 +1215,7 @@ private void SetLabelRefCounts() { code[i].Label.Temp++; } - else if (code[i].opcode == OpCodes.Switch) + else if (code[i].opcode == System.Reflection.Emit.OpCodes.Switch) { foreach (CodeEmitterLabel label in code[i].Labels) { @@ -1269,9 +1270,9 @@ private void RemoveDeadCode() } code[i].Label.Temp |= ReachableFlag; } - else if (code[i].opcode == OpCodes.Switch) + else if (code[i].opcode == System.Reflection.Emit.OpCodes.Switch) { - foreach (CodeEmitterLabel label in code[i].Labels) + foreach (var label in code[i].Labels) { if (label.Temp == ProcessedFlag) { @@ -1282,15 +1283,15 @@ private void RemoveDeadCode() } switch (code[i].opcode.FlowControl) { - case FlowControl.Cond_Branch: - if (!code[i].HasLabel && code[i].opcode != OpCodes.Switch) + case System.Reflection.Emit.FlowControl.Cond_Branch: + if (!code[i].HasLabel && code[i].opcode != System.Reflection.Emit.OpCodes.Switch) { throw new NotSupportedException(); } break; - case FlowControl.Branch: - case FlowControl.Return: - case FlowControl.Throw: + case System.Reflection.Emit.FlowControl.Branch: + case System.Reflection.Emit.FlowControl.Return: + case System.Reflection.Emit.FlowControl.Throw: reachable = false; break; } @@ -1328,9 +1329,9 @@ private void RemoveDeadCode() { switch (code[i].opcode.FlowControl) { - case FlowControl.Branch: - case FlowControl.Return: - case FlowControl.Throw: + case System.Reflection.Emit.FlowControl.Branch: + case System.Reflection.Emit.FlowControl.Return: + case System.Reflection.Emit.FlowControl.Throw: reachable = false; firstUnreachable = i + 1; break; @@ -1417,7 +1418,7 @@ private void DeduplicateBranchSourceTargetCode() SetLabelIndexes(); for (int i = 0; i < code.Count; i++) { - if (code[i].opcode == OpCodes.Br && code[i].HasLabel) + if (code[i].opcode == System.Reflection.Emit.OpCodes.Br && code[i].HasLabel) { int source = i - 1; int target = code[i].Label.Temp - 1; @@ -1437,8 +1438,8 @@ private void DeduplicateBranchSourceTargetCode() } switch (code[source].opcode.FlowControl) { - case FlowControl.Branch: - case FlowControl.Cond_Branch: + case System.Reflection.Emit.FlowControl.Branch: + case System.Reflection.Emit.FlowControl.Cond_Branch: goto break_while; } source--; @@ -1452,7 +1453,7 @@ private void DeduplicateBranchSourceTargetCode() // TODO for now we only do this optimization if there happens to be an appriopriate label if (code[target - 1].pseudo == CodeType.Label) { - code[source] = new OpCodeWrapper(OpCodes.Br, code[target - 1].Label); + code[source] = new OpCodeWrapper(System.Reflection.Emit.OpCodes.Br, code[target - 1].Label); for (int j = source + 1; j <= i; j++) { // We can't depend on DCE for code correctness (we have to maintain all MSIL invariants at all times), @@ -1469,10 +1470,10 @@ private void OptimizeStackTransfer() { for (int i = 0; i < code.Count; i++) { - if (code[i].opcode == OpCodes.Ldloc && - code[i + 1].opcode == OpCodes.Stloc && + if (code[i].opcode == System.Reflection.Emit.OpCodes.Ldloc && + code[i + 1].opcode == System.Reflection.Emit.OpCodes.Stloc && code[i + 2].pseudo == CodeType.BeginExceptionBlock && - code[i + 3].opcode == OpCodes.Ldloc && + code[i + 3].opcode == System.Reflection.Emit.OpCodes.Ldloc && code[i + 3].MatchLocal(code[i + 1]) && code[i + 4].pseudo == CodeType.ReleaseTempLocal && code[i + 4].MatchLocal(code[i + 3])) @@ -1559,7 +1560,7 @@ private void MergeExceptionBlocks() // the BeginExceptionBlock of the second block. for (int j = beginFault1; j < i + 2; j++) { - code[j] = new OpCodeWrapper(OpCodes.Nop, null); + code[j] = new OpCodeWrapper(System.Reflection.Emit.OpCodes.Nop, null); } // Repair the linking structure. extra[extra[i]] = beginFault2; @@ -1587,7 +1588,7 @@ bool HasBranchTo(int start, int end, CodeEmitterLabel label) if (code[i].Label == label) return true; } - else if (code[i].opcode == OpCodes.Switch) + else if (code[i].opcode == System.Reflection.Emit.OpCodes.Switch) { foreach (CodeEmitterLabel swlbl in code[i].Labels) if (swlbl == label) @@ -1660,9 +1661,9 @@ private void ConvertSynchronizedFaultToFinally() i++; } // check if the fault handler is the synchronized block exit pattern - if (code[i + 1].opcode == OpCodes.Ldloc + if (code[i + 1].opcode == System.Reflection.Emit.OpCodes.Ldloc && code[i + 2].pseudo == CodeType.MonitorExit - && code[i + 3].opcode == OpCodes.Endfinally) + && code[i + 3].opcode == System.Reflection.Emit.OpCodes.Endfinally) { if (!labelIndexSet) { @@ -1676,13 +1677,13 @@ private void ConvertSynchronizedFaultToFinally() { for (int j = start; j < i; j++) { - if (code[j].opcode == OpCodes.Leave) + if (code[j].opcode == System.Reflection.Emit.OpCodes.Leave) { int target = code[j].Label.Temp; if (target < start || target > i) { // check if the code preceding the leave matches the fault block - if ((code[j - 1].opcode == OpCodes.Pop || code[j - 1].opcode == OpCodes.Stloc) + if ((code[j - 1].opcode == System.Reflection.Emit.OpCodes.Pop || code[j - 1].opcode == System.Reflection.Emit.OpCodes.Stloc) && code[j - 2].pseudo == CodeType.MonitorExit && code[j - 3].Match(code[i + 1])) { @@ -1745,14 +1746,14 @@ private void RemoveRedundantMemoryBarriers() lastMemoryBarrier = i; break; case CodeType.OpCode: - if (code[i].opcode == OpCodes.Volatile) + if (code[i].opcode == System.Reflection.Emit.OpCodes.Volatile) { - if (code[i + 1].opcode != OpCodes.Stfld && code[i + 1].opcode != OpCodes.Stsfld) + if (code[i + 1].opcode != System.Reflection.Emit.OpCodes.Stfld && code[i + 1].opcode != System.Reflection.Emit.OpCodes.Stsfld) { lastMemoryBarrier = -1; } } - else if (code[i].opcode.FlowControl != FlowControl.Next) + else if (code[i].opcode.FlowControl != System.Reflection.Emit.FlowControl.Next) { lastMemoryBarrier = -1; } @@ -1763,32 +1764,32 @@ private void RemoveRedundantMemoryBarriers() private static bool MatchLdarg(OpCodeWrapper opc, out short arg) { - if (opc.opcode == OpCodes.Ldarg) + if (opc.opcode == System.Reflection.Emit.OpCodes.Ldarg) { arg = opc.ValueInt16; return true; } - else if (opc.opcode == OpCodes.Ldarg_S) + else if (opc.opcode == System.Reflection.Emit.OpCodes.Ldarg_S) { arg = opc.ValueByte; return true; } - else if (opc.opcode == OpCodes.Ldarg_0) + else if (opc.opcode == System.Reflection.Emit.OpCodes.Ldarg_0) { arg = 0; return true; } - else if (opc.opcode == OpCodes.Ldarg_1) + else if (opc.opcode == System.Reflection.Emit.OpCodes.Ldarg_1) { arg = 1; return true; } - else if (opc.opcode == OpCodes.Ldarg_2) + else if (opc.opcode == System.Reflection.Emit.OpCodes.Ldarg_2) { arg = 2; return true; } - else if (opc.opcode == OpCodes.Ldarg_3) + else if (opc.opcode == System.Reflection.Emit.OpCodes.Ldarg_3) { arg = 3; return true; @@ -1800,10 +1801,10 @@ private static bool MatchLdarg(OpCodeWrapper opc, out short arg) } } - private bool IsBranchEqNe(OpCode opcode) + private bool IsBranchEqNe(System.Reflection.Emit.OpCode opcode) { - return opcode == OpCodes.Beq - || opcode == OpCodes.Bne_Un; + return opcode == System.Reflection.Emit.OpCodes.Beq + || opcode == System.Reflection.Emit.OpCodes.Bne_Un; } private void CLRv4_x64_JIT_Workaround() @@ -1824,7 +1825,7 @@ private void CLRv4_x64_JIT_Workaround() // // The workaround is to replace ldarg with ldarga/ldind.i8. Looking at the generated code by the x86 and x64 JITs // this appears to be as efficient as the ldarg and it avoids the x64 bug. - if (code[i].opcode == OpCodes.Ldc_I8 && code[i].ValueInt64 == 0) + if (code[i].opcode == System.Reflection.Emit.OpCodes.Ldc_I8 && code[i].ValueInt64 == 0) { short arg; int m; @@ -1840,8 +1841,8 @@ private void CLRv4_x64_JIT_Workaround() { continue; } - code[m] = new OpCodeWrapper(OpCodes.Ldarga, arg); - code.Insert(m + 1, new OpCodeWrapper(OpCodes.Ldind_I8, null)); + code[m] = new OpCodeWrapper(System.Reflection.Emit.OpCodes.Ldarga, arg); + code.Insert(m + 1, new OpCodeWrapper(System.Reflection.Emit.OpCodes.Ldind_I8, null)); } } } @@ -1913,7 +1914,7 @@ void CheckInvariantBranchInOrOutOfBlocks() { case CodeType.OpCode: if (code[i].HasLabel - && code[i].opcode != OpCodes.Leave + && code[i].opcode != System.Reflection.Emit.OpCodes.Leave && code[i].Label.Temp != blockId) { DumpMethod(); @@ -1941,9 +1942,9 @@ private void CheckInvariantOpCodeUsage() { switch (code[i].opcode.FlowControl) { - case FlowControl.Branch: - case FlowControl.Cond_Branch: - if (!code[i].HasLabel && code[i].opcode != OpCodes.Switch) + case System.Reflection.Emit.FlowControl.Branch: + case System.Reflection.Emit.FlowControl.Cond_Branch: + if (!code[i].HasLabel && code[i].opcode != System.Reflection.Emit.OpCodes.Switch) { throw new InvalidOperationException(); } @@ -2063,31 +2064,31 @@ internal void DumpMethod() { Console.Write(" label" + labelIndexes[code[i].Label]); } - else if (code[i].opcode == OpCodes.Ldarg_S || code[i].opcode == OpCodes.Ldarga_S) + else if (code[i].opcode == System.Reflection.Emit.OpCodes.Ldarg_S || code[i].opcode == System.Reflection.Emit.OpCodes.Ldarga_S) { Console.Write(" " + code[i].ValueByte); } - else if (code[i].opcode == OpCodes.Ldarg || code[i].opcode == OpCodes.Ldarga) + else if (code[i].opcode == System.Reflection.Emit.OpCodes.Ldarg || code[i].opcode == System.Reflection.Emit.OpCodes.Ldarga) { Console.Write(" " + code[i].ValueInt16); } - else if (code[i].opcode == OpCodes.Isinst || code[i].opcode == OpCodes.Castclass || code[i].opcode == OpCodes.Box || code[i].opcode == OpCodes.Unbox || code[i].opcode == OpCodes.Ldobj || code[i].opcode == OpCodes.Newarr) + else if (code[i].opcode == System.Reflection.Emit.OpCodes.Isinst || code[i].opcode == System.Reflection.Emit.OpCodes.Castclass || code[i].opcode == System.Reflection.Emit.OpCodes.Box || code[i].opcode == System.Reflection.Emit.OpCodes.Unbox || code[i].opcode == System.Reflection.Emit.OpCodes.Ldobj || code[i].opcode == System.Reflection.Emit.OpCodes.Newarr) { Console.Write(" " + code[i].Type); } - else if (code[i].opcode == OpCodes.Call || code[i].opcode == OpCodes.Callvirt) + else if (code[i].opcode == System.Reflection.Emit.OpCodes.Call || code[i].opcode == System.Reflection.Emit.OpCodes.Callvirt) { Console.Write(" " + code[i].MethodBase); } - else if (code[i].opcode == OpCodes.Ldfld || code[i].opcode == OpCodes.Ldsfld || code[i].opcode == OpCodes.Stfld || code[i].opcode == OpCodes.Stsfld) + else if (code[i].opcode == System.Reflection.Emit.OpCodes.Ldfld || code[i].opcode == System.Reflection.Emit.OpCodes.Ldsfld || code[i].opcode == System.Reflection.Emit.OpCodes.Stfld || code[i].opcode == System.Reflection.Emit.OpCodes.Stsfld) { Console.Write(" " + code[i].FieldInfo); } - else if (code[i].opcode == OpCodes.Ldc_I4) + else if (code[i].opcode == System.Reflection.Emit.OpCodes.Ldc_I4) { Console.Write(" " + code[i].ValueInt32); } - else if (code[i].opcode == OpCodes.Ldloc || code[i].opcode == OpCodes.Stloc) + else if (code[i].opcode == System.Reflection.Emit.OpCodes.Ldloc || code[i].opcode == System.Reflection.Emit.OpCodes.Stloc) { Console.Write(" " + code[i].Local.__LocalIndex); } @@ -2209,27 +2210,27 @@ internal CodeEmitterLabel DefineLabel() return new CodeEmitterLabel(ilgen_real.DefineLabel()); } - internal void Emit(OpCode opcode) + internal void Emit(System.Reflection.Emit.OpCode opcode) { EmitOpCode(opcode, null); } internal void EmitUnaligned(byte alignment) { - EmitOpCode(OpCodes.Unaligned, alignment); + EmitOpCode(System.Reflection.Emit.OpCodes.Unaligned, alignment); } - internal void Emit(OpCode opcode, IMethodBaseSymbol mb) + internal void Emit(System.Reflection.Emit.OpCode opcode, IMethodBaseSymbol mb) { EmitOpCode(opcode, mb); } internal void EmitLdc_R8(double arg) { - EmitOpCode(OpCodes.Ldc_R8, arg); + EmitOpCode(System.Reflection.Emit.OpCodes.Ldc_R8, arg); } - internal void Emit(OpCode opcode, IFieldSymbol field) + internal void Emit(System.Reflection.Emit.OpCode opcode, IFieldSymbol field) { EmitOpCode(opcode, field); } @@ -2241,22 +2242,22 @@ internal void EmitLdarg(int arg) switch (arg) { case 0: - EmitOpCode(OpCodes.Ldarg_0, null); + EmitOpCode(System.Reflection.Emit.OpCodes.Ldarg_0, null); break; case 1: - EmitOpCode(OpCodes.Ldarg_1, null); + EmitOpCode(System.Reflection.Emit.OpCodes.Ldarg_1, null); break; case 2: - EmitOpCode(OpCodes.Ldarg_2, null); + EmitOpCode(System.Reflection.Emit.OpCodes.Ldarg_2, null); break; case 3: - EmitOpCode(OpCodes.Ldarg_3, null); + EmitOpCode(System.Reflection.Emit.OpCodes.Ldarg_3, null); break; default: if ((uint)arg <= byte.MaxValue) - EmitOpCode(OpCodes.Ldarg_S, (byte)arg); + EmitOpCode(System.Reflection.Emit.OpCodes.Ldarg_S, (byte)arg); else - EmitOpCode(OpCodes.Ldarg, (short)arg); + EmitOpCode(System.Reflection.Emit.OpCodes.Ldarg, (short)arg); break; } @@ -2267,9 +2268,9 @@ internal void EmitLdarga(int arg) Debug.Assert(0 <= arg && arg < 65536); if (arg < 256) - EmitOpCode(OpCodes.Ldarga_S, (byte)arg); + EmitOpCode(System.Reflection.Emit.OpCodes.Ldarga_S, (byte)arg); else - EmitOpCode(OpCodes.Ldarga, (short)arg); + EmitOpCode(System.Reflection.Emit.OpCodes.Ldarga, (short)arg); } internal void EmitStarg(int arg) @@ -2277,112 +2278,112 @@ internal void EmitStarg(int arg) Debug.Assert(0 <= arg && arg < 65536); if (arg < 256) - EmitOpCode(OpCodes.Starg_S, (byte)arg); + EmitOpCode(System.Reflection.Emit.OpCodes.Starg_S, (byte)arg); else - EmitOpCode(OpCodes.Starg, (short)arg); + EmitOpCode(System.Reflection.Emit.OpCodes.Starg, (short)arg); } internal void EmitLdc_I8(long arg) { - EmitOpCode(OpCodes.Ldc_I8, arg); + EmitOpCode(System.Reflection.Emit.OpCodes.Ldc_I8, arg); } internal void EmitBr(CodeEmitterLabel label) { - EmitOpCode(OpCodes.Br, label); + EmitOpCode(System.Reflection.Emit.OpCodes.Br, label); } internal void EmitBeq(CodeEmitterLabel label) { - EmitOpCode(OpCodes.Beq, label); + EmitOpCode(System.Reflection.Emit.OpCodes.Beq, label); } internal void EmitBne_Un(CodeEmitterLabel label) { - EmitOpCode(OpCodes.Bne_Un, label); + EmitOpCode(System.Reflection.Emit.OpCodes.Bne_Un, label); } internal void EmitBle_Un(CodeEmitterLabel label) { - EmitOpCode(OpCodes.Ble_Un, label); + EmitOpCode(System.Reflection.Emit.OpCodes.Ble_Un, label); } internal void EmitBlt_Un(CodeEmitterLabel label) { - EmitOpCode(OpCodes.Blt_Un, label); + EmitOpCode(System.Reflection.Emit.OpCodes.Blt_Un, label); } internal void EmitBge_Un(CodeEmitterLabel label) { - EmitOpCode(OpCodes.Bge_Un, label); + EmitOpCode(System.Reflection.Emit.OpCodes.Bge_Un, label); } internal void EmitBle(CodeEmitterLabel label) { - EmitOpCode(OpCodes.Ble, label); + EmitOpCode(System.Reflection.Emit.OpCodes.Ble, label); } internal void EmitBlt(CodeEmitterLabel label) { - EmitOpCode(OpCodes.Blt, label); + EmitOpCode(System.Reflection.Emit.OpCodes.Blt, label); } internal void EmitBge(CodeEmitterLabel label) { - EmitOpCode(OpCodes.Bge, label); + EmitOpCode(System.Reflection.Emit.OpCodes.Bge, label); } internal void EmitBgt(CodeEmitterLabel label) { - EmitOpCode(OpCodes.Bgt, label); + EmitOpCode(System.Reflection.Emit.OpCodes.Bgt, label); } internal void EmitBrtrue(CodeEmitterLabel label) { - EmitOpCode(OpCodes.Brtrue, label); + EmitOpCode(System.Reflection.Emit.OpCodes.Brtrue, label); } internal void EmitBrfalse(CodeEmitterLabel label) { - EmitOpCode(OpCodes.Brfalse, label); + EmitOpCode(System.Reflection.Emit.OpCodes.Brfalse, label); } internal void EmitLeave(CodeEmitterLabel label) { - EmitOpCode(OpCodes.Leave, label); + EmitOpCode(System.Reflection.Emit.OpCodes.Leave, label); } internal void EmitSwitch(CodeEmitterLabel[] labels) { - EmitOpCode(OpCodes.Switch, labels); + EmitOpCode(System.Reflection.Emit.OpCodes.Switch, labels); } - internal void Emit(OpCode opcode, CodeEmitterLocal local) + internal void Emit(System.Reflection.Emit.OpCode opcode, CodeEmitterLocal local) { EmitOpCode(opcode, local); } internal void EmitLdc_R4(float arg) { - EmitOpCode(OpCodes.Ldc_R4, arg); + EmitOpCode(System.Reflection.Emit.OpCodes.Ldc_R4, arg); } - internal void Emit(OpCode opcode, string arg) + internal void Emit(System.Reflection.Emit.OpCode opcode, string arg) { EmitOpCode(opcode, arg); } - internal void Emit(OpCode opcode, ITypeSymbol cls) + internal void Emit(System.Reflection.Emit.OpCode opcode, ITypeSymbol cls) { EmitOpCode(opcode, cls); } - internal void EmitCalli(OpCode opcode, CallingConvention unmanagedCallConv, ITypeSymbol returnType, ITypeSymbol[] parameterTypes) + internal void EmitCalli(System.Reflection.Emit.OpCode opcode, CallingConvention unmanagedCallConv, ITypeSymbol returnType, ITypeSymbol[] parameterTypes) { EmitOpCode(opcode, new CalliWrapper(unmanagedCallConv, returnType, parameterTypes)); } - internal void EmitCalli(OpCode opcode, CallingConventions unmanagedCallConv, ITypeSymbol returnType, ITypeSymbol[] parameterTypes, ITypeSymbol[] optionalParameterTypes) + internal void EmitCalli(System.Reflection.Emit.OpCode opcode, CallingConventions unmanagedCallConv, ITypeSymbol returnType, ITypeSymbol[] parameterTypes, ITypeSymbol[] optionalParameterTypes) { EmitOpCode(opcode, new ManagedCalliWrapper(unmanagedCallConv, returnType, parameterTypes, optionalParameterTypes)); } @@ -2405,8 +2406,8 @@ internal void MarkLabel(CodeEmitterLabel loc) internal void ThrowException(ITypeSymbol excType) { - Emit(OpCodes.Newobj, excType.GetConstructor([])); - Emit(OpCodes.Throw); + Emit(System.Reflection.Emit.OpCodes.Newobj, excType.GetConstructor([])); + Emit(System.Reflection.Emit.OpCodes.Throw); } internal void SetLineNumber(ushort line) @@ -2440,24 +2441,24 @@ internal void EmitThrow(string dottedClassName) var mw = exception.GetMethodWrapper("", "()V", false); mw.Link(); mw.EmitNewobj(this); - Emit(OpCodes.Throw); + Emit(System.Reflection.Emit.OpCodes.Throw); } internal void EmitThrow(string dottedClassName, string message) { var exception = context.ClassLoaderFactory.GetBootstrapClassLoader().LoadClassByName(dottedClassName); - Emit(OpCodes.Ldstr, message); + Emit(System.Reflection.Emit.OpCodes.Ldstr, message); var mw = exception.GetMethodWrapper("", "(Ljava.lang.String;)V", false); mw.Link(); mw.EmitNewobj(this); - Emit(OpCodes.Throw); + Emit(System.Reflection.Emit.OpCodes.Throw); } internal void EmitNullCheck() { // I think this is the most efficient way to generate a NullReferenceException if the reference is null - Emit(OpCodes.Ldvirtftn, context.CodeEmitterFactory.ObjectToStringMethod); - Emit(OpCodes.Pop); + Emit(System.Reflection.Emit.OpCodes.Ldvirtftn, context.CodeEmitterFactory.ObjectToStringMethod); + Emit(System.Reflection.Emit.OpCodes.Pop); } internal void EmitCastclass(ITypeSymbol type) @@ -2465,22 +2466,22 @@ internal void EmitCastclass(ITypeSymbol type) if (context.CodeEmitterFactory.VerboseCastFailureMethod != null) { var lb = DeclareLocal(context.Types.Object); - Emit(OpCodes.Stloc, lb); - Emit(OpCodes.Ldloc, lb); - Emit(OpCodes.Isinst, type); - Emit(OpCodes.Dup); + Emit(System.Reflection.Emit.OpCodes.Stloc, lb); + Emit(System.Reflection.Emit.OpCodes.Ldloc, lb); + Emit(System.Reflection.Emit.OpCodes.Isinst, type); + Emit(System.Reflection.Emit.OpCodes.Dup); var ok = DefineLabel(); EmitBrtrue(ok); - Emit(OpCodes.Ldloc, lb); + Emit(System.Reflection.Emit.OpCodes.Ldloc, lb); EmitBrfalse(ok); // handle null - Emit(OpCodes.Ldtoken, type); - Emit(OpCodes.Ldloc, lb); - Emit(OpCodes.Call, context.CodeEmitterFactory.VerboseCastFailureMethod); + Emit(System.Reflection.Emit.OpCodes.Ldtoken, type); + Emit(System.Reflection.Emit.OpCodes.Ldloc, lb); + Emit(System.Reflection.Emit.OpCodes.Call, context.CodeEmitterFactory.VerboseCastFailureMethod); MarkLabel(ok); } else { - Emit(OpCodes.Castclass, type); + Emit(System.Reflection.Emit.OpCodes.Castclass, type); } } @@ -2489,16 +2490,16 @@ internal void EmitCastclass(ITypeSymbol type) internal void EmitAssertType(ITypeSymbol type) { var isnull = DefineLabel(); - Emit(OpCodes.Dup); + Emit(System.Reflection.Emit.OpCodes.Dup); EmitBrfalse(isnull); - Emit(OpCodes.Isinst, type); - Emit(OpCodes.Dup); + Emit(System.Reflection.Emit.OpCodes.Isinst, type); + Emit(System.Reflection.Emit.OpCodes.Dup); var ok = DefineLabel(); EmitBrtrue(ok); EmitThrow("java.lang.IncompatibleClassChangeError"); MarkLabel(isnull); - Emit(OpCodes.Pop); - Emit(OpCodes.Ldnull); + Emit(System.Reflection.Emit.OpCodes.Pop); + Emit(System.Reflection.Emit.OpCodes.Ldnull); MarkLabel(ok); } @@ -2508,24 +2509,24 @@ internal void EmitUnboxSpecial(ITypeSymbol type) var label1 = DefineLabel(); var label2 = DefineLabel(); - Emit(OpCodes.Dup); + Emit(System.Reflection.Emit.OpCodes.Dup); EmitBrtrue(label1); - Emit(OpCodes.Pop); + Emit(System.Reflection.Emit.OpCodes.Pop); var local = AllocTempLocal(type); - Emit(OpCodes.Ldloca, local); - Emit(OpCodes.Initobj, type); - Emit(OpCodes.Ldloc, local); + Emit(System.Reflection.Emit.OpCodes.Ldloca, local); + Emit(System.Reflection.Emit.OpCodes.Initobj, type); + Emit(System.Reflection.Emit.OpCodes.Ldloc, local); ReleaseTempLocal(local); EmitBr(label2); MarkLabel(label1); - Emit(OpCodes.Unbox, type); - Emit(OpCodes.Ldobj, type); + Emit(System.Reflection.Emit.OpCodes.Unbox, type); + Emit(System.Reflection.Emit.OpCodes.Ldobj, type); MarkLabel(label2); } internal void EmitLdc_I4(int i) { - EmitOpCode(OpCodes.Ldc_I4, i); + EmitOpCode(System.Reflection.Emit.OpCodes.Ldc_I4, i); } internal void Emit_idiv() @@ -2536,14 +2537,14 @@ internal void Emit_idiv() var label1 = DefineLabel(); var label2 = DefineLabel(); - Emit(OpCodes.Dup); - Emit(OpCodes.Ldc_I4_M1); + Emit(System.Reflection.Emit.OpCodes.Dup); + Emit(System.Reflection.Emit.OpCodes.Ldc_I4_M1); EmitBne_Un(label1); - Emit(OpCodes.Pop); - Emit(OpCodes.Neg); + Emit(System.Reflection.Emit.OpCodes.Pop); + Emit(System.Reflection.Emit.OpCodes.Neg); EmitBr(label2); MarkLabel(label1); - Emit(OpCodes.Div); + Emit(System.Reflection.Emit.OpCodes.Div); MarkLabel(label2); } @@ -2555,23 +2556,23 @@ internal void Emit_ldiv() var label1 = DefineLabel(); var label2 = DefineLabel(); - Emit(OpCodes.Dup); - Emit(OpCodes.Ldc_I4_M1); - Emit(OpCodes.Conv_I8); + Emit(System.Reflection.Emit.OpCodes.Dup); + Emit(System.Reflection.Emit.OpCodes.Ldc_I4_M1); + Emit(System.Reflection.Emit.OpCodes.Conv_I8); EmitBne_Un(label1); - Emit(OpCodes.Pop); - Emit(OpCodes.Neg); + Emit(System.Reflection.Emit.OpCodes.Pop); + Emit(System.Reflection.Emit.OpCodes.Neg); EmitBr(label2); MarkLabel(label1); - Emit(OpCodes.Div); + Emit(System.Reflection.Emit.OpCodes.Div); MarkLabel(label2); } internal void Emit_instanceof(ITypeSymbol type) { - Emit(OpCodes.Isinst, type); - Emit(OpCodes.Ldnull); - Emit(OpCodes.Cgt_Un); + Emit(System.Reflection.Emit.OpCodes.Isinst, type); + Emit(System.Reflection.Emit.OpCodes.Ldnull); + Emit(System.Reflection.Emit.OpCodes.Cgt_Un); } internal enum Comparison @@ -2585,7 +2586,7 @@ internal enum Comparison internal void Emit_if_le_lt_ge_gt(Comparison comp, CodeEmitterLabel label) { // don't change this Ldc_I4_0 to Ldc_I4(0) because the optimizer recognizes only this specific pattern - Emit(OpCodes.Ldc_I4_0); + Emit(System.Reflection.Emit.OpCodes.Ldc_I4_0); switch (comp) { case Comparison.LessOrEqual: @@ -2603,52 +2604,52 @@ internal void Emit_if_le_lt_ge_gt(Comparison comp, CodeEmitterLabel label) } } - private void EmitCmp(ITypeSymbol type, OpCode cmp1, OpCode cmp2) + private void EmitCmp(ITypeSymbol type, System.Reflection.Emit.OpCode cmp1, System.Reflection.Emit.OpCode cmp2) { var value1 = AllocTempLocal(type); var value2 = AllocTempLocal(type); - Emit(OpCodes.Stloc, value2); - Emit(OpCodes.Stloc, value1); - Emit(OpCodes.Ldloc, value1); - Emit(OpCodes.Ldloc, value2); + Emit(System.Reflection.Emit.OpCodes.Stloc, value2); + Emit(System.Reflection.Emit.OpCodes.Stloc, value1); + Emit(System.Reflection.Emit.OpCodes.Ldloc, value1); + Emit(System.Reflection.Emit.OpCodes.Ldloc, value2); Emit(cmp1); - Emit(OpCodes.Ldloc, value1); - Emit(OpCodes.Ldloc, value2); + Emit(System.Reflection.Emit.OpCodes.Ldloc, value1); + Emit(System.Reflection.Emit.OpCodes.Ldloc, value2); Emit(cmp2); - Emit(OpCodes.Sub); + Emit(System.Reflection.Emit.OpCodes.Sub); ReleaseTempLocal(value2); ReleaseTempLocal(value1); } internal void Emit_lcmp() { - EmitCmp(context.Types.Int64, OpCodes.Cgt, OpCodes.Clt); + EmitCmp(context.Types.Int64, System.Reflection.Emit.OpCodes.Cgt, System.Reflection.Emit.OpCodes.Clt); } internal void Emit_fcmpl() { - EmitCmp(context.Types.Single, OpCodes.Cgt, OpCodes.Clt_Un); + EmitCmp(context.Types.Single, System.Reflection.Emit.OpCodes.Cgt, System.Reflection.Emit.OpCodes.Clt_Un); } internal void Emit_fcmpg() { - EmitCmp(context.Types.Single, OpCodes.Cgt_Un, OpCodes.Clt); + EmitCmp(context.Types.Single, System.Reflection.Emit.OpCodes.Cgt_Un, System.Reflection.Emit.OpCodes.Clt); } internal void Emit_dcmpl() { - EmitCmp(context.Types.Double, OpCodes.Cgt, OpCodes.Clt_Un); + EmitCmp(context.Types.Double, System.Reflection.Emit.OpCodes.Cgt, System.Reflection.Emit.OpCodes.Clt_Un); } internal void Emit_dcmpg() { - EmitCmp(context.Types.Double, OpCodes.Cgt_Un, OpCodes.Clt); + EmitCmp(context.Types.Double, System.Reflection.Emit.OpCodes.Cgt_Un, System.Reflection.Emit.OpCodes.Clt); } internal void Emit_And_I4(int v) { EmitLdc_I4(v); - Emit(OpCodes.And); + Emit(System.Reflection.Emit.OpCodes.And); } internal void CheckLabels() diff --git a/src/IKVM.Runtime/CodeEmitterLabel.cs b/src/IKVM.Runtime/CodeEmitterLabel.cs index 465b660a2..d7cae4d01 100644 --- a/src/IKVM.Runtime/CodeEmitterLabel.cs +++ b/src/IKVM.Runtime/CodeEmitterLabel.cs @@ -22,12 +22,7 @@ Jeroen Frijters */ -#if IMPORTER -using IKVM.Reflection; -using IKVM.Reflection.Emit; -#else -using System.Reflection.Emit; -#endif +using IKVM.CoreLib.Symbols.Emit; namespace IKVM.Runtime { @@ -35,14 +30,14 @@ namespace IKVM.Runtime sealed class CodeEmitterLabel { - internal readonly Label Label; + internal readonly ILabel Label; internal int Temp; /// /// Initializes a new instance. /// /// - internal CodeEmitterLabel(Label label) + internal CodeEmitterLabel(ILabel label) { this.Label = label; } diff --git a/src/IKVM.Runtime/DefineMethodHelper.cs b/src/IKVM.Runtime/DefineMethodHelper.cs index 5468da337..d6e041c68 100644 --- a/src/IKVM.Runtime/DefineMethodHelper.cs +++ b/src/IKVM.Runtime/DefineMethodHelper.cs @@ -21,7 +21,8 @@ Jeroen Frijters jeroen@frijters.net */ -using System; +using IKVM.CoreLib.Symbols.Emit; +using IKVM.CoreLib.Symbols; #if IMPORTER using IKVM.Reflection; @@ -54,23 +55,23 @@ internal int ParameterCount get { return mw.GetParameters().Length + (mw.HasCallerID ? 1 : 0); } } - internal MethodBuilder DefineMethod(RuntimeByteCodeJavaType context, TypeBuilder tb, string name, MethodAttributes attribs) + internal IMethodSymbolBuilder DefineMethod(RuntimeByteCodeJavaType context, ITypeSymbolBuilder tb, string name, System.Reflection.MethodAttributes attribs) { return DefineMethod(context.ClassLoader.GetTypeWrapperFactory(), tb, name, attribs, null, false); } - internal MethodBuilder DefineMethod(RuntimeJavaTypeFactory context, TypeBuilder tb, string name, MethodAttributes attribs) + internal IMethodSymbolBuilder DefineMethod(RuntimeJavaTypeFactory context, ITypeSymbolBuilder tb, string name, System.Reflection.MethodAttributes attribs) { return DefineMethod(context, tb, name, attribs, null, false); } - internal MethodBuilder DefineMethod(RuntimeJavaTypeFactory context, TypeBuilder tb, string name, MethodAttributes attribs, Type firstParameter, bool mustBePublic) + internal IMethodSymbolBuilder DefineMethod(RuntimeJavaTypeFactory context, ITypeSymbolBuilder tb, string name, System.Reflection.MethodAttributes attribs, ITypeSymbol firstParameter, bool mustBePublic) { // we add optional modifiers to make the signature unique int firstParam = firstParameter == null ? 0 : 1; - RuntimeJavaType[] parameters = mw.GetParameters(); - Type[] parameterTypes = new Type[parameters.Length + (mw.HasCallerID ? 1 : 0) + firstParam]; - Type[][] modopt = new Type[parameterTypes.Length][]; + var parameters = mw.GetParameters(); + var parameterTypes = new ITypeSymbol[parameters.Length + (mw.HasCallerID ? 1 : 0) + firstParam]; + var modopt = new ITypeSymbol[parameterTypes.Length][]; if (firstParameter != null) { parameterTypes[0] = firstParameter; @@ -87,21 +88,20 @@ internal MethodBuilder DefineMethod(RuntimeJavaTypeFactory context, TypeBuilder { parameterTypes[parameterTypes.Length - 1] = mw.DeclaringType.Context.JavaBase.TypeOfIkvmInternalCallerID.TypeAsSignatureType; } - Type returnType = mustBePublic - ? mw.ReturnType.TypeAsPublicSignatureType - : mw.ReturnType.TypeAsSignatureType; - Type[] modoptReturnType = RuntimeByteCodeJavaType.GetModOpt(context, mw.ReturnType, mustBePublic); - return tb.DefineMethod(name, attribs, CallingConventions.Standard, returnType, null, modoptReturnType, parameterTypes, null, modopt); + + var returnType = mustBePublic ? mw.ReturnType.TypeAsPublicSignatureType : mw.ReturnType.TypeAsSignatureType; + var modoptReturnType = RuntimeByteCodeJavaType.GetModOpt(context, mw.ReturnType, mustBePublic); + return tb.DefineMethod(name, attribs, System.Reflection.CallingConventions.Standard, returnType, null, modoptReturnType, parameterTypes, null, modopt); } - internal MethodBuilder DefineConstructor(RuntimeByteCodeJavaType context, TypeBuilder tb, MethodAttributes attribs) + internal IMethodSymbolBuilder DefineConstructor(RuntimeByteCodeJavaType context, ITypeSymbolBuilder tb, System.Reflection.MethodAttributes attribs) { return DefineConstructor(context.ClassLoader.GetTypeWrapperFactory(), tb, attribs); } - internal MethodBuilder DefineConstructor(RuntimeJavaTypeFactory context, TypeBuilder tb, MethodAttributes attribs) + internal IMethodSymbolBuilder DefineConstructor(RuntimeJavaTypeFactory context, ITypeSymbolBuilder tb, System.Reflection.MethodAttributes attribs) { - return DefineMethod(context, tb, ConstructorInfo.ConstructorName, attribs | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName); + return DefineMethod(context, tb, ConstructorInfo.ConstructorName, attribs | System.Reflection.MethodAttributes.SpecialName | System.Reflection.MethodAttributes.RTSpecialName); } } diff --git a/src/IKVM.Runtime/DynamicClassLoader.cs b/src/IKVM.Runtime/DynamicClassLoader.cs index b8f86ec23..c22efbdfa 100644 --- a/src/IKVM.Runtime/DynamicClassLoader.cs +++ b/src/IKVM.Runtime/DynamicClassLoader.cs @@ -29,6 +29,10 @@ Jeroen Frijters using static System.Diagnostics.DebuggableAttribute; using IKVM.CoreLib.Diagnostics; +using IKVM.CoreLib.Symbols.Emit; +using IKVM.CoreLib.Symbols; + + #if IMPORTER @@ -202,17 +206,17 @@ internal sealed class DynamicClassLoader : RuntimeJavaTypeFactory readonly RuntimeContext context; readonly IDiagnosticHandler diagnostics; - readonly ModuleBuilder moduleBuilder; + readonly IModuleSymbolBuilder moduleBuilder; readonly bool hasInternalAccess; #if IMPORTER - TypeBuilder proxiesContainer; - List proxies; + ITypeSymbolBuilder proxiesContainer; + List proxies; #endif - Dictionary unloadables; - TypeBuilder unloadableContainer; - Type[] delegates; + Dictionary unloadables; + ITypeSymbolBuilder unloadableContainer; + ITypeSymbol[] delegates; /// /// Initializes a new instance. @@ -221,7 +225,7 @@ internal sealed class DynamicClassLoader : RuntimeJavaTypeFactory /// /// /// - internal DynamicClassLoader(RuntimeContext context, IDiagnosticHandler diagnostics, ModuleBuilder moduleBuilder, bool hasInternalAccess) + internal DynamicClassLoader(RuntimeContext context, IDiagnosticHandler diagnostics, IModuleSymbolBuilder moduleBuilder, bool hasInternalAccess) { this.context = context ?? throw new ArgumentNullException(nameof(context)); this.diagnostics = diagnostics ?? throw new ArgumentNullException(nameof(diagnostics)); @@ -310,84 +314,82 @@ private static java.lang.Class TieClassAndWrapper(RuntimeJavaType type, Protecti #if IMPORTER - internal TypeBuilder DefineProxy(string name, TypeAttributes typeAttributes, Type parent, Type[] interfaces) + internal ITypeSymbolBuilder DefineProxy(string name, System.Reflection.TypeAttributes typeAttributes, ITypeSymbol parent, ITypeSymbol[] interfaces) { if (proxiesContainer == null) { - proxiesContainer = moduleBuilder.DefineType(TypeNameUtil.ProxiesContainer, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.Abstract); + proxiesContainer = moduleBuilder.DefineType(TypeNameUtil.ProxiesContainer, System.Reflection.TypeAttributes.Public | System.Reflection.TypeAttributes.Class | System.Reflection.TypeAttributes.Sealed | System.Reflection.TypeAttributes.Abstract); context.AttributeHelper.HideFromJava(proxiesContainer); context.AttributeHelper.SetEditorBrowsableNever(proxiesContainer); - proxies = new List(); + proxies = new List(); } - TypeBuilder tb = proxiesContainer.DefineNestedType(name, typeAttributes, parent, interfaces); + + var tb = proxiesContainer.DefineNestedType(name, typeAttributes, parent, interfaces); proxies.Add(tb); return tb; } #endif - internal override Type DefineUnloadable(string name) + internal override ITypeSymbol DefineUnloadable(string name) { lock (this) { if (unloadables == null) - { - unloadables = new Dictionary(); - } - TypeBuilder type; - if (unloadables.TryGetValue(name, out type)) - { + unloadables = new Dictionary(); + + if (unloadables.TryGetValue(name, out var type)) return type; - } + if (unloadableContainer == null) { - unloadableContainer = moduleBuilder.DefineType(RuntimeUnloadableJavaType.ContainerTypeName, TypeAttributes.Interface | TypeAttributes.Abstract); + unloadableContainer = moduleBuilder.DefineType(RuntimeUnloadableJavaType.ContainerTypeName, System.Reflection.TypeAttributes.Interface | System.Reflection.TypeAttributes.Abstract); context.AttributeHelper.HideFromJava(unloadableContainer); } - type = unloadableContainer.DefineNestedType(TypeNameUtil.MangleNestedTypeName(name), TypeAttributes.NestedPrivate | TypeAttributes.Interface | TypeAttributes.Abstract); + + type = unloadableContainer.DefineNestedType(TypeNameUtil.MangleNestedTypeName(name), System.Reflection.TypeAttributes.NestedPrivate | System.Reflection.TypeAttributes.Interface | System.Reflection.TypeAttributes.Abstract); unloadables.Add(name, type); - return type; + return type.Symbol; } } - internal override Type DefineDelegate(int parameterCount, bool returnVoid) + internal override ITypeSymbol DefineDelegate(int parameterCount, bool returnVoid) { lock (this) { if (delegates == null) - { - delegates = new Type[512]; - } + delegates = new ITypeSymbol[512]; + int index = parameterCount + (returnVoid ? 256 : 0); - Type type = delegates[index]; + var type = delegates[index]; if (type != null) - { return type; - } - TypeBuilder tb = moduleBuilder.DefineType(returnVoid ? "__<>NVIV`" + parameterCount : "__<>NVI`" + (parameterCount + 1), TypeAttributes.NotPublic | TypeAttributes.Sealed, context.Types.MulticastDelegate); - string[] names = new string[parameterCount + (returnVoid ? 0 : 1)]; + + var tb = moduleBuilder.DefineType(returnVoid ? "__<>NVIV`" + parameterCount : "__<>NVI`" + (parameterCount + 1), System.Reflection.TypeAttributes.NotPublic | System.Reflection.TypeAttributes.Sealed, context.Types.MulticastDelegate); + var names = new string[parameterCount + (returnVoid ? 0 : 1)]; for (int i = 0; i < names.Length; i++) - { names[i] = "P" + i; - } + if (!returnVoid) - { names[names.Length - 1] = "R"; - } - Type[] genericParameters = tb.DefineGenericParameters(names); - Type[] parameterTypes = genericParameters; + + var genericParameters = tb.DefineGenericParameters(names); + var parameterTypes = genericParameters; if (!returnVoid) { - parameterTypes = new Type[genericParameters.Length - 1]; + parameterTypes = new ITypeSymbol[genericParameters.Length - 1]; Array.Copy(genericParameters, parameterTypes, parameterTypes.Length); } - tb.DefineMethod(ConstructorInfo.ConstructorName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, context.Types.Void, new Type[] { context.Types.Object, context.Types.IntPtr }) - .SetImplementationFlags(MethodImplAttributes.Runtime); - MethodBuilder mb = tb.DefineMethod("Invoke", MethodAttributes.Public | MethodAttributes.NewSlot | MethodAttributes.Virtual, returnVoid ? context.Types.Void : genericParameters[genericParameters.Length - 1], parameterTypes); - mb.SetImplementationFlags(MethodImplAttributes.Runtime); - type = tb.CreateType(); - delegates[index] = type; - return type; + + var ctor = tb.DefineMethod(ConstructorInfo.ConstructorName, System.Reflection.MethodAttributes.Public | System.Reflection.MethodAttributes.SpecialName | System.Reflection.MethodAttributes.RTSpecialName, context.Types.Void, [context.Types.Object, context.Types.IntPtr]); + ctor.SetImplementationFlags(System.Reflection.MethodImplAttributes.Runtime); + + var mb = tb.DefineMethod("Invoke", System.Reflection.MethodAttributes.Public | System.Reflection.MethodAttributes.NewSlot | System.Reflection.MethodAttributes.Virtual, returnVoid ? context.Types.Void : genericParameters[genericParameters.Length - 1], parameterTypes); + mb.SetImplementationFlags(System.Reflection.MethodImplAttributes.Runtime); + + tb.Complete(); + delegates[index] = tb.Symbol; + return tb.Symbol; } } @@ -449,7 +451,7 @@ internal static ModuleBuilder CreateJniProxyModuleBuilder() #endif - internal sealed override ModuleBuilder ModuleBuilder => moduleBuilder; + internal sealed override IModuleSymbolBuilder ModuleBuilder => moduleBuilder; #if !IMPORTER diff --git a/src/IKVM.Runtime/IRuntimeSymbolResolver.cs b/src/IKVM.Runtime/IRuntimeSymbolResolver.cs index 09b5a0140..9196c97d2 100644 --- a/src/IKVM.Runtime/IRuntimeSymbolResolver.cs +++ b/src/IKVM.Runtime/IRuntimeSymbolResolver.cs @@ -3,7 +3,11 @@ using IKVM.CoreLib.Symbols; #if IMPORTER || EXPORTER +using IKVM.Reflection; + using Type = IKVM.Reflection.Type; +#else +using System.Reflection; #endif namespace IKVM.Runtime @@ -15,6 +19,25 @@ namespace IKVM.Runtime interface IRuntimeSymbolResolver : ISymbolResolver { + /// + /// Gets the that manages access to symbols. + /// + ISymbolContext Symbols { get; } + + /// + /// Gets the associated with the specified type. + /// + /// + /// + IAssemblySymbol ResolveAssembly(Assembly assembly); + + /// + /// Gets the associated with the specified type. + /// + /// + /// + IModuleSymbol ResolveModule(Module module); + /// /// Gets the associated with the specified type. /// diff --git a/src/IKVM.Runtime/ReflectUtil.cs b/src/IKVM.Runtime/ReflectUtil.cs index 31889ad73..44c812677 100644 --- a/src/IKVM.Runtime/ReflectUtil.cs +++ b/src/IKVM.Runtime/ReflectUtil.cs @@ -24,7 +24,7 @@ Jeroen Frijters using System; using IKVM.CoreLib.Symbols; - +using IKVM.CoreLib.Symbols.Emit; #if IMPORTER || EXPORTER using IKVM.Reflection; @@ -116,9 +116,9 @@ internal static bool IsDynamicMethod(IMethodSymbol method) } } - internal static MethodBuilder DefineTypeInitializer(TypeBuilder typeBuilder, RuntimeClassLoader loader) + internal static IMethodSymbolBuilder DefineTypeInitializer(ITypeSymbolBuilder typeBuilder, RuntimeClassLoader loader) { - var attr = MethodAttributes.Static | MethodAttributes.RTSpecialName | MethodAttributes.SpecialName | MethodAttributes.Private; + var attr = System.Reflection.MethodAttributes.Static | System.Reflection.MethodAttributes.RTSpecialName | System.Reflection.MethodAttributes.SpecialName | System.Reflection.MethodAttributes.Private; return typeBuilder.DefineMethod(ConstructorInfo.TypeConstructorName, attr, null, []); } @@ -146,9 +146,9 @@ internal static bool IsConstructor(IMethodBaseSymbol method) return method.IsSpecialName && method.Name == ConstructorInfo.ConstructorName; } - internal static MethodBuilder DefineConstructor(TypeBuilder tb, MethodAttributes attribs, Type[] parameterTypes) + internal static IMethodSymbolBuilder DefineConstructor(ITypeSymbolBuilder tb, System.Reflection.MethodAttributes attribs, ITypeSymbol[] parameterTypes) { - return tb.DefineMethod(ConstructorInfo.ConstructorName, attribs | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, null, parameterTypes); + return tb.DefineMethod(ConstructorInfo.ConstructorName, attribs | System.Reflection.MethodAttributes.SpecialName | System.Reflection.MethodAttributes.RTSpecialName, null, parameterTypes); } /// diff --git a/src/IKVM.Runtime/RuntimeArrayJavaType.cs b/src/IKVM.Runtime/RuntimeArrayJavaType.cs index 1bcc4c1b8..95cd1a6c5 100644 --- a/src/IKVM.Runtime/RuntimeArrayJavaType.cs +++ b/src/IKVM.Runtime/RuntimeArrayJavaType.cs @@ -27,7 +27,6 @@ Jeroen Frijters using IKVM.Attributes; using IKVM.CoreLib.Symbols; - #if IMPORTER || EXPORTER using IKVM.Reflection; using IKVM.Reflection.Emit; @@ -45,7 +44,7 @@ sealed class RuntimeArrayJavaType : RuntimeJavaType volatile RuntimeJavaType[] interfaces; readonly RuntimeJavaType ultimateElementTypeWrapper; - Type arrayType; + ITypeSymbol arrayType; bool finished; /// @@ -68,9 +67,9 @@ internal override RuntimeJavaType BaseTypeWrapper internal override RuntimeClassLoader ClassLoader => ultimateElementTypeWrapper.ClassLoader; - internal static MethodInfo GetCloneMethod(RuntimeContext context) + internal static IMethodSymbol GetCloneMethod(RuntimeContext context) { - return context.Types.Array.GetMethod("Clone", BindingFlags.Public | BindingFlags.Instance, null, [], null); + return context.Types.Array.GetMethod("Clone", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance, []); } protected override void LazyPublishMembers() @@ -113,14 +112,14 @@ internal override RuntimeJavaType[] Interfaces } } - internal override Type TypeAsTBD + internal override ITypeSymbol TypeAsTBD { get { while (arrayType == null) { bool prevFinished = finished; - Type type = MakeArrayType(ultimateElementTypeWrapper.TypeAsArrayType, this.ArrayRank); + var type = MakeArrayType(ultimateElementTypeWrapper.TypeAsArrayType, this.ArrayRank); if (prevFinished) { // We were already finished prior to the call to MakeArrayType, so we can safely diff --git a/src/IKVM.Runtime/RuntimeByteCodeJavaType.DynamicImpl.cs b/src/IKVM.Runtime/RuntimeByteCodeJavaType.DynamicImpl.cs index 534959843..7606d4334 100644 --- a/src/IKVM.Runtime/RuntimeByteCodeJavaType.DynamicImpl.cs +++ b/src/IKVM.Runtime/RuntimeByteCodeJavaType.DynamicImpl.cs @@ -21,9 +21,8 @@ Jeroen Frijters jeroen@frijters.net */ -using System; - using IKVM.Attributes; +using IKVM.CoreLib.Symbols; #if IMPORTER using IKVM.Reflection; @@ -42,13 +41,13 @@ partial class RuntimeByteCodeJavaType private abstract class DynamicImpl { - internal abstract Type Type { get; } + internal abstract ITypeSymbol Type { get; } internal abstract RuntimeJavaType[] InnerClasses { get; } internal abstract RuntimeJavaType DeclaringTypeWrapper { get; } internal abstract Modifiers ReflectiveModifiers { get; } internal abstract DynamicImpl Finish(); - internal abstract MethodBase LinkMethod(RuntimeJavaMethod mw); - internal abstract FieldInfo LinkField(RuntimeJavaField fw); + internal abstract IMethodBaseSymbol LinkMethod(RuntimeJavaMethod mw); + internal abstract IFieldSymbol LinkField(RuntimeJavaField fw); internal abstract void EmitRunClassConstructor(CodeEmitter ilgen); internal abstract string GetGenericSignature(); internal abstract string[] GetEnclosingMethod(); @@ -60,7 +59,7 @@ private abstract class DynamicImpl internal abstract object[][] GetParameterAnnotations(int index); internal abstract MethodParametersEntry[] GetMethodParameters(int index); internal abstract object[] GetFieldAnnotations(int index); - internal abstract MethodInfo GetFinalizeMethod(); + internal abstract IMethodSymbol GetFinalizeMethod(); internal abstract object[] GetConstantPool(); internal abstract byte[] GetRawTypeAnnotations(); internal abstract byte[] GetMethodRawTypeAnnotations(int index); diff --git a/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishedTypeImpl.cs b/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishedTypeImpl.cs index f6b97af94..7488888be 100644 --- a/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishedTypeImpl.cs +++ b/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishedTypeImpl.cs @@ -25,6 +25,7 @@ Jeroen Frijters using System.Diagnostics; using IKVM.Attributes; +using IKVM.CoreLib.Symbols; #if IMPORTER using IKVM.Reflection; @@ -46,16 +47,16 @@ partial class RuntimeByteCodeJavaType sealed class FinishedTypeImpl : DynamicImpl { - readonly Type type; + readonly ITypeSymbol type; readonly RuntimeJavaType[] innerclasses; readonly RuntimeJavaType declaringTypeWrapper; readonly Modifiers reflectiveModifiers; - readonly MethodInfo clinitMethod; - readonly MethodInfo finalizeMethod; + readonly IMethodSymbol clinitMethod; + readonly IMethodSymbol finalizeMethod; readonly Metadata metadata; readonly RuntimeJavaType host; - internal FinishedTypeImpl(Type type, RuntimeJavaType[] innerclasses, RuntimeJavaType declaringTypeWrapper, Modifiers reflectiveModifiers, Metadata metadata, MethodInfo clinitMethod, MethodInfo finalizeMethod, RuntimeJavaType host) + internal FinishedTypeImpl(ITypeSymbol type, RuntimeJavaType[] innerclasses, RuntimeJavaType declaringTypeWrapper, Modifiers reflectiveModifiers, Metadata metadata, IMethodSymbol clinitMethod, IMethodSymbol finalizeMethod, RuntimeJavaType host) { this.type = type; this.innerclasses = innerclasses; @@ -93,7 +94,7 @@ internal override Modifiers ReflectiveModifiers } } - internal override Type Type + internal override ITypeSymbol Type { get { @@ -105,7 +106,7 @@ internal override void EmitRunClassConstructor(CodeEmitter ilgen) { if (clinitMethod != null) { - ilgen.Emit(OpCodes.Call, clinitMethod); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, clinitMethod); } } @@ -114,14 +115,14 @@ internal override DynamicImpl Finish() return this; } - internal override MethodBase LinkMethod(RuntimeJavaMethod mw) + internal override IMethodBaseSymbol LinkMethod(RuntimeJavaMethod mw) { // we should never be called, because all methods on a finished type are already linked Debug.Assert(false); return mw.GetMethod(); } - internal override FieldInfo LinkField(RuntimeJavaField fw) + internal override IFieldSymbol LinkField(RuntimeJavaField fw) { // we should never be called, because all fields on a finished type are already linked Debug.Assert(false); @@ -178,7 +179,7 @@ internal override object[] GetFieldAnnotations(int index) return Metadata.GetFieldAnnotations(metadata, index); } - internal override MethodInfo GetFinalizeMethod() + internal override IMethodSymbol GetFinalizeMethod() { return finalizeMethod; } diff --git a/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.cs b/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.cs index 2964cf197..ffa19a858 100644 --- a/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.cs +++ b/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.cs @@ -27,6 +27,8 @@ Jeroen Frijters using System.Collections.Concurrent; using IKVM.Attributes; +using IKVM.CoreLib.Symbols.Emit; +using IKVM.CoreLib.Symbols; #if IMPORTER using IKVM.Reflection; @@ -54,20 +56,20 @@ private sealed partial class JavaTypeImpl : DynamicImpl readonly RuntimeJavaType host; readonly ClassFile classFile; readonly RuntimeDynamicOrImportJavaType wrapper; - TypeBuilder typeBuilder; + ITypeSymbolBuilder typeBuilder; RuntimeJavaMethod[] methods; RuntimeJavaMethod[][] baseMethods; RuntimeJavaField[] fields; FinishedTypeImpl finishedType; bool finishInProgress; - MethodBuilder clinitMethod; - MethodBuilder finalizeMethod; + IMethodSymbolBuilder clinitMethod; + IMethodSymbolBuilder finalizeMethod; int recursionCount; #if IMPORTER RuntimeByteCodeJavaType enclosingClassWrapper; AnnotationBuilder annotationBuilder; - TypeBuilder enumBuilder; - TypeBuilder privateInterfaceMethods; + ITypeSymbolBuilder enumBuilder; + ITypeSymbolBuilder privateInterfaceMethods; ConcurrentDictionary nestedTypeNames; // only keys are used, values are always null #endif @@ -952,19 +954,16 @@ private static void CheckLoaderConstraints(RuntimeJavaMethod mw, RuntimeJavaMeth } } - private int GetFieldIndex(RuntimeJavaField fw) + int GetFieldIndex(RuntimeJavaField fw) { for (int i = 0; i < fields.Length; i++) - { if (fields[i] == fw) - { return i; - } - } + throw new InvalidOperationException(); } - internal override FieldInfo LinkField(RuntimeJavaField fw) + internal override IFieldSymbol LinkField(RuntimeJavaField fw) { if (fw is RuntimeByteCodePropertyJavaField) { @@ -990,15 +989,9 @@ internal override FieldInfo LinkField(RuntimeJavaField fw) // order, we emit the fields in class declaration order in the .NET metadata (and then when we retrieve them // using .NET reflection, we sort on metadata token.) if (fieldIndex > 0) - { if (!fields[fieldIndex - 1].IsLinked) - { for (int i = 0; i < fieldIndex; i++) - { fields[i].Link(); - } - } - } if (fieldIndex >= classFile.Fields.Length) { @@ -1028,21 +1021,24 @@ internal override FieldInfo LinkField(RuntimeJavaField fw) { fieldAttribs |= FieldAttributes.InitOnly; } + return DefineField(fw.Name, fw.FieldTypeWrapper, fieldAttribs, fw.IsVolatile); } #endif // IMPORTER - FieldBuilder field; - ClassFile.Field fld = classFile.Fields[fieldIndex]; + IFieldSymbolBuilder field; + var fld = classFile.Fields[fieldIndex]; FieldAttributes attribs = 0; - string realFieldName = UnicodeUtil.EscapeInvalidSurrogates(fld.Name); + var realFieldName = UnicodeUtil.EscapeInvalidSurrogates(fld.Name); if (!ReferenceEquals(realFieldName, fld.Name)) { attribs |= FieldAttributes.SpecialName; } - MethodAttributes methodAttribs = MethodAttributes.HideBySig; + + var methodAttribs = MethodAttributes.HideBySig; #if IMPORTER bool setModifiers = fld.IsInternal || (fld.Modifiers & (Modifiers.Synthetic | Modifiers.Enum)) != 0; #endif + if (fld.IsPrivate) { attribs |= FieldAttributes.Private; @@ -1068,6 +1064,7 @@ internal override FieldInfo LinkField(RuntimeJavaField fw) attribs |= FieldAttributes.Static; methodAttribs |= MethodAttributes.Static; } + // NOTE "constant" static finals are converted into literals // TODO it would be possible for Java code to change the value of a non-blank static final, but I don't // know if we want to support this (since the Java JITs don't really support it either) @@ -1138,7 +1135,7 @@ internal override FieldInfo LinkField(RuntimeJavaField fw) return field; } - FieldBuilder DefineField(string name, RuntimeJavaType tw, FieldAttributes attribs, bool isVolatile) + IFieldSymbolBuilder DefineField(string name, RuntimeJavaType tw, FieldAttributes attribs, bool isVolatile) { var modreq = isVolatile ? [wrapper.Context.Types.IsVolatile] : []; return typeBuilder.DefineField(name, tw.TypeAsSignatureType, modreq, wrapper.GetModOpt(tw, false), attribs); @@ -1384,10 +1381,10 @@ sealed class AnnotationBuilder : Annotation readonly RuntimeContext context; JavaTypeImpl impl; - TypeBuilder outer; - TypeBuilder annotationTypeBuilder; - TypeBuilder attributeTypeBuilder; - MethodBuilder defineConstructor; + ITypeSymbolBuilder outer; + ITypeSymbolBuilder annotationTypeBuilder; + ITypeSymbolBuilder attributeTypeBuilder; + IMethodSymbolBuilder defineConstructor; /// /// Initializes a new instance. @@ -1395,7 +1392,7 @@ sealed class AnnotationBuilder : Annotation /// /// /// - internal AnnotationBuilder(RuntimeContext context, JavaTypeImpl o, TypeBuilder outer) + internal AnnotationBuilder(RuntimeContext context, JavaTypeImpl o, ITypeSymbolBuilder outer) { this.context = context; this.impl = o; @@ -1541,28 +1538,25 @@ internal void Link() { // apply any .NET custom attributes that are on the annotation to the custom attribute we synthesize // (for example, to allow AttributeUsageAttribute to be overridden) - Annotation annotation = Annotation.Load(o.wrapper, def); + var annotation = Annotation.Load(o.wrapper, def); if (annotation != null && annotation.IsCustomAttribute) - { annotation.Apply(o.wrapper.ClassLoader, attributeTypeBuilder, def); - } if (def[1].Equals("Lcli/System/AttributeUsageAttribute$Annotation;")) - { hasAttributeUsageAttribute = true; - } } } + if (attributeUsageAttribute != null && !hasAttributeUsageAttribute) { attributeTypeBuilder.SetCustomAttribute(attributeUsageAttribute); } } - defineConstructor = ReflectUtil.DefineConstructor(attributeTypeBuilder, MethodAttributes.Public, new Type[] { context.Resolver.ResolveCoreType(typeof(object).FullName).MakeArrayType().AsReflection() }); + defineConstructor = ReflectUtil.DefineConstructor(attributeTypeBuilder, MethodAttributes.Public, [context.Resolver.ResolveCoreType(typeof(object).FullName).MakeArrayType()]); context.AttributeHelper.SetEditorBrowsableNever(defineConstructor); } - private static Type TypeWrapperToAnnotationParameterType(RuntimeJavaType tw) + static ITypeSymbol TypeWrapperToAnnotationParameterType(RuntimeJavaType tw) { bool isArray = false; if (tw.IsArray) @@ -1570,6 +1564,7 @@ private static Type TypeWrapperToAnnotationParameterType(RuntimeJavaType tw) isArray = true; tw = tw.ElementTypeWrapper; } + if (tw.Annotation != null) { // we don't support Annotation args @@ -1577,7 +1572,7 @@ private static Type TypeWrapperToAnnotationParameterType(RuntimeJavaType tw) } else { - Type argType; + ITypeSymbol argType; if (tw == tw.Context.JavaBase.TypeOfJavaLangClass) { argType = tw.Context.Types.Type; @@ -1594,15 +1589,15 @@ private static Type TypeWrapperToAnnotationParameterType(RuntimeJavaType tw) { argType = tw.TypeAsSignatureType; } + if (isArray) - { argType = RuntimeArrayJavaType.MakeArrayType(argType, 1); - } + return argType; } } - private static bool IsDotNetEnum(RuntimeJavaType tw) + static bool IsDotNetEnum(RuntimeJavaType tw) { return tw.IsFakeNestedType && (tw.Modifiers & Modifiers.Enum) != 0; } @@ -1612,15 +1607,15 @@ internal string AttributeTypeName get { Link(); + if (attributeTypeBuilder != null) - { - return attributeTypeBuilder.FullName; - } + return attributeTypeBuilder.Symbol.FullName; + return null; } } - private static void EmitSetValueCall(RuntimeJavaType annotationAttributeBaseType, CodeEmitter ilgen, string name, RuntimeJavaType tw, int argIndex) + static void EmitSetValueCall(RuntimeJavaType annotationAttributeBaseType, CodeEmitter ilgen, string name, RuntimeJavaType tw, int argIndex) { ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Ldstr, name); @@ -1637,6 +1632,7 @@ private static void EmitSetValueCall(RuntimeJavaType annotationAttributeBaseType { ilgen.Emit(OpCodes.Box, tw.DeclaringTypeWrapper.TypeAsSignatureType); } + var setValueMethod = annotationAttributeBaseType.GetMethodWrapper("setValue", "(Ljava.lang.String;Ljava.lang.Object;)V", false); setValueMethod.Link(); setValueMethod.EmitCall(ilgen); @@ -1683,7 +1679,7 @@ internal void Finish(JavaTypeImpl o) { if (requiredArgCount > 0) { - var args = new Type[requiredArgCount]; + var args = new ITypeSymbol[requiredArgCount]; for (int i = 0, j = 0; i < o.methods.Length; i++) { if (!o.methods[i].IsStatic) @@ -1699,7 +1695,7 @@ internal void Finish(JavaTypeImpl o) context.AttributeHelper.HideFromJava(reqArgConstructor); ilgen = context.CodeEmitterFactory.Create(reqArgConstructor); ilgen.Emit(OpCodes.Ldarg_0); - ilgen.Emit(OpCodes.Call, defaultConstructor); + ilgen.Emit(OpCodes.Call, defaultConstructor.Symbol); for (int i = 0, j = 0; i < o.methods.Length; i++) { @@ -1852,38 +1848,38 @@ internal void Finish(JavaTypeImpl o) private CustomAttributeBuilder MakeCustomAttributeBuilder(RuntimeClassLoader loader, object annotation) { Link(); - ConstructorInfo ctor = defineConstructor != null + var ctor = defineConstructor != null ? defineConstructor.__AsConstructorInfo() - : context.Resolver.ResolveRuntimeType("IKVM.Attributes.DynamicAnnotationAttribute").AsReflection().GetConstructor(new Type[] { context.Types.Object.MakeArrayType() }); + : context.Resolver.ResolveRuntimeType("IKVM.Attributes.DynamicAnnotationAttribute").GetConstructor(new [] { context.Types.Object.MakeArrayType() }); return new CustomAttributeBuilder(ctor, new object[] { AnnotationDefaultAttribute.Escape(QualifyClassNames(loader, annotation)) }); } - internal override void Apply(RuntimeClassLoader loader, TypeBuilder tb, object annotation) + internal override void Apply(RuntimeClassLoader loader, ITypeSymbolBuilder tb, object annotation) { tb.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); } - internal override void Apply(RuntimeClassLoader loader, MethodBuilder mb, object annotation) + internal override void Apply(RuntimeClassLoader loader, IMethodSymbolBuilder mb, object annotation) { mb.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); } - internal override void Apply(RuntimeClassLoader loader, FieldBuilder fb, object annotation) + internal override void Apply(RuntimeClassLoader loader, IFieldSymbolBuilder fb, object annotation) { fb.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); } - internal override void Apply(RuntimeClassLoader loader, ParameterBuilder pb, object annotation) + internal override void Apply(RuntimeClassLoader loader, IParameterSymbolBuilder pb, object annotation) { pb.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); } - internal override void Apply(RuntimeClassLoader loader, AssemblyBuilder ab, object annotation) + internal override void Apply(RuntimeClassLoader loader, IAssemblySymbolBuilder ab, object annotation) { ab.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); } - internal override void Apply(RuntimeClassLoader loader, PropertyBuilder pb, object annotation) + internal override void Apply(RuntimeClassLoader loader, IPropertySymbolBuilder pb, object annotation) { pb.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); } @@ -2365,7 +2361,7 @@ MethodAttributes GetPropertyAccess(RuntimeJavaMethod mw) } } - internal override MethodBase LinkMethod(RuntimeJavaMethod mw) + internal override IMethodBaseSymbol LinkMethod(RuntimeJavaMethod mw) { Debug.Assert(mw != null); @@ -2945,7 +2941,7 @@ private static bool IsAccessBridge(ClassFile classFile, ClassFile.Method m) } #endif // IMPORTER - internal override Type Type + internal override ITypeSymbol Type { get { @@ -3013,7 +3009,7 @@ internal override object[] GetFieldAnnotations(int index) return null; } - internal override MethodInfo GetFinalizeMethod() + internal override IMethodSymbol GetFinalizeMethod() { return finalizeMethod; } diff --git a/src/IKVM.Runtime/RuntimeByteCodeJavaType.cs b/src/IKVM.Runtime/RuntimeByteCodeJavaType.cs index ad900b87f..5eb072d7c 100644 --- a/src/IKVM.Runtime/RuntimeByteCodeJavaType.cs +++ b/src/IKVM.Runtime/RuntimeByteCodeJavaType.cs @@ -27,7 +27,8 @@ Jeroen Frijters using IKVM.Attributes; using IKVM.CoreLib.Diagnostics; - +using IKVM.CoreLib.Symbols; +using IKVM.CoreLib.Symbols.Emit; #if IMPORTER using IKVM.Reflection; @@ -54,12 +55,6 @@ sealed partial class RuntimeByteCodeJavaType : RuntimeJavaType #endif { -#if IMPORTER == false && NETCOREAPP - - static readonly PropertyInfo MetadataTokenInternalPropertyInfo = typeof(MethodBuilder).GetProperty("MetadataTokenInternal", BindingFlags.Instance | BindingFlags.NonPublic); - -#endif - #if IMPORTER protected readonly ImportClassLoader classLoader; #else @@ -72,7 +67,7 @@ sealed partial class RuntimeByteCodeJavaType : RuntimeJavaType #if !IMPORTER byte[][] lineNumberTables; #endif - MethodBase automagicSerializationCtor; + IMethodBaseSymbol automagicSerializationCtor; RuntimeJavaType LoadTypeWrapper(RuntimeClassLoader classLoader, ProtectionDomain pd, ClassFile.ConstantPoolItemClass clazz) { @@ -93,21 +88,19 @@ private static void CheckMissing(RuntimeJavaType prev, RuntimeJavaType tw) #if IMPORTER do { - RuntimeUnloadableJavaType missing = tw as RuntimeUnloadableJavaType; + var missing = tw as RuntimeUnloadableJavaType; if (missing != null) { - Type mt = ReflectUtil.GetMissingType(missing.MissingType); - if (mt.Assembly.__IsMissing) - { + var mt = ReflectUtil.GetMissingType(missing.MissingType); + if (mt.Assembly.IsMissing) throw new FatalCompilerErrorException(DiagnosticEvent.MissingBaseTypeReference(mt.FullName, mt.Assembly.FullName)); - } throw new FatalCompilerErrorException(DiagnosticEvent.MissingBaseType(mt.FullName, mt.Assembly.FullName, prev.TypeAsBaseType.FullName, prev.TypeAsBaseType.Module.Name)); } + foreach (RuntimeJavaType iface in tw.Interfaces) - { CheckMissing(tw, iface); - } + prev = tw; tw = tw.BaseTypeWrapper; } @@ -351,7 +344,7 @@ internal override RuntimeJavaType DeclaringTypeWrapper } } - internal override Type TypeAsTBD + internal override ITypeSymbol TypeAsTBD { get { @@ -408,7 +401,7 @@ static bool TypesMatchForOverride(RuntimeJavaType tw1, RuntimeJavaType tw2) return false; } - void GenerateOverrideStub(TypeBuilder typeBuilder, RuntimeJavaMethod baseMethod, MethodInfo target, RuntimeJavaMethod targetMethod) + void GenerateOverrideStub(ITypeSymbolBuilder typeBuilder, RuntimeJavaMethod baseMethod, IMethodSymbol target, RuntimeJavaMethod targetMethod) { Debug.Assert(!baseMethod.HasCallerID); @@ -587,9 +580,9 @@ protected static void GetParameterNamesFromSig(string sig, string[] parameterNam parameterNames[i] = names[i]; } - protected static ParameterBuilder[] GetParameterBuilders(MethodBuilder mb, int parameterCount, string[] parameterNames) + protected static IParameterSymbolBuilder[] GetParameterBuilders(IMethodSymbolBuilder mb, int parameterCount, string[] parameterNames) { - var parameterBuilders = new ParameterBuilder[parameterCount]; + var parameterBuilders = new IParameterSymbolBuilder[parameterCount]; Dictionary clashes = null; for (int i = 0; i < parameterBuilders.Length; i++) { @@ -609,8 +602,10 @@ protected static ParameterBuilder[] GetParameterBuilders(MethodBuilder mb, int p name += clash; } } - parameterBuilders[i] = mb.DefineParameter(i + 1, ParameterAttributes.None, name); + + parameterBuilders[i] = mb.DefineParameter(i + 1, System.Reflection.ParameterAttributes.None, name); } + return parameterBuilders; } @@ -641,67 +636,57 @@ private static string GetParameterName(string type) protected abstract bool EmitMapXmlMethodPrologueAndOrBody(CodeEmitter ilgen, ClassFile f, ClassFile.Method m); - protected abstract void EmitMapXmlMetadata(TypeBuilder typeBuilder, ClassFile classFile, RuntimeJavaField[] fields, RuntimeJavaMethod[] methods); + protected abstract void EmitMapXmlMetadata(ITypeSymbolBuilder typeBuilder, ClassFile classFile, RuntimeJavaField[] fields, RuntimeJavaMethod[] methods); - protected abstract MethodBuilder DefineGhostMethod(TypeBuilder typeBuilder, string name, MethodAttributes attribs, RuntimeJavaMethod mw); + protected abstract MethodBuilder DefineGhostMethod(ITypeSymbolBuilder typeBuilder, string name, System.Reflection.MethodAttributes attribs, RuntimeJavaMethod mw); - protected abstract void FinishGhost(TypeBuilder typeBuilder, RuntimeJavaMethod[] methods); + protected abstract void FinishGhost(ITypeSymbolBuilder typeBuilder, RuntimeJavaMethod[] methods); protected abstract void FinishGhostStep2(); - protected abstract TypeBuilder DefineGhostType(string mangledTypeName, TypeAttributes typeAttribs); + protected abstract TypeBuilder DefineGhostType(string mangledTypeName, System.Reflection.TypeAttributes typeAttribs); #endif // IMPORTER private bool IsPInvokeMethod(ClassFile.Method m) { #if IMPORTER - Dictionary mapxml = classLoader.GetMapXmlClasses(); + var mapxml = classLoader.GetMapXmlClasses(); if (mapxml != null) { - IKVM.Tools.Importer.MapXml.Class clazz; - if (mapxml.TryGetValue(this.Name, out clazz) && clazz.Methods != null) + if (mapxml.TryGetValue(this.Name, out var clazz) && clazz.Methods != null) { foreach (IKVM.Tools.Importer.MapXml.Method method in clazz.Methods) { if (method.Name == m.Name && method.Sig == m.Signature) { if (method.Attributes != null) - { foreach (IKVM.Tools.Importer.MapXml.Attribute attr in method.Attributes) - { if (Context.StaticCompiler.GetType(classLoader, attr.Type) == Context.Resolver.ResolveCoreType(typeof(System.Runtime.InteropServices.DllImportAttribute).FullName).AsReflection()) - { return true; - } - } - } + break; } } } } #endif + if (m.Annotations != null) - { foreach (object[] annot in m.Annotations) - { if ("Lcli/System/Runtime/InteropServices/DllImportAttribute$Annotation;".Equals(annot[1])) - { return true; - } - } - } + return false; } - internal override MethodBase LinkMethod(RuntimeJavaMethod mw) + internal override IMethodBaseSymbol LinkMethod(RuntimeJavaMethod mw) { mw.AssertLinked(); return impl.LinkMethod(mw); } - internal override FieldInfo LinkField(RuntimeJavaField fw) + internal override IFieldSymbol LinkField(RuntimeJavaField fw) { fw.AssertLinked(); return impl.LinkField(fw); @@ -719,42 +704,33 @@ internal override string GetGenericSignature() internal override string GetGenericMethodSignature(RuntimeJavaMethod mw) { - RuntimeJavaMethod[] methods = GetMethods(); + var methods = GetMethods(); for (int i = 0; i < methods.Length; i++) - { if (methods[i] == mw) - { return impl.GetGenericMethodSignature(i); - } - } + Debug.Fail("Unreachable code"); return null; } internal override string GetGenericFieldSignature(RuntimeJavaField fw) { - RuntimeJavaField[] fields = GetFields(); + var fields = GetFields(); for (int i = 0; i < fields.Length; i++) - { if (fields[i] == fw) - { return impl.GetGenericFieldSignature(i); - } - } + Debug.Fail("Unreachable code"); return null; } internal override MethodParametersEntry[] GetMethodParameters(RuntimeJavaMethod mw) { - RuntimeJavaMethod[] methods = GetMethods(); + var methods = GetMethods(); for (int i = 0; i < methods.Length; i++) - { if (methods[i] == mw) - { return impl.GetMethodParameters(i); - } - } + Debug.Fail("Unreachable code"); return null; } @@ -780,30 +756,9 @@ internal override string GetSourceFileName() /// /// /// - int GetMethodBaseToken(MethodBase mb) + int GetMethodBaseToken(IMethodBaseSymbol mb) { - if (mb is MethodBuilder mbld) - { -#if NETFRAMEWORK - return mbld.GetToken().Token; -#else - try - { - return mbld.GetMetadataToken(); - } - catch (InvalidOperationException) - { - if (MetadataTokenInternalPropertyInfo != null) - return (int)MetadataTokenInternalPropertyInfo.GetValue(mbld); - } -#endif - } - -#if NETFRAMEWORK return mb.MetadataToken; -#else - return mb.GetMetadataToken(); -#endif } /// @@ -812,7 +767,7 @@ int GetMethodBaseToken(MethodBase mb) /// /// /// - internal override int GetSourceLineNumber(MethodBase mb, int ilOffset) + internal override int GetSourceLineNumber(IMethodBaseSymbol mb, int ilOffset) { if (lineNumberTables != null) { @@ -858,76 +813,71 @@ internal override object[] GetDeclaredAnnotations() internal override object[] GetMethodAnnotations(RuntimeJavaMethod mw) { - RuntimeJavaMethod[] methods = GetMethods(); + var methods = GetMethods(); for (int i = 0; i < methods.Length; i++) - { if (methods[i] == mw) - { return DecodeAnnotations(impl.GetMethodAnnotations(i)); - } - } + Debug.Fail("Unreachable code"); return null; } internal override object[][] GetParameterAnnotations(RuntimeJavaMethod mw) { - RuntimeJavaMethod[] methods = GetMethods(); + var methods = GetMethods(); for (int i = 0; i < methods.Length; i++) { if (methods[i] == mw) { - object[][] annotations = impl.GetParameterAnnotations(i); + var annotations = impl.GetParameterAnnotations(i); if (annotations != null) { object[][] objs = new object[annotations.Length][]; for (int j = 0; j < annotations.Length; j++) - { objs[j] = DecodeAnnotations(annotations[j]); - } + return objs; } + return null; } } + Debug.Fail("Unreachable code"); return null; } internal override object[] GetFieldAnnotations(RuntimeJavaField fw) { - RuntimeJavaField[] fields = GetFields(); + var fields = GetFields(); for (int i = 0; i < fields.Length; i++) - { if (fields[i] == fw) - { return DecodeAnnotations(impl.GetFieldAnnotations(i)); - } - } + Debug.Fail("Unreachable code"); return null; } internal override object GetAnnotationDefault(RuntimeJavaMethod mw) { - RuntimeJavaMethod[] methods = GetMethods(); + var methods = GetMethods(); for (int i = 0; i < methods.Length; i++) { if (methods[i] == mw) { - object defVal = impl.GetMethodDefaultValue(i); + var defVal = impl.GetMethodDefaultValue(i); if (defVal != null) - { return JVM.NewAnnotationElementValue(mw.DeclaringType.ClassLoader.GetJavaClassLoader(), mw.ReturnType.ClassObject, defVal); - } + return null; } } + Debug.Fail("Unreachable code"); return null; } - private Type GetBaseTypeForDefineType() + private ITypeSymbol GetBaseTypeForDefineType() { return BaseTypeWrapper.TypeAsBaseType; } @@ -936,7 +886,7 @@ private Type GetBaseTypeForDefineType() #if IMPORTER - protected virtual Type GetBaseTypeForDefineType() + protected virtual ITypeSymbol GetBaseTypeForDefineType() { return BaseTypeWrapper.TypeAsBaseType; } @@ -948,33 +898,31 @@ internal virtual RuntimeJavaMethod[] GetReplacedMethodsFor(RuntimeJavaMethod mw) #endif // IMPORTER - internal override MethodBase GetSerializationConstructor() + internal override IMethodBaseSymbol GetSerializationConstructor() { return automagicSerializationCtor; } - private Type[] GetModOpt(RuntimeJavaType tw, bool mustBePublic) + private ITypeSymbol[] GetModOpt(RuntimeJavaType tw, bool mustBePublic) { return GetModOpt(ClassLoader.GetTypeWrapperFactory(), tw, mustBePublic); } - internal static Type[] GetModOpt(RuntimeJavaTypeFactory context, RuntimeJavaType tw, bool mustBePublic) + internal static ITypeSymbol[] GetModOpt(RuntimeJavaTypeFactory context, RuntimeJavaType tw, bool mustBePublic) { - Type[] modopt = []; + ITypeSymbol[] modopt = []; if (tw.IsUnloadable) { if (((RuntimeUnloadableJavaType)tw).MissingType == null) - { - modopt = new Type[] { ((RuntimeUnloadableJavaType)tw).GetCustomModifier(context) }; - } + modopt = new ITypeSymbol[] { ((RuntimeUnloadableJavaType)tw).GetCustomModifier(context) }; } else { - RuntimeJavaType tw1 = tw.IsArray ? tw.GetUltimateElementTypeWrapper() : tw; + var tw1 = tw.IsArray ? tw.GetUltimateElementTypeWrapper() : tw; if (tw1.IsErasedOrBoxedPrimitiveOrRemapped || tw.IsGhostArray || (mustBePublic && !tw1.IsPublic)) { // FXBUG Ref.Emit refuses arrays in custom modifiers, so we add an array type for each dimension - modopt = new Type[tw.ArrayRank + 1]; + modopt = new ITypeSymbol[tw.ArrayRank + 1]; modopt[0] = GetModOptHelper(tw1); for (int i = 1; i < modopt.Length; i++) { @@ -985,9 +933,10 @@ internal static Type[] GetModOpt(RuntimeJavaTypeFactory context, RuntimeJavaType return modopt; } - private static Type GetModOptHelper(RuntimeJavaType tw) + static ITypeSymbol GetModOptHelper(RuntimeJavaType tw) { Debug.Assert(!tw.IsUnloadable); + if (tw.IsArray) { return RuntimeArrayJavaType.MakeArrayType(GetModOptHelper(tw.GetUltimateElementTypeWrapper()), tw.ArrayRank); @@ -1003,7 +952,8 @@ private static Type GetModOptHelper(RuntimeJavaType tw) } #if IMPORTER - private bool NeedsType2AccessStub(RuntimeJavaField fw) + + bool NeedsType2AccessStub(RuntimeJavaField fw) { Debug.Assert(this.IsPublic && fw.DeclaringType == this); return fw.IsType2FinalField @@ -1011,6 +961,7 @@ private bool NeedsType2AccessStub(RuntimeJavaField fw) && (fw.IsPublic || (fw.IsProtected && !this.IsFinal)) && (fw.FieldTypeWrapper.IsUnloadable || fw.FieldTypeWrapper.IsAccessibleFrom(this) || fw.FieldTypeWrapper.InternalsVisibleTo(this))); } + #endif internal static bool RequiresDynamicReflectionCallerClass(string classFile, string method, string signature) @@ -1074,6 +1025,7 @@ internal void EmitLevel4Warning(HardError error, string message) } #endif } + } } \ No newline at end of file diff --git a/src/IKVM.Runtime/RuntimeByteCodePropertyJavaField.cs b/src/IKVM.Runtime/RuntimeByteCodePropertyJavaField.cs index 00a6b1c0a..877505558 100644 --- a/src/IKVM.Runtime/RuntimeByteCodePropertyJavaField.cs +++ b/src/IKVM.Runtime/RuntimeByteCodePropertyJavaField.cs @@ -21,16 +21,13 @@ Jeroen Frijters jeroen@frijters.net */ -using System; - -using IKVM.CoreLib.Diagnostics; +using IKVM.CoreLib.Symbols.Emit; #if IMPORTER || EXPORTER using IKVM.Reflection; using IKVM.Reflection.Emit; using Type = IKVM.Reflection.Type; - #else using System.Reflection; using System.Reflection.Emit; @@ -53,7 +50,7 @@ sealed class RuntimeByteCodePropertyJavaField : RuntimeJavaField readonly RuntimeJavaMethod getter; readonly RuntimeJavaMethod setter; - PropertyBuilder pb; + IPropertySymbolBuilder pb; RuntimeJavaMethod GetMethod(string name, string sig, bool isstatic) { @@ -94,31 +91,25 @@ internal override void ResolveField() #endif - internal PropertyBuilder GetPropertyBuilder() + internal IPropertySymbolBuilder GetPropertyBuilder() { AssertLinked(); return pb; } - internal void DoLink(TypeBuilder tb) + internal void DoLink(ITypeSymbolBuilder tb) { if (getter != null) - { getter.Link(); - } if (setter != null) - { setter.Link(); - } - pb = tb.DefineProperty(this.Name, PropertyAttributes.None, this.FieldTypeWrapper.TypeAsSignatureType, []); + + pb = tb.DefineProperty(Name, PropertyAttributes.None, FieldTypeWrapper.TypeAsSignatureType, []); if (getter != null) - { - pb.SetGetMethod((MethodBuilder)getter.GetMethod()); - } + pb.SetGetMethod((IMethodSymbolBuilder)getter.GetMethod()); if (setter != null) - { - pb.SetSetMethod((MethodBuilder)setter.GetMethod()); - } + pb.SetSetMethod((IMethodSymbolBuilder)setter.GetMethod()); + #if IMPORTER DeclaringType.Context.AttributeHelper.SetModifiers(pb, this.Modifiers, this.IsInternal); #endif @@ -147,7 +138,7 @@ internal static void EmitThrowNoSuchMethodErrorForGetter(CodeEmitter ilgen, Runt type.ClassLoader.Diagnostics.EmittedNoSuchMethodError("", member.DeclaringType.Name + "." + member.Name + member.Signature); #endif // HACK the branch around the throw is to keep the verifier happy - CodeEmitterLabel label = ilgen.DefineLabel(); + var label = ilgen.DefineLabel(); ilgen.Emit(OpCodes.Ldc_I4_0); ilgen.EmitBrtrue(label); ilgen.EmitThrow("java.lang.NoSuchMethodError"); @@ -192,7 +183,7 @@ internal static void EmitThrowNoSuchMethodErrorForSetter(CodeEmitter ilgen, Runt member.DeclaringType.ClassLoader.Diagnostics.EmittedNoSuchMethodError("", member.DeclaringType.Name + "." + member.Name + member.Signature); #endif // HACK the branch around the throw is to keep the verifier happy - CodeEmitterLabel label = ilgen.DefineLabel(); + var label = ilgen.DefineLabel(); ilgen.Emit(OpCodes.Ldc_I4_0); ilgen.EmitBrtrue(label); ilgen.EmitThrow("java.lang.NoSuchMethodError"); @@ -206,23 +197,23 @@ internal static void EmitThrowNoSuchMethodErrorForSetter(CodeEmitter ilgen, Runt #endif #if !IMPORTER && !FIRST_PASS + internal override object GetValue(object obj) { if (getter == null) - { throw new java.lang.NoSuchMethodError(); - } + return getter.Invoke(obj, []); } internal override void SetValue(object obj, object value) { if (setter == null) - { throw new java.lang.NoSuchMethodError(); - } + setter.Invoke(obj, new object[] { value }); } + #endif } diff --git a/src/IKVM.Runtime/RuntimeClassLoader.cs b/src/IKVM.Runtime/RuntimeClassLoader.cs index 03a426852..e2d095ec1 100644 --- a/src/IKVM.Runtime/RuntimeClassLoader.cs +++ b/src/IKVM.Runtime/RuntimeClassLoader.cs @@ -27,6 +27,7 @@ Jeroen Frijters using System.Diagnostics; using System.Threading; +using IKVM.CoreLib.Symbols; using IKVM.Runtime.Accessors.Java.Lang; using IKVM.CoreLib.Diagnostics; @@ -99,7 +100,7 @@ internal RuntimeClassLoader(RuntimeContext context, CodeGenOptions codegenoption #if IMPORTER || EXPORTER - internal void SetRemappedType(Type type, RuntimeJavaType tw) + internal void SetRemappedType(ITypeSymbol type, RuntimeJavaType tw) { lock (types) types.Add(tw.Name, tw); @@ -541,7 +542,7 @@ internal RuntimeJavaType FindOrLoadGenericClass(string name, LoadMode mode) } } - var typeArguments = new Type[typeParamNames.Count]; + var typeArguments = new ITypeSymbol[typeParamNames.Count]; for (int i = 0; i < typeArguments.Length; i++) { var s = typeParamNames[i]; @@ -741,13 +742,13 @@ internal virtual java.lang.ClassLoader GetJavaClassLoader() /// . /// /// - internal Type[] ArgTypeListFromSig(string signature) + internal ITypeSymbol[] ArgTypeListFromSig(string signature) { if (signature[1] == ')') return []; var javaTypes = ArgJavaTypeListFromSig(signature, LoadMode.LoadOrThrow); - var types = new Type[javaTypes.Length]; + var types = new ITypeSymbol[javaTypes.Length]; for (int i = 0; i < javaTypes.Length; i++) types[i] = javaTypes[i].TypeAsSignatureType; diff --git a/src/IKVM.Runtime/RuntimeClassLoaderFactory.cs b/src/IKVM.Runtime/RuntimeClassLoaderFactory.cs index c84a9c54c..f47f336ec 100644 --- a/src/IKVM.Runtime/RuntimeClassLoaderFactory.cs +++ b/src/IKVM.Runtime/RuntimeClassLoaderFactory.cs @@ -263,22 +263,23 @@ internal RuntimeJavaType GetJavaTypeFromType(ITypeSymbol type) internal RuntimeClassLoader GetGenericClassLoader(RuntimeJavaType wrapper) { - Type type = wrapper.TypeAsTBD; + var type = wrapper.TypeAsTBD; Debug.Assert(type.IsGenericType); Debug.Assert(!type.ContainsGenericParameters); - List list = new List(); + var list = new List(); list.Add(context.AssemblyClassLoaderFactory.FromAssembly(type.Assembly)); - foreach (Type arg in type.GetGenericArguments()) + foreach (var arg in type.GetGenericArguments()) { - RuntimeClassLoader loader = GetJavaTypeFromType(arg).ClassLoader; + var loader = GetJavaTypeFromType(arg).ClassLoader; if (!list.Contains(loader) && loader != bootstrapClassLoader) { list.Add(loader); } } - RuntimeClassLoader[] key = list.ToArray(); - RuntimeClassLoader matchingLoader = GetGenericClassLoaderByKey(key); + + var key = list.ToArray(); + var matchingLoader = GetGenericClassLoaderByKey(key); matchingLoader.RegisterInitiatingLoader(wrapper); return matchingLoader; } @@ -307,7 +308,7 @@ RuntimeClassLoader GetGenericClassLoaderByKey(RuntimeClassLoader[] key) { lock (wrapperLock) { - foreach (RuntimeGenericClassLoader loader in genericClassLoaders) + foreach (var loader in genericClassLoaders) if (loader.Matches(key)) return loader; @@ -389,9 +390,9 @@ internal RuntimeClassLoader GetAssemblyClassLoaderByName(string name) return GetGenericClassLoaderByName(name); #if NETFRAMEWORK - return context.AssemblyClassLoaderFactory.FromAssembly(Assembly.Load(name)); + return context.AssemblyClassLoaderFactory.FromAssembly(context.Resolver.ResolveAssembly( Assembly.Load(name))); #else - return context.AssemblyClassLoaderFactory.FromAssembly(AssemblyLoadContext.GetLoadContext(typeof(RuntimeClassLoader).Assembly).LoadFromAssemblyName(new AssemblyName(name))); + return context.AssemblyClassLoaderFactory.FromAssembly(context.Resolver.ResolveAssembly(AssemblyLoadContext.GetLoadContext(typeof(RuntimeClassLoader).Assembly).LoadFromAssemblyName(new AssemblyName(name)))); #endif } @@ -409,7 +410,7 @@ internal RuntimeClassLoader GetGenericClassLoaderById(int id) return genericClassLoaders[id]; } - internal void SetWrapperForType(Type type, RuntimeJavaType wrapper) + internal void SetWrapperForType(ITypeSymbol type, RuntimeJavaType wrapper) { #if !IMPORTER RuntimeJavaType.AssertFinished(type); diff --git a/src/IKVM.Runtime/RuntimeGhostJavaMethod.cs b/src/IKVM.Runtime/RuntimeGhostJavaMethod.cs index 894722bc2..e986d0822 100644 --- a/src/IKVM.Runtime/RuntimeGhostJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimeGhostJavaMethod.cs @@ -25,6 +25,7 @@ Jeroen Frijters using IKVM.Attributes; using IKVM.CoreLib.Symbols; +using IKVM.CoreLib.Symbols.Emit; #if IMPORTER || EXPORTER using IKVM.Reflection; @@ -67,12 +68,12 @@ internal RuntimeGhostJavaMethod(RuntimeJavaType declaringType, string name, stri protected override void CallImpl(CodeEmitter ilgen) { - ilgen.Emit(OpCodes.Call, defaultImpl); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, defaultImpl); } protected override void CallvirtImpl(CodeEmitter ilgen) { - ilgen.Emit(OpCodes.Call, ghostMethod); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, ghostMethod); } #endif @@ -99,14 +100,14 @@ internal IMethodSymbol GetDefaultImpl() #if IMPORTER - internal void SetGhostMethod(MethodBuilder mb) + internal void SetGhostMethod(IMethodSymbolBuilder mb) { - this.ghostMethod = mb; + this.ghostMethod = mb.Symbol; } - internal MethodBuilder GetGhostMethod() + internal IMethodSymbolBuilder GetGhostMethod() { - return (MethodBuilder)ghostMethod.AsReflection(); + return ghostMethod.Builder; } #endif diff --git a/src/IKVM.Runtime/RuntimeJavaTypeFactory.cs b/src/IKVM.Runtime/RuntimeJavaTypeFactory.cs index 1da4591ce..9d65d5183 100644 --- a/src/IKVM.Runtime/RuntimeJavaTypeFactory.cs +++ b/src/IKVM.Runtime/RuntimeJavaTypeFactory.cs @@ -24,6 +24,7 @@ Jeroen Frijters using System.Collections.Generic; using IKVM.CoreLib.Symbols; +using IKVM.CoreLib.Symbols.Emit; #if IMPORTER || EXPORTER using IKVM.Reflection.Emit; @@ -43,7 +44,7 @@ namespace IKVM.Runtime abstract class RuntimeJavaTypeFactory { - internal abstract ModuleBuilder ModuleBuilder { get; } + internal abstract IModuleSymbolBuilder ModuleBuilder { get; } internal abstract RuntimeJavaType DefineClassImpl(Dictionary types, RuntimeJavaType host, ClassFile f, RuntimeClassLoader classLoader, ProtectionDomain protectionDomain); diff --git a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.RemappedJavaType.cs b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.RemappedJavaType.cs index 8e03fb335..ed369d2fe 100644 --- a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.RemappedJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.RemappedJavaType.cs @@ -27,7 +27,6 @@ Jeroen Frijters using IKVM.Attributes; using IKVM.CoreLib.Symbols; - #if IMPORTER || EXPORTER using IKVM.Reflection; using IKVM.Reflection.Emit; @@ -149,11 +148,11 @@ RuntimeJavaMethod CreateRemappedMethodWrapper(IMethodBaseSymbol mb, HideFromJava for (int i = 0; i < parameters.Length; i++) argTypes[i + 1] = parameters[i].ParameterType; - var helper = type.GetMethod("instancehelper_" + mb.Name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static, null, argTypes, null); + var helper = type.GetMethod("instancehelper_" + mb.Name, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static, argTypes); if (helper != null) mbHelper = helper; - mbNonvirtualHelper = type.GetMethod("nonvirtualhelper/" + mb.Name, BindingFlags.NonPublic | BindingFlags.Static, null, argTypes, null); + mbNonvirtualHelper = type.GetMethod("nonvirtualhelper/" + mb.Name, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static, argTypes); } return new RemappedJavaMethod(this, name, sig, mb, retType, paramTypes, modifiers, hideFromReflection, mbHelper, mbNonvirtualHelper); diff --git a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs index a0a349676..f3cdaf1c5 100644 --- a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs @@ -24,25 +24,20 @@ Jeroen Frijters using System; using System.Collections.Generic; using System.Diagnostics; +using System.Linq; using IKVM.CoreLib.Diagnostics; +using IKVM.CoreLib.Symbols; using IKVM.Attributes; using IKVM.Runtime.Syntax; using IKVM.ByteCode; -using IKVM.CoreLib.Symbols; -using com.sun.org.apache.bcel.@internal.generic; -using System.Linq; - - - +using IKVM.CoreLib.Symbols.Emit; #if IMPORTER || EXPORTER using IKVM.Reflection; using IKVM.Reflection.Emit; using Type = IKVM.Reflection.Type; -using System.Runtime.Serialization.Formatters; - #else using System.Reflection; using System.Reflection.Emit; @@ -1198,40 +1193,40 @@ internal sealed class CompiledAnnotation : Annotation internal CompiledAnnotation(RuntimeContext context, ITypeSymbol type) { this.context = context ?? throw new ArgumentNullException(nameof(context)); - constructor = type.GetConstructor(new ITypeSymbol[] { context.Resolver.ResolveCoreType(typeof(object).FullName).MakeArrayType() }); + constructor = type.GetConstructor([context.Resolver.ResolveCoreType(typeof(object).FullName).MakeArrayType()]); } - private CustomAttributeBuilder MakeCustomAttributeBuilder(RuntimeClassLoader loader, object annotation) + private ICustomAttributeBuilder MakeCustomAttributeBuilder(RuntimeClassLoader loader, object annotation) { - return new CustomAttributeBuilder(constructor, new object[] { AnnotationDefaultAttribute.Escape(QualifyClassNames(loader, annotation)) }); + return context.Resolver.Symbols.CreateCustomAttribute(constructor, [AnnotationDefaultAttribute.Escape(QualifyClassNames(loader, annotation))]); } - internal override void Apply(RuntimeClassLoader loader, TypeBuilder tb, object annotation) + internal override void Apply(RuntimeClassLoader loader, ITypeSymbolBuilder tb, object annotation) { tb.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); } - internal override void Apply(RuntimeClassLoader loader, MethodBuilder mb, object annotation) + internal override void Apply(RuntimeClassLoader loader, IMethodSymbolBuilder mb, object annotation) { mb.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); } - internal override void Apply(RuntimeClassLoader loader, FieldBuilder fb, object annotation) + internal override void Apply(RuntimeClassLoader loader, IFieldSymbolBuilder fb, object annotation) { fb.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); } - internal override void Apply(RuntimeClassLoader loader, ParameterBuilder pb, object annotation) + internal override void Apply(RuntimeClassLoader loader, IParameterSymbolBuilder pb, object annotation) { pb.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); } - internal override void Apply(RuntimeClassLoader loader, AssemblyBuilder ab, object annotation) + internal override void Apply(RuntimeClassLoader loader, IAssemblySymbolBuilder ab, object annotation) { ab.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); } - internal override void Apply(RuntimeClassLoader loader, PropertyBuilder pb, object annotation) + internal override void Apply(RuntimeClassLoader loader, IPropertySymbolBuilder pb, object annotation) { pb.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); } diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.MultipleAnnotationJavaType.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.MultipleAnnotationJavaType.cs index b96ed3f2d..d5b164b58 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.MultipleAnnotationJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.MultipleAnnotationJavaType.cs @@ -23,6 +23,9 @@ Jeroen Frijters */ using System; +using IKVM.CoreLib.Symbols; +using IKVM.CoreLib.Symbols.Emit; + #if IMPORTER || EXPORTER using IKVM.Reflection.Emit; @@ -43,7 +46,7 @@ sealed partial class AttributeAnnotationJavaType sealed class MultipleAnnotationJavaType : AttributeAnnotationJavaTypeBase { - readonly Type annotationType; + readonly ITypeSymbol annotationType; readonly AttributeAnnotationJavaType declaringType; internal MultipleAnnotationJavaType(RuntimeContext context, AttributeAnnotationJavaType declaringType) : @@ -60,19 +63,21 @@ internal MultipleAnnotationJavaType(RuntimeContext context, AttributeAnnotationJ protected override void LazyPublishMembers() { RuntimeJavaType tw = declaringType.MakeArrayType(1); - SetMethods(new RuntimeJavaMethod[] { new DynamicOnlyJavaMethod(this, "value", "()" + tw.SigName, tw, Array.Empty(), MemberFlags.None) }); - SetFields(Array.Empty()); + SetMethods([new DynamicOnlyJavaMethod(this, "value", "()" + tw.SigName, tw, [], MemberFlags.None)]); + SetFields([]); } internal override RuntimeJavaType DeclaringTypeWrapper => declaringType; - internal override Type TypeAsTBD => annotationType; + internal override ITypeSymbol TypeAsTBD => annotationType; #if !IMPORTER && !EXPORTER + internal override object[] GetDeclaredAnnotations() { return declaringType.GetDeclaredAnnotations(); } + #endif sealed class MultipleAnnotation : Annotation @@ -107,7 +112,7 @@ static object[] UnwrapArray(object annotation) return []; } - internal override void Apply(RuntimeClassLoader loader, MethodBuilder mb, object annotation) + internal override void Apply(RuntimeClassLoader loader, IMethodSymbolBuilder mb, object annotation) { Annotation annot = type.Annotation; foreach (object ann in UnwrapArray(annotation)) @@ -116,7 +121,7 @@ internal override void Apply(RuntimeClassLoader loader, MethodBuilder mb, object } } - internal override void Apply(RuntimeClassLoader loader, AssemblyBuilder ab, object annotation) + internal override void Apply(RuntimeClassLoader loader, IAssemblySymbolBuilder ab, object annotation) { Annotation annot = type.Annotation; foreach (object ann in UnwrapArray(annotation)) @@ -125,7 +130,7 @@ internal override void Apply(RuntimeClassLoader loader, AssemblyBuilder ab, obje } } - internal override void Apply(RuntimeClassLoader loader, FieldBuilder fb, object annotation) + internal override void Apply(RuntimeClassLoader loader, IFieldSymbolBuilder fb, object annotation) { Annotation annot = type.Annotation; foreach (object ann in UnwrapArray(annotation)) @@ -134,7 +139,7 @@ internal override void Apply(RuntimeClassLoader loader, FieldBuilder fb, object } } - internal override void Apply(RuntimeClassLoader loader, ParameterBuilder pb, object annotation) + internal override void Apply(RuntimeClassLoader loader, IParameterSymbolBuilder pb, object annotation) { Annotation annot = type.Annotation; foreach (object ann in UnwrapArray(annotation)) @@ -143,7 +148,7 @@ internal override void Apply(RuntimeClassLoader loader, ParameterBuilder pb, obj } } - internal override void Apply(RuntimeClassLoader loader, TypeBuilder tb, object annotation) + internal override void Apply(RuntimeClassLoader loader, ITypeSymbolBuilder tb, object annotation) { Annotation annot = type.Annotation; foreach (object ann in UnwrapArray(annotation)) @@ -152,7 +157,7 @@ internal override void Apply(RuntimeClassLoader loader, TypeBuilder tb, object a } } - internal override void Apply(RuntimeClassLoader loader, PropertyBuilder pb, object annotation) + internal override void Apply(RuntimeClassLoader loader, IPropertySymbolBuilder pb, object annotation) { Annotation annot = type.Annotation; foreach (object ann in UnwrapArray(annotation)) diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.ReturnValueAnnotationJavaType.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.ReturnValueAnnotationJavaType.cs index d7044a980..81e268fd7 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.ReturnValueAnnotationJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.ReturnValueAnnotationJavaType.cs @@ -24,6 +24,8 @@ Jeroen Frijters using System; using IKVM.Attributes; +using IKVM.CoreLib.Symbols; +using IKVM.CoreLib.Symbols.Emit; #if IMPORTER || EXPORTER using IKVM.Reflection; @@ -51,7 +53,7 @@ sealed partial class AttributeAnnotationJavaType sealed class ReturnValueAnnotationJavaType : AttributeAnnotationJavaTypeBase { - readonly Type fakeType; + readonly ITypeSymbol fakeType; readonly AttributeAnnotationJavaType declaringType; /// @@ -81,7 +83,7 @@ protected override void LazyPublishMembers() internal override RuntimeJavaType DeclaringTypeWrapper => declaringType; - internal override Type TypeAsTBD => fakeType; + internal override ITypeSymbol TypeAsTBD => fakeType; #if !IMPORTER && !FIRST_PASS && !EXPORTER @@ -113,7 +115,7 @@ internal ReturnValueAnnotation(AttributeAnnotationJavaType type) this.type = type; } - internal override void ApplyReturnValue(RuntimeClassLoader loader, MethodBuilder mb, ref ParameterBuilder pb, object annotation) + internal override void ApplyReturnValue(RuntimeClassLoader loader, IMethodSymbolBuilder mb, ref IParameterSymbolBuilder pb, object annotation) { // TODO make sure the descriptor is correct var ann = type.Annotation; @@ -122,7 +124,7 @@ internal override void ApplyReturnValue(RuntimeClassLoader loader, MethodBuilder { if ("value".Equals(arr[i])) { - pb ??= mb.DefineParameter(0, ParameterAttributes.None, null); + pb ??= mb.DefineParameter(0, System.Reflection.ParameterAttributes.None, null); var value = (object[])arr[i + 1]; if (value[0].Equals(AnnotationDefaultAttribute.TAG_ANNOTATION)) @@ -136,32 +138,32 @@ internal override void ApplyReturnValue(RuntimeClassLoader loader, MethodBuilder } } - internal override void Apply(RuntimeClassLoader loader, MethodBuilder mb, object annotation) + internal override void Apply(RuntimeClassLoader loader, IMethodSymbolBuilder mb, object annotation) { } - internal override void Apply(RuntimeClassLoader loader, AssemblyBuilder ab, object annotation) + internal override void Apply(RuntimeClassLoader loader, IAssemblySymbolBuilder ab, object annotation) { } - internal override void Apply(RuntimeClassLoader loader, FieldBuilder fb, object annotation) + internal override void Apply(RuntimeClassLoader loader, IFieldSymbolBuilder fb, object annotation) { } - internal override void Apply(RuntimeClassLoader loader, ParameterBuilder pb, object annotation) + internal override void Apply(RuntimeClassLoader loader, IParameterSymbolBuilder pb, object annotation) { } - internal override void Apply(RuntimeClassLoader loader, TypeBuilder tb, object annotation) + internal override void Apply(RuntimeClassLoader loader, ITypeSymbolBuilder tb, object annotation) { } - internal override void Apply(RuntimeClassLoader loader, PropertyBuilder pb, object annotation) + internal override void Apply(RuntimeClassLoader loader, IPropertySymbolBuilder pb, object annotation) { } diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.cs index a4867ea4d..6b2a6272b 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.cs @@ -26,7 +26,7 @@ Jeroen Frijters using IKVM.CoreLib.Diagnostics; using IKVM.CoreLib.Symbols; - +using IKVM.CoreLib.Symbols.Emit; #if IMPORTER || EXPORTER using IKVM.Reflection; @@ -491,7 +491,7 @@ internal AttributeAnnotation(ITypeSymbol type) this.type = type; } - CustomAttributeBuilder MakeCustomAttributeBuilder(RuntimeClassLoader loader, object annotation) + ICustomAttributeBuilder MakeCustomAttributeBuilder(RuntimeClassLoader loader, object annotation) { object[] arr = (object[])annotation; object ctorArg = null; @@ -534,25 +534,25 @@ CustomAttributeBuilder MakeCustomAttributeBuilder(RuntimeClassLoader loader, obj // TODO required argument is missing } - return new CustomAttributeBuilder( - ctorArg == null ? defCtor.AsReflection() : singleOneArgCtor.AsReflection(), + return loader.Context.Resolver.Symbols.CreateCustomAttribute( + ctorArg == null ? defCtor : singleOneArgCtor, ctorArg == null ? [] : new object[] { ctorArg }, - properties.ToArray().AsReflection(), + properties.ToArray(), propertyValues.ToArray(), - fields.ToArray().AsReflection(), + fields.ToArray(), fieldValues.ToArray()); } - internal override void Apply(RuntimeClassLoader loader, TypeBuilder tb, object annotation) + internal override void Apply(RuntimeClassLoader loader, ITypeSymbolBuilder tb, object annotation) { - if (type == loader.Context.Resolver.ResolveCoreType(typeof(System.Runtime.InteropServices.StructLayoutAttribute).FullName) && loader.Context.Resolver.ResolveType(tb.BaseType) != loader.Context.Types.Object) + if (type == loader.Context.Resolver.ResolveCoreType(typeof(System.Runtime.InteropServices.StructLayoutAttribute).FullName) && tb.Symbol.BaseType != loader.Context.Types.Object) { // we have to handle this explicitly, because if we apply an illegal StructLayoutAttribute, // TypeBuilder.CreateType() will later on throw an exception. #if IMPORTER - loader.Diagnostics.IgnoredCustomAttribute(type.FullName, $"Type '{tb.FullName}' does not extend cli.System.Object"); + loader.Diagnostics.IgnoredCustomAttribute(type.FullName, $"Type '{tb.Symbol.FullName}' does not extend cli.System.Object"); #else - loader.Diagnostics.GenericRuntimeError($"StructLayoutAttribute cannot be applied to {tb.FullName}, because it does not directly extend cli.System.Object"); + loader.Diagnostics.GenericRuntimeError($"StructLayoutAttribute cannot be applied to {tb.Symbol.FullName}, because it does not directly extend cli.System.Object"); #endif return; } @@ -560,17 +560,17 @@ internal override void Apply(RuntimeClassLoader loader, TypeBuilder tb, object a tb.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); } - internal override void Apply(RuntimeClassLoader loader, MethodBuilder mb, object annotation) + internal override void Apply(RuntimeClassLoader loader, IMethodSymbolBuilder mb, object annotation) { mb.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); } - internal override void Apply(RuntimeClassLoader loader, FieldBuilder fb, object annotation) + internal override void Apply(RuntimeClassLoader loader, IFieldSymbolBuilder fb, object annotation) { fb.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); } - internal override void Apply(RuntimeClassLoader loader, ParameterBuilder pb, object annotation) + internal override void Apply(RuntimeClassLoader loader, IParameterSymbolBuilder pb, object annotation) { // TODO with the current custom attribute annotation restrictions it is impossible to use this CA, // but if we make it possible, we should also implement it here @@ -580,9 +580,11 @@ internal override void Apply(RuntimeClassLoader loader, ParameterBuilder pb, obj pb.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); } - internal override void Apply(RuntimeClassLoader loader, AssemblyBuilder ab, object annotation) + internal override void Apply(RuntimeClassLoader loader, IAssemblySymbolBuilder assemblyBuilder, object annotation) { #if IMPORTER + var ab = assemblyBuilder.AsReflection(); + if (type == loader.Context.Resolver.ResolveCoreType(typeof(System.Runtime.CompilerServices.TypeForwardedToAttribute).FullName)) { ab.__AddTypeForwarder((Type)ConvertValue(loader, loader.Context.Types.Type, ((object[])annotation)[3])); @@ -627,14 +629,14 @@ internal override void Apply(RuntimeClassLoader loader, AssemblyBuilder ab, obje } else { - ab.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); + assemblyBuilder.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); } #else - ab.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); + assemblyBuilder.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); #endif } - internal override void Apply(RuntimeClassLoader loader, PropertyBuilder pb, object annotation) + internal override void Apply(RuntimeClassLoader loader, IPropertySymbolBuilder pb, object annotation) { pb.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); } diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.DelegateJavaMethod.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.DelegateJavaMethod.cs index 8438b052b..678bb8f5e 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.DelegateJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.DelegateJavaMethod.cs @@ -25,6 +25,7 @@ Jeroen Frijters using System.Diagnostics; using IKVM.Attributes; +using IKVM.CoreLib.Symbols; #if IMPORTER || EXPORTER using IKVM.Reflection; @@ -45,7 +46,7 @@ sealed partial class RuntimeManagedJavaType sealed class DelegateJavaMethod : RuntimeJavaMethod { - readonly ConstructorInfo delegateConstructor; + readonly IConstructorSymbol delegateConstructor; readonly DelegateInnerClassJavaType iface; /// @@ -54,9 +55,9 @@ sealed class DelegateJavaMethod : RuntimeJavaMethod /// /// internal DelegateJavaMethod(RuntimeJavaType declaringType, DelegateInnerClassJavaType iface) : - base(declaringType, "", "(" + iface.SigName + ")V", null, declaringType.Context.PrimitiveJavaTypeFactory.VOID, new RuntimeJavaType[] { iface }, Modifiers.Public, MemberFlags.Intrinsic) + base(declaringType, "", "(" + iface.SigName + ")V", null, declaringType.Context.PrimitiveJavaTypeFactory.VOID, [iface], Modifiers.Public, MemberFlags.Intrinsic) { - this.delegateConstructor = declaringType.TypeAsTBD.GetConstructor(new Type[] { DeclaringType.Context.Types.Object, DeclaringType.Context.Types.IntPtr }); + this.delegateConstructor = declaringType.TypeAsTBD.GetConstructor([DeclaringType.Context.Types.Object, DeclaringType.Context.Types.IntPtr]); this.iface = iface; } diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.EnumValueJavaField.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.EnumValueJavaField.cs index 1d521fbe4..de5ed4d6d 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.EnumValueJavaField.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.EnumValueJavaField.cs @@ -24,6 +24,8 @@ Jeroen Frijters using System; using IKVM.Attributes; +using IKVM.CoreLib.Symbols; + #if IMPORTER || EXPORTER using IKVM.Reflection.Emit; @@ -43,7 +45,7 @@ sealed partial class RuntimeManagedJavaType internal sealed class EnumValueJavaField : RuntimeJavaField { - readonly Type underlyingType; + readonly ITypeSymbol underlyingType; /// /// Initializes a new instance. @@ -53,7 +55,7 @@ internal sealed class EnumValueJavaField : RuntimeJavaField internal EnumValueJavaField(RuntimeManagedJavaType tw, RuntimeJavaType fieldType) : base(tw, fieldType, "Value", fieldType.SigName, new ExModifiers(Modifiers.Public | Modifiers.Final, false), null) { - underlyingType = EnumHelper.GetUnderlyingType(tw.type); + underlyingType = tw.type.GetEnumUnderlyingType(); } #if EMITTERS diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.cs index 523b20f72..0eaac509b 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.cs @@ -804,7 +804,7 @@ RuntimeJavaMethod CreateMethodWrapper(string name, string sig, RuntimeJavaType[] if (name == "Finalize" && sig == "()V" && !mb.IsStatic && IsRemappedImplDerived(Context, TypeAsBaseType)) { // TODO if the .NET also has a "finalize" method, we need to hide that one (or rename it, or whatever) - var mw = new RuntimeSimpleCallJavaMethod(this, "finalize", "()V", (MethodInfo)mb, Context.PrimitiveJavaTypeFactory.VOID, Array.Empty(), mods, MemberFlags.None, SimpleOpCode.Call, SimpleOpCode.Callvirt); + var mw = new RuntimeSimpleCallJavaMethod(this, "finalize", "()V", (IMethodSymbol)mb, Context.PrimitiveJavaTypeFactory.VOID, [], mods, MemberFlags.None, SimpleOpCode.Call, SimpleOpCode.Callvirt); mw.SetDeclaredExceptions(new string[] { "java.lang.Throwable" }); return mw; } diff --git a/src/IKVM.Runtime/RuntimeManagedJavaTypeFactory.cs b/src/IKVM.Runtime/RuntimeManagedJavaTypeFactory.cs index d6c1aace8..617ed9132 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaTypeFactory.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaTypeFactory.cs @@ -63,7 +63,7 @@ public RuntimeManagedJavaTypeFactory(RuntimeContext context) /// public RuntimeJavaType GetJavaTypeFromManagedType(ITypeSymbol type) { - return cache.GetValue(type, _ => context.AssemblyClassLoaderFactory.FromAssembly(_.Assembly.AsReflection()).GetJavaTypeFromAssemblyType(_.AsReflection())); + return cache.GetValue(type, _ => context.AssemblyClassLoaderFactory.FromAssembly(_.Assembly).GetJavaTypeFromAssemblyType(_)); } /// diff --git a/src/IKVM.Runtime/RuntimeSimpleCallJavaMethod.cs b/src/IKVM.Runtime/RuntimeSimpleCallJavaMethod.cs index 0e3bf8d3b..424a8ac14 100644 --- a/src/IKVM.Runtime/RuntimeSimpleCallJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimeSimpleCallJavaMethod.cs @@ -22,6 +22,7 @@ Jeroen Frijters */ using IKVM.Attributes; +using IKVM.CoreLib.Symbols; #if IMPORTER || EXPORTER using IKVM.Reflection; @@ -51,7 +52,7 @@ sealed class RuntimeSimpleCallJavaMethod : RuntimeJavaMethod /// /// /// - internal RuntimeSimpleCallJavaMethod(RuntimeJavaType declaringType, string name, string sig, MethodInfo method, RuntimeJavaType returnType, RuntimeJavaType[] parameterTypes, Modifiers modifiers, MemberFlags flags, SimpleOpCode call, SimpleOpCode callvirt) : + internal RuntimeSimpleCallJavaMethod(RuntimeJavaType declaringType, string name, string sig, IMethodSymbol method, RuntimeJavaType returnType, RuntimeJavaType[] parameterTypes, Modifiers modifiers, MemberFlags flags, SimpleOpCode call, SimpleOpCode callvirt) : base(declaringType, name, sig, method, returnType, parameterTypes, modifiers, flags) { this.call = call; diff --git a/src/IKVM.Runtime/RuntimeUnloadableJavaType.cs b/src/IKVM.Runtime/RuntimeUnloadableJavaType.cs index a0265537b..7c4e3cf26 100644 --- a/src/IKVM.Runtime/RuntimeUnloadableJavaType.cs +++ b/src/IKVM.Runtime/RuntimeUnloadableJavaType.cs @@ -143,7 +143,7 @@ internal override void Finish() internal ITypeSymbol CustomModifier => customModifier; - internal void SetCustomModifier(Type type) + internal void SetCustomModifier(ITypeSymbol type) { this.customModifier = type; } diff --git a/src/IKVM.Runtime/RuntimeVerifierJavaType.cs b/src/IKVM.Runtime/RuntimeVerifierJavaType.cs index 998f9c82c..b3961bffd 100644 --- a/src/IKVM.Runtime/RuntimeVerifierJavaType.cs +++ b/src/IKVM.Runtime/RuntimeVerifierJavaType.cs @@ -23,6 +23,8 @@ Jeroen Frijters */ using System; +using IKVM.CoreLib.Symbols; + #if IMPORTER || EXPORTER using IKVM.Reflection; using IKVM.Reflection.Emit; @@ -202,7 +204,7 @@ protected override void LazyPublishMembers() throw new InvalidOperationException("LazyPublishMembers called on " + this); } - internal override Type TypeAsTBD + internal override ITypeSymbol TypeAsTBD { get { diff --git a/src/IKVM.Runtime/StubGen/StubGenerator.cs b/src/IKVM.Runtime/StubGen/StubGenerator.cs index 6c8911eb0..f5a6b5fa8 100644 --- a/src/IKVM.Runtime/StubGen/StubGenerator.cs +++ b/src/IKVM.Runtime/StubGen/StubGenerator.cs @@ -1,21 +1,13 @@ using System; -using System.IO; using System.Collections.Generic; +using System.IO; -using IKVM.ByteCode.Encoding; using IKVM.Attributes; using IKVM.ByteCode; -using IKVM.ByteCode.Decoding; using IKVM.ByteCode.Buffers; - - -#if EXPORTER -using IKVM.Reflection; - -using Type = IKVM.Reflection.Type; -#else -using System.Reflection; -#endif +using IKVM.ByteCode.Decoding; +using IKVM.ByteCode.Encoding; +using IKVM.CoreLib.Symbols; namespace IKVM.Runtime.StubGen { @@ -222,7 +214,7 @@ void AddRuntimeVisibleAnnotationsAttribute(ClassFileBuilder builder, RuntimeJava /// void AddDeprecatedAttribute(ClassFileBuilder builder, RuntimeJavaType type) { - if (type.TypeAsBaseType.IsDefined(context.Resolver.ResolveCoreType(typeof(ObsoleteAttribute).FullName).AsReflection(), false)) + if (type.TypeAsBaseType.IsDefined(context.Resolver.ResolveCoreType(typeof(ObsoleteAttribute).FullName), false)) builder.Attributes.Deprecated(); } @@ -310,7 +302,7 @@ void AddAssemblyAttribute(ClassFileBuilder builder, RuntimeJavaType javaType) /// /// /// - void AddExceptionsAttribute(ClassFileBuilder builder, RuntimeJavaType type, RuntimeJavaMethod method, AttributeTableBuilder attributes, MethodBase methodBase) + void AddExceptionsAttribute(ClassFileBuilder builder, RuntimeJavaType type, RuntimeJavaMethod method, AttributeTableBuilder attributes, IMethodBaseSymbol methodBase) { var throws = context.AttributeHelper.GetThrows(methodBase); if (throws == null) @@ -336,8 +328,8 @@ void AddExceptionsAttribute(ClassFileBuilder builder, RuntimeJavaType type, Runt e.Class(builder.Constants.GetOrAddClass(ex.Replace('.', '/'))); if (throws.types != null) - foreach (Type ex in throws.types) - e.Class(builder.Constants.GetOrAddClass(context.ClassLoaderFactory.GetJavaTypeFromType(ex).Name.Replace('.', '/'))); + foreach (var ex in throws.types) + e.Class(builder.Constants.GetOrAddClass(context.ClassLoaderFactory.GetJavaTypeFromType(context.Resolver.ResolveType(ex)).Name.Replace('.', '/'))); }); } } @@ -380,11 +372,11 @@ void AddMethodParameters(ClassFileBuilder builder, RuntimeJavaType type, Runtime /// /// /// - void AddAnnotationDefaultAttribute(ClassFileBuilder builder, RuntimeJavaType type, RuntimeJavaMethod method, AttributeTableBuilder attributes, MethodBase methodBase) + void AddAnnotationDefaultAttribute(ClassFileBuilder builder, RuntimeJavaType type, RuntimeJavaMethod method, AttributeTableBuilder attributes, IMethodBaseSymbol methodBase) { var attr = GetAnnotationDefault(methodBase); - if (attr != null) - attributes.AnnotationDefault(e => EncodeAnnotationDefault(builder, ref e, attr.ConstructorArguments[0])); + if (attr is CustomAttribute ca) + attributes.AnnotationDefault(e => EncodeAnnotationDefault(builder, ref e, ca.ConstructorArguments[0])); } /// @@ -409,12 +401,12 @@ void AddSignatureAttribute(ClassFileBuilder builder, RuntimeJavaType type, Runti /// /// /// - void AddDeprecatedAttribute(ClassFileBuilder builder, RuntimeJavaType type, RuntimeJavaMethod method, AttributeTableBuilder attributes, MethodBase methodBase) + void AddDeprecatedAttribute(ClassFileBuilder builder, RuntimeJavaType type, RuntimeJavaMethod method, AttributeTableBuilder attributes, IMethodBaseSymbol methodBase) { // HACK the instancehelper methods are marked as Obsolete (to direct people toward the ikvm.extensions methods instead) // but in the Java world most of them are not deprecated (and to keep the Japi results clean we need to reflect this) // the Java deprecated methods actually have two Obsolete attributes - if (methodBase.IsDefined(context.Resolver.ResolveCoreType(typeof(ObsoleteAttribute).FullName).AsReflection(), false) && (!methodBase.Name.StartsWith("instancehelper_") || methodBase.DeclaringType.FullName != "java.lang.String" || GetObsoleteCount(methodBase) == 2)) + if (methodBase.IsDefined(context.Resolver.ResolveCoreType(typeof(ObsoleteAttribute).FullName), false) && (!methodBase.Name.StartsWith("instancehelper_") || methodBase.DeclaringType.FullName != "java.lang.String" || GetObsoleteCount(methodBase) == 2)) attributes.Deprecated(); } @@ -477,7 +469,7 @@ void AddConstantValueAttribute(ClassFileBuilder builder, RuntimeJavaType type, R { var constant = field.GetField().GetRawConstantValue(); if (field.GetField().FieldType.IsEnum) - constant = EnumHelper.GetPrimitiveValue(context, EnumHelper.GetUnderlyingType(field.GetField().FieldType), constant); + constant = EnumHelper.GetPrimitiveValue(context, field.GetField().FieldType.GetEnumUnderlyingType(), constant); if (constant != null) { @@ -541,7 +533,7 @@ void AddSignatureAttribute(ClassFileBuilder builder, RuntimeJavaType type, Runti void AddDeprecatedAttribute(ClassFileBuilder builder, RuntimeJavaType type, RuntimeJavaField field, AttributeTableBuilder attributes) { // .NET ObsoleteAttribute translates to Deprecated attribute - if (field.GetField() != null && field.GetField().IsDefined(context.Resolver.ResolveCoreType(typeof(ObsoleteAttribute).FullName).AsReflection(), false)) + if (field.GetField() != null && field.GetField().IsDefined(context.Resolver.ResolveCoreType(typeof(ObsoleteAttribute).FullName), false)) attributes.Deprecated(); } @@ -581,7 +573,7 @@ void AddRuntimeVisibleAnnotationsAttribute(ClassFileBuilder builder, RuntimeJava /// /// /// - bool EncodeAnnotations(ClassFileBuilder builder, ref AnnotationTableEncoder encoder, MemberInfo source) + bool EncodeAnnotations(ClassFileBuilder builder, ref AnnotationTableEncoder encoder, IMemberSymbol source) { var any = false; @@ -609,7 +601,7 @@ bool EncodeAnnotations(ClassFileBuilder builder, ref AnnotationTableEncoder enco /// /// /// - bool EncodeParameterAnnotations(ClassFileBuilder builder, ref ParameterAnnotationTableEncoder encoder, MethodBase source) + bool EncodeParameterAnnotations(ClassFileBuilder builder, ref ParameterAnnotationTableEncoder encoder, IMethodBaseSymbol source) { var any = false; @@ -918,7 +910,7 @@ public PackageConstantHandle Map(PackageConstantHandle handle) /// /// /// - object[] GetAnnotation(CustomAttributeData cad) + object[] GetAnnotation(CustomAttribute cad) { // attribute is either a AnnotationAttributeBase or a DynamicAnnotationAttribute with a single object[] in our internal annotation format if (cad.ConstructorArguments.Count == 1 && cad.ConstructorArguments[0].ArgumentType == typeof(object[]) && (cad.Constructor.DeclaringType.BaseType == typeof(ikvm.@internal.AnnotationAttributeBase) || cad.Constructor.DeclaringType == typeof(DynamicAnnotationAttribute))) @@ -1164,27 +1156,14 @@ object[] UnpackArray(IList list) return arr; } - int GetObsoleteCount(MethodBase mb) + int GetObsoleteCount(IMethodBaseSymbol mb) { -#if EXPORTER - return mb.__GetCustomAttributes(context.Resolver.ResolveCoreType(typeof(ObsoleteAttribute).FullName).AsReflection(), false).Count; -#else - return mb.GetCustomAttributes(typeof(ObsoleteAttribute), false).Length; -#endif + return mb.GetCustomAttributes(context.Resolver.ResolveCoreType(typeof(ObsoleteAttribute).FullName), false).Length; } - CustomAttributeData GetAnnotationDefault(MethodBase mb) + CustomAttribute? GetAnnotationDefault(IMethodBaseSymbol mb) { -#if EXPORTER - var attr = CustomAttributeData.__GetCustomAttributes(mb, context.Resolver.ResolveRuntimeType(typeof(Attributes.AnnotationDefaultAttribute).FullName).AsReflection(), false); - return attr.Count == 1 ? attr[0] : null; -#else - foreach (var cad in CustomAttributeData.GetCustomAttributes(mb)) - if (cad.Constructor.DeclaringType == typeof(Attributes.AnnotationDefaultAttribute)) - return cad; - - return null; -#endif + return mb.GetCustomAttribute(context.Resolver.ResolveRuntimeType(typeof(Attributes.AnnotationDefaultAttribute).FullName), false); } string GetAssemblyName(RuntimeJavaType tw) diff --git a/src/IKVM.Runtime/SymbolExtensions.cs b/src/IKVM.Runtime/SymbolExtensions.cs index 65a6c08df..14e3948b0 100644 --- a/src/IKVM.Runtime/SymbolExtensions.cs +++ b/src/IKVM.Runtime/SymbolExtensions.cs @@ -3,13 +3,18 @@ using IKVM.CoreLib.Symbols; using IKVM.CoreLib.Symbols.Reflection; using IKVM.CoreLib.Symbols.IkvmReflection; +using IKVM.CoreLib.Symbols.Emit; +using IKVM.CoreLib.Symbols.Reflection.Emit; +using IKVM.CoreLib.Symbols.IkvmReflection.Emit; #if IMPORTER || EXPORTER using IKVM.Reflection; +using IKVM.Reflection.Emit; using Type = IKVM.Reflection.Type; #else using System.Reflection; +using System.Reflection.Emit; #endif namespace IKVM.Runtime @@ -150,6 +155,78 @@ public static PropertyInfo[] AsReflection(this IPropertySymbol[] symbols) return a; } + public static AssemblyBuilder AsReflection(this IAssemblySymbolBuilder builder) + { + if (builder == null) + return null; + +#if IMPORTER || EXPORTER + return ((IkvmReflectionAssemblySymbolBuilder)builder).ReflectionBuilder; +#else + return ((ReflectionAssemblySymbolBuilder)builder).ReflectionBuilder; +#endif + } + + public static ModuleBuilder AsReflection(this IModuleSymbolBuilder builder) + { + if (builder == null) + return null; + +#if IMPORTER || EXPORTER + return ((IkvmReflectionModuleSymbolBuilder)builder).ReflectionBuilder; +#else + return ((ReflectionModuleSymbolBuilder)builder).ReflectionBuilder; +#endif + } + + public static TypeBuilder AsReflection(this ITypeSymbolBuilder builder) + { + if (builder == null) + return null; + +#if IMPORTER || EXPORTER + return ((IkvmReflectionTypeSymbolBuilder)builder).ReflectionBuilder; +#else + return ((ReflectionTypeSymbolBuilder)builder).ReflectionBuilder; +#endif + } + + public static ConstructorBuilder AsReflection(this IConstructorSymbolBuilder builder) + { + if (builder == null) + return null; + +#if IMPORTER || EXPORTER + return ((IkvmReflectionConstructorSymbolBuilder)builder).ReflectionBuilder; +#else + return ((ReflectionConstructorSymbolBuilder)builder).ReflectionBuilder; +#endif + } + + public static MethodBuilder AsReflection(this IMethodSymbolBuilder builder) + { + if (builder == null) + return null; + +#if IMPORTER || EXPORTER + return ((IkvmReflectionMethodSymbolBuilder)builder).ReflectionBuilder; +#else + return ((ReflectionMethodSymbolBuilder)builder).ReflectionBuilder; +#endif + } + + public static FieldBuilder AsReflection(this IFieldSymbolBuilder builder) + { + if (builder == null) + return null; + +#if IMPORTER || EXPORTER + return ((IkvmReflectionFieldSymbolBuilder)builder).ReflectionBuilder; +#else + return ((ReflectionFieldSymbolBuilder)builder).ReflectionBuilder; +#endif + } + } } diff --git a/src/IKVM.Tools.Exporter/ExportImpl.cs b/src/IKVM.Tools.Exporter/ExportImpl.cs index 29ad16827..dc57fffe8 100644 --- a/src/IKVM.Tools.Exporter/ExportImpl.cs +++ b/src/IKVM.Tools.Exporter/ExportImpl.cs @@ -7,6 +7,7 @@ using System.Reflection.PortableExecutable; using IKVM.CoreLib.Diagnostics; +using IKVM.CoreLib.Symbols; using IKVM.Reflection; using IKVM.Runtime; using IKVM.Tools.Importer; @@ -174,7 +175,7 @@ public int Execute() context = new RuntimeContext(new RuntimeContextOptions(), diagnostics, new ManagedTypeResolver(compiler, baseAssembly), false, compiler); } - if (context.AttributeHelper.IsJavaModule(assembly.ManifestModule)) + if (context.AttributeHelper.IsJavaModule(context.Resolver.ResolveModule(assembly.ManifestModule))) { diagnostics.ExportingImportsNotSupported(); return 1; @@ -344,7 +345,7 @@ void WriteClass(RuntimeJavaType javaType) javaType.Context.StubGenerator.Write(stream, javaType, options.IncludeNonPublicTypes, options.IncludeNonPublicInterfaces, options.IncludeNonPublicMembers, options.IncludeParameterNames, options.SerialVersionUID); } - bool ExportNamespace(IList namespaces, Type type) + bool ExportNamespace(IList namespaces, ITypeSymbol type) { if (namespaces.Count == 0) return true; @@ -360,7 +361,7 @@ bool ExportNamespace(IList namespaces, Type type) int ProcessTypes(RuntimeContext context, Type[] types) { int rc = 0; - foreach (var t in types) + foreach (var t in types.Select(context.Resolver.ResolveType)) { if ((t.IsPublic || options.IncludeNonPublicTypes) && ExportNamespace(options.Namespaces, t) && !t.IsGenericTypeDefinition && !context.AttributeHelper.IsHideFromJava(t) && (!t.IsGenericType || !context.AttributeHelper.IsJavaModule(t.Module))) { diff --git a/src/IKVM.Tools.Exporter/FakeTypes.cs b/src/IKVM.Tools.Exporter/FakeTypes.cs index 1cd9d3de5..3720cd2dc 100644 --- a/src/IKVM.Tools.Exporter/FakeTypes.cs +++ b/src/IKVM.Tools.Exporter/FakeTypes.cs @@ -23,6 +23,7 @@ Jeroen Frijters */ using System; +using IKVM.CoreLib.Symbols; using IKVM.Runtime; using Type = IKVM.Reflection.Type; @@ -34,7 +35,7 @@ class FakeTypes { readonly RuntimeContext context; - readonly Type genericType; + readonly ITypeSymbol genericType; /// /// Initializes a new instance. @@ -44,30 +45,30 @@ class FakeTypes public FakeTypes(RuntimeContext context) { this.context = context ?? throw new ArgumentNullException(nameof(context)); - genericType = context.Resolver.ResolveRuntimeType("IKVM.Runtime.ValueObject`1").AsReflection(); + genericType = context.Resolver.ResolveRuntimeType("IKVM.Runtime.ValueObject`1"); } - internal Type GetAttributeType(Type type) + internal ITypeSymbol GetAttributeType(ITypeSymbol type) { return genericType.MakeGenericType(type); } - internal Type GetAttributeReturnValueType(Type type) + internal ITypeSymbol GetAttributeReturnValueType(ITypeSymbol type) { return genericType.MakeGenericType(type); } - internal Type GetAttributeMultipleType(Type type) + internal ITypeSymbol GetAttributeMultipleType(ITypeSymbol type) { return genericType.MakeGenericType(type); } - internal Type GetDelegateType(Type type) + internal ITypeSymbol GetDelegateType(ITypeSymbol type) { return genericType.MakeGenericType(type); } - internal Type GetEnumType(Type type) + internal ITypeSymbol GetEnumType(ITypeSymbol type) { return genericType.MakeGenericType(type); } diff --git a/src/IKVM.Tools.Exporter/ManagedTypeResolver.cs b/src/IKVM.Tools.Exporter/ManagedTypeResolver.cs index d1f2ac469..3d9941628 100644 --- a/src/IKVM.Tools.Exporter/ManagedTypeResolver.cs +++ b/src/IKVM.Tools.Exporter/ManagedTypeResolver.cs @@ -3,37 +3,41 @@ using IKVM.CoreLib.Symbols; using IKVM.CoreLib.Symbols.IkvmReflection; using IKVM.Reflection; +using IKVM.Runtime; using Type = IKVM.Reflection.Type; namespace IKVM.Tools.Exporter { - class ManagedTypeResolver : ISymbolResolver + class ManagedTypeResolver : IRuntimeSymbolResolver { readonly StaticCompiler compiler; readonly Assembly baseAssembly; - readonly IkvmReflectionSymbolContext context = new(); + readonly IkvmReflectionSymbolContext symbols = new(); - /// - /// Initializes a new instance. - /// - /// - /// - public ManagedTypeResolver(StaticCompiler compiler, Assembly baseAssembly) + /// + /// Initializes a new instance. + /// + /// + /// + public ManagedTypeResolver(StaticCompiler compiler, Assembly baseAssembly) { this.compiler = compiler ?? throw new ArgumentNullException(nameof(compiler)); this.baseAssembly = baseAssembly; - } + } - /// - /// Attempts to resolve the base Java assembly. - /// - /// - public IAssemblySymbol ResolveBaseAssembly() + /// + public ISymbolContext Symbols => symbols; + + /// + /// Attempts to resolve the base Java assembly. + /// + /// + public IAssemblySymbol ResolveBaseAssembly() { - return baseAssembly != null ? context.GetOrCreateAssemblySymbol(baseAssembly) : null; + return baseAssembly != null ? symbols.GetOrCreateAssemblySymbol(baseAssembly) : null; } /// @@ -43,7 +47,7 @@ public IAssemblySymbol ResolveBaseAssembly() /// public IAssemblySymbol ResolveAssembly(string assemblyName) { - return compiler.Load(assemblyName) is { } a ? context.GetOrCreateAssemblySymbol(a) : null; + return compiler.Load(assemblyName) is { } a ? symbols.GetOrCreateAssemblySymbol(a) : null; } /// @@ -55,7 +59,7 @@ public ITypeSymbol ResolveCoreType(string typeName) { foreach (var assembly in compiler.Universe.GetAssemblies()) if (assembly.GetType(typeName) is Type t) - return context.GetOrCreateTypeSymbol(t); + return ResolveType(t); return null; } @@ -67,9 +71,27 @@ public ITypeSymbol ResolveCoreType(string typeName) /// public ITypeSymbol ResolveRuntimeType(string typeName) { - return compiler.GetRuntimeType(typeName) is { } t ? context.GetOrCreateTypeSymbol(t) : null; - } + return compiler.GetRuntimeType(typeName) is { } t ? symbols.GetOrCreateTypeSymbol(t) : null; + } + + /// + public IAssemblySymbol ResolveAssembly(Assembly assembly) + { + return symbols.GetOrCreateAssemblySymbol(assembly); + } + + /// + public IModuleSymbol ResolveModule(Module module) + { + return symbols.GetOrCreateModuleSymbol(module); + } + + /// + public ITypeSymbol ResolveType(Type type) + { + return symbols.GetOrCreateTypeSymbol(type); + } - } + } } diff --git a/src/IKVM.Tools.Exporter/RuntimeBootstrapClassLoader.cs b/src/IKVM.Tools.Exporter/RuntimeBootstrapClassLoader.cs index 12948e0ee..1debbee0d 100644 --- a/src/IKVM.Tools.Exporter/RuntimeBootstrapClassLoader.cs +++ b/src/IKVM.Tools.Exporter/RuntimeBootstrapClassLoader.cs @@ -39,14 +39,14 @@ internal RuntimeBootstrapClassLoader(RuntimeContext context) : base(context, CodeGenOptions.None, null) { var javaLangObject = new RuntimeStubJavaType(context, Modifiers.Public, "java.lang.Object", null, true); - SetRemappedType(Context.Resolver.ResolveCoreType(typeof(object).FullName).AsReflection(), javaLangObject); - SetRemappedType(Context.Resolver.ResolveCoreType(typeof(string).FullName).AsReflection(), new RuntimeStubJavaType(context, Modifiers.Public | Modifiers.Final, "java.lang.String", javaLangObject, true)); - SetRemappedType(Context.Resolver.ResolveCoreType(typeof(Exception).FullName).AsReflection(), new RuntimeStubJavaType(context, Modifiers.Public, "java.lang.Throwable", javaLangObject, true)); - SetRemappedType(Context.Resolver.ResolveCoreType(typeof(IComparable).FullName).AsReflection(), new RuntimeStubJavaType(context, Modifiers.Public | Modifiers.Abstract | Modifiers.Interface, "java.lang.Comparable", null, true)); + SetRemappedType(Context.Resolver.ResolveCoreType(typeof(object).FullName), javaLangObject); + SetRemappedType(Context.Resolver.ResolveCoreType(typeof(string).FullName), new RuntimeStubJavaType(context, Modifiers.Public | Modifiers.Final, "java.lang.String", javaLangObject, true)); + SetRemappedType(Context.Resolver.ResolveCoreType(typeof(Exception).FullName), new RuntimeStubJavaType(context, Modifiers.Public, "java.lang.Throwable", javaLangObject, true)); + SetRemappedType(Context.Resolver.ResolveCoreType(typeof(IComparable).FullName), new RuntimeStubJavaType(context, Modifiers.Public | Modifiers.Abstract | Modifiers.Interface, "java.lang.Comparable", null, true)); var autoCloseable = new RuntimeStubJavaType(context, Modifiers.Public | Modifiers.Abstract | Modifiers.Interface, "java.lang.AutoCloseable", null, true); - autoCloseable.SetMethods(new[] { new RuntimeSimpleCallJavaMethod(autoCloseable, "close", "()V", Context.Resolver.ResolveCoreType(typeof(IDisposable).FullName).GetMethod("Dispose").AsReflection(), context.PrimitiveJavaTypeFactory.VOID, Array.Empty(), Modifiers.Public | Modifiers.Abstract, MemberFlags.None, SimpleOpCode.Callvirt, SimpleOpCode.Callvirt) }); - SetRemappedType(Context.Resolver.ResolveCoreType(typeof(IDisposable).FullName).AsReflection(), autoCloseable); + autoCloseable.SetMethods(new[] { new RuntimeSimpleCallJavaMethod(autoCloseable, "close", "()V", Context.Resolver.ResolveCoreType(typeof(IDisposable).FullName).GetMethod("Dispose"), context.PrimitiveJavaTypeFactory.VOID, Array.Empty(), Modifiers.Public | Modifiers.Abstract, MemberFlags.None, SimpleOpCode.Callvirt, SimpleOpCode.Callvirt) }); + SetRemappedType(Context.Resolver.ResolveCoreType(typeof(IDisposable).FullName), autoCloseable); RegisterInitiatingLoader(new RuntimeStubJavaType(context, Modifiers.Public, "java.lang.Enum", javaLangObject, false)); RegisterInitiatingLoader(new RuntimeStubJavaType(context, Modifiers.Public | Modifiers.Abstract | Modifiers.Interface, "java.lang.annotation.Annotation", null, false)); diff --git a/src/IKVM.Tools.Exporter/RuntimeStubJavaType.cs b/src/IKVM.Tools.Exporter/RuntimeStubJavaType.cs index a1c878073..6c51d4749 100644 --- a/src/IKVM.Tools.Exporter/RuntimeStubJavaType.cs +++ b/src/IKVM.Tools.Exporter/RuntimeStubJavaType.cs @@ -24,8 +24,7 @@ Jeroen Frijters using System; using IKVM.Attributes; - -using Type = IKVM.Reflection.Type; +using IKVM.CoreLib.Symbols; namespace IKVM.Runtime { @@ -60,7 +59,7 @@ internal override RuntimeJavaType BaseTypeWrapper internal override RuntimeClassLoader ClassLoader => Context.ClassLoaderFactory.GetBootstrapClassLoader(); - internal override Type TypeAsTBD + internal override ITypeSymbol TypeAsTBD { get { throw new NotSupportedException(); } } diff --git a/src/IKVM.Tools.Importer/ImportClassLoader.cs b/src/IKVM.Tools.Importer/ImportClassLoader.cs index 8bbc52ed5..a535a1957 100644 --- a/src/IKVM.Tools.Importer/ImportClassLoader.cs +++ b/src/IKVM.Tools.Importer/ImportClassLoader.cs @@ -35,6 +35,8 @@ Jeroen Frijters using IKVM.Attributes; using IKVM.ByteCode; using IKVM.CoreLib.Diagnostics; +using IKVM.CoreLib.Symbols; +using IKVM.CoreLib.Symbols.Emit; using IKVM.Reflection; using IKVM.Reflection.Emit; using IKVM.Runtime; @@ -2115,7 +2117,7 @@ internal override RuntimeJavaType[] Interfaces } } - internal override Type TypeAsTBD + internal override ITypeSymbol TypeAsTBD { get { @@ -2123,7 +2125,7 @@ internal override Type TypeAsTBD } } - internal override Type TypeAsBaseType + internal override ITypeSymbol TypeAsBaseType { get { @@ -2146,7 +2148,7 @@ internal override bool IsFastClassLiteralSafe } } - internal static void AddDeclaredExceptions(RuntimeContext context, MethodBuilder mb, IKVM.Tools.Importer.MapXml.Throws[] throws) + internal static void AddDeclaredExceptions(RuntimeContext context, IMethodSymbolBuilder mb, IKVM.Tools.Importer.MapXml.Throws[] throws) { if (throws != null) { diff --git a/src/IKVM.Tools.Importer/RuntimeImportByteCodeJavaType.cs b/src/IKVM.Tools.Importer/RuntimeImportByteCodeJavaType.cs index 37c22bb2a..9712f24ac 100644 --- a/src/IKVM.Tools.Importer/RuntimeImportByteCodeJavaType.cs +++ b/src/IKVM.Tools.Importer/RuntimeImportByteCodeJavaType.cs @@ -27,6 +27,8 @@ Jeroen Frijters using IKVM.Attributes; using IKVM.CoreLib.Diagnostics; +using IKVM.CoreLib.Symbols; +using IKVM.CoreLib.Symbols.Emit; using IKVM.Reflection; using IKVM.Reflection.Emit; using IKVM.Runtime; @@ -43,14 +45,14 @@ namespace IKVM.Tools.Importer sealed class RuntimeImportByteCodeJavaType : RuntimeByteCodeJavaType { - FieldInfo ghostRefField; - MethodBuilder ghostIsInstanceMethod; - MethodBuilder ghostIsInstanceArrayMethod; - MethodBuilder ghostCastMethod; - MethodBuilder ghostCastArrayMethod; - TypeBuilder typeBuilderGhostInterface; + IFieldSymbol ghostRefField; + IMethodSymbolBuilder ghostIsInstanceMethod; + IMethodSymbolBuilder ghostIsInstanceArrayMethod; + IMethodSymbolBuilder ghostCastMethod; + IMethodSymbolBuilder ghostCastArrayMethod; + ITypeSymbolBuilder typeBuilderGhostInterface; Annotation annotation; - Type enumType; + ITypeSymbol enumType; RuntimeJavaMethod[] replacedMethods; /// @@ -73,9 +75,9 @@ sealed class ConstructorForwarder : RuntimeJavaMethod { readonly RuntimeJavaTypeFactory context; - readonly TypeBuilder typeBuilder; + readonly ITypeSymbolBuilder typeBuilder; readonly RuntimeJavaMethod ctor; - MethodBuilder constructorBuilder; + IMethodSymbolBuilder constructorBuilder; /// /// Initializes a new instance. @@ -83,7 +85,7 @@ sealed class ConstructorForwarder : RuntimeJavaMethod /// /// /// - internal ConstructorForwarder(RuntimeJavaTypeFactory context, TypeBuilder typeBuilder, RuntimeJavaMethod ctor) : + internal ConstructorForwarder(RuntimeJavaTypeFactory context, ITypeSymbolBuilder typeBuilder, RuntimeJavaMethod ctor) : base(ctor.DeclaringType, ctor.Name, ctor.Signature, null, null, null, ctor.Modifiers, MemberFlags.None) { this.context = context; @@ -94,23 +96,23 @@ internal ConstructorForwarder(RuntimeJavaTypeFactory context, TypeBuilder typeBu protected override void DoLinkMethod() { ctor.Link(); - DefineMethodHelper dmh = ctor.GetDefineMethodHelper(); - constructorBuilder = dmh.DefineConstructor(context, typeBuilder, MethodAttributes.PrivateScope); + var dmh = ctor.GetDefineMethodHelper(); + constructorBuilder = dmh.DefineConstructor(context, typeBuilder, System.Reflection.MethodAttributes.PrivateScope); ctor.DeclaringType.Context.AttributeHelper.HideFromJava(constructorBuilder); - CodeEmitter ilgen = ctor.DeclaringType.Context.CodeEmitterFactory.Create(constructorBuilder); - ilgen.Emit(OpCodes.Ldarg_0); + var ilgen = ctor.DeclaringType.Context.CodeEmitterFactory.Create(constructorBuilder); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); for (int i = 1; i <= dmh.ParameterCount; i++) { ilgen.EmitLdarg(i); } ctor.EmitCall(ilgen); - ilgen.Emit(OpCodes.Ret); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ret); ilgen.DoEmit(); } internal override void EmitCall(CodeEmitter ilgen) { - ilgen.Emit(OpCodes.Call, constructorBuilder); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, constructorBuilder); } } @@ -118,7 +120,7 @@ internal override void EmitCall(CodeEmitter ilgen) internal override bool IsMapUnsafeException => classLoader.IsMapUnsafeException(this); - internal override Type TypeAsBaseType => typeBuilderGhostInterface != null ? typeBuilderGhostInterface : base.TypeAsBaseType; + internal override ITypeSymbol TypeAsBaseType => typeBuilderGhostInterface != null ? typeBuilderGhostInterface : base.TypeAsBaseType; internal void GetParameterNamesFromXml(string methodName, string methodSig, string[] parameterNames) { @@ -129,7 +131,7 @@ internal void GetParameterNamesFromXml(string methodName, string methodSig, stri parameterNames[i] = parameters[i].Name; } - internal void AddXmlMapParameterAttributes(MethodBuilder method, string className, string methodName, string methodSig, ref ParameterBuilder[] parameterBuilders) + internal void AddXmlMapParameterAttributes(IMethodSymbolBuilder method, string className, string methodName, string methodSig, ref ParameterBuilder[] parameterBuilders) { var parameters = classLoader.GetXmlMapParameters(className, methodName, methodSig); if (parameters != null) @@ -145,7 +147,7 @@ internal void AddXmlMapParameterAttributes(MethodBuilder method, string classNam } } - private void AddParameterMetadata(MethodBuilder method, RuntimeJavaMethod mw) + private void AddParameterMetadata(IMethodSymbolBuilder method, RuntimeJavaMethod mw) { ParameterBuilder[] pbs; if ((mw.DeclaringType.IsPublic && (mw.IsPublic || mw.IsProtected)) || classLoader.EmitSymbols) @@ -210,7 +212,7 @@ protected override bool EmitMapXmlMethodPrologueAndOrBody(CodeEmitter ilgen, Cla return false; } - void PublishAttributes(TypeBuilder typeBuilder, Class clazz) + void PublishAttributes(ITypeSymbolBuilder typeBuilder, Class clazz) { foreach (var attr in clazz.Attributes) Context.AttributeHelper.SetCustomAttribute(classLoader, typeBuilder, attr); @@ -222,7 +224,7 @@ void PublishAttributes(TypeBuilder typeBuilder, Class clazz) /// /// /// - static bool CheckPropertyArgs(Type[] args1, Type[] args2) + static bool CheckPropertyArgs(ITypeSymbol[] args1, ITypeSymbol[] args2) { if (args1.Length == args2.Length) { @@ -236,12 +238,12 @@ static bool CheckPropertyArgs(Type[] args1, Type[] args2) return false; } - static MethodAttributes GetPropertyMethodAttributes(RuntimeJavaMethod mw, bool final) + static System.Reflection.MethodAttributes GetPropertyMethodAttributes(RuntimeJavaMethod mw, bool final) { - var attribs = MethodAttributes.HideBySig; + var attribs = System.Reflection.MethodAttributes.HideBySig; if (mw.IsStatic) { - attribs |= MethodAttributes.Static; + attribs |= System.Reflection.MethodAttributes.Static; } else { @@ -249,36 +251,36 @@ static MethodAttributes GetPropertyMethodAttributes(RuntimeJavaMethod mw, bool f // the getter and setter methods need to have substantially the same method attributes, // so we may need to look at our peer to determine whether we should be final // or not (and vice versa). - attribs |= MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.CheckAccessOnOverride; + attribs |= System.Reflection.MethodAttributes.Virtual | System.Reflection.MethodAttributes.NewSlot | System.Reflection.MethodAttributes.CheckAccessOnOverride; if (final) - attribs |= MethodAttributes.Final; + attribs |= System.Reflection.MethodAttributes.Final; } // TODO what happens if accessibility doesn't match our peer? if (mw.IsPublic) - attribs |= MethodAttributes.Public; + attribs |= System.Reflection.MethodAttributes.Public; else if (mw.IsProtected) - attribs |= MethodAttributes.FamORAssem; + attribs |= System.Reflection.MethodAttributes.FamORAssem; else if (mw.IsPrivate) - attribs |= MethodAttributes.Private; + attribs |= System.Reflection.MethodAttributes.Private; else - attribs |= MethodAttributes.Assembly; + attribs |= System.Reflection.MethodAttributes.Assembly; return attribs; } - private void PublishProperties(TypeBuilder typeBuilder, Class clazz) + private void PublishProperties(ITypeSymbolBuilder typeBuilder, Class clazz) { foreach (var prop in clazz.Properties) { var typeWrapper = ClassLoader.RetTypeWrapperFromSig(prop.Sig, LoadMode.Link); var propargs = ClassLoader.ArgJavaTypeListFromSig(prop.Sig, LoadMode.Link); - Type[] indexer = new Type[propargs.Length]; + var indexer = new ITypeSymbol[propargs.Length]; for (int i = 0; i < propargs.Length; i++) { indexer[i] = propargs[i].TypeAsSignatureType; } - PropertyBuilder propbuilder = typeBuilder.DefineProperty(prop.Name, PropertyAttributes.None, typeWrapper.TypeAsSignatureType, indexer); + var propbuilder = typeBuilder.DefineProperty(prop.Name, System.Reflection.PropertyAttributes.None, typeWrapper.TypeAsSignatureType, indexer); Context.AttributeHelper.HideFromJava(propbuilder); if (prop.Attributes != null) { @@ -317,10 +319,12 @@ private void PublishProperties(TypeBuilder typeBuilder, Class clazz) } else { - var mb = mw.GetMethod() as MethodBuilder; - if (mb == null || mb.DeclaringType != typeBuilder || (!mb.IsFinal && final)) + var m = mw.GetMethod() as IMethodSymbol; + if (m == null || m.DeclaringType != typeBuilder || (!m.IsFinal && final)) { - mb = typeBuilder.DefineMethod("get_" + prop.Name, GetPropertyMethodAttributes(mw, final), typeWrapper.TypeAsSignatureType, indexer); + var mb = typeBuilder.DefineMethod("get_" + prop.Name, GetPropertyMethodAttributes(mw, final), typeWrapper.TypeAsSignatureType, indexer); + m = mb.Symbol; + Context.AttributeHelper.HideFromJava(mb); var ilgen = Context.CodeEmitterFactory.Create(mb); if (mw.IsStatic) @@ -333,15 +337,16 @@ private void PublishProperties(TypeBuilder typeBuilder, Class clazz) } else { - ilgen.Emit(OpCodes.Ldarg_0); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); for (int i = 0; i < indexer.Length; i++) ilgen.EmitLdarg(i + 1); mw.EmitCallvirt(ilgen); } - ilgen.Emit(OpCodes.Ret); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ret); ilgen.DoEmit(); + + propbuilder.SetGetMethod(mb); } - propbuilder.SetGetMethod(mb); } } if (setter != null) @@ -354,10 +359,12 @@ private void PublishProperties(TypeBuilder typeBuilder, Class clazz) } else { - var mb = mw.GetMethod() as MethodBuilder; - if (mb == null || mb.DeclaringType != typeBuilder || (!mb.IsFinal && final)) + var m = mw.GetMethod() as IMethodSymbol; + if (m == null || m.DeclaringType != typeBuilder || (!m.IsFinal && final)) { - mb = typeBuilder.DefineMethod("set_" + prop.Name, GetPropertyMethodAttributes(mw, final), mw.ReturnTypeForDefineMethod, args); + var mb = typeBuilder.DefineMethod("set_" + prop.Name, GetPropertyMethodAttributes(mw, final), mw.ReturnTypeForDefineMethod, args); + m = mb.Symbol; + Context.AttributeHelper.HideFromJava(mb); var ilgen = Context.CodeEmitterFactory.Create(mb); if (mw.IsStatic) @@ -368,22 +375,23 @@ private void PublishProperties(TypeBuilder typeBuilder, Class clazz) } else { - ilgen.Emit(OpCodes.Ldarg_0); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); for (int i = 0; i <= indexer.Length; i++) ilgen.EmitLdarg(i + 1); mw.EmitCallvirt(ilgen); } - ilgen.Emit(OpCodes.Ret); + + ilgen.Emit(System.Reflection.Emit.OpCodes.Ret); ilgen.DoEmit(); - } - propbuilder.SetSetMethod(mb); + propbuilder.SetSetMethod(mb); + } } } } } - private static void MapModifiers(MapModifiers mapmods, bool isConstructor, out bool setmodifiers, ref MethodAttributes attribs, bool isNewSlot) + private static void MapModifiers(MapModifiers mapmods, bool isConstructor, out bool setmodifiers, ref System.Reflection.MethodAttributes attribs, bool isNewSlot) { setmodifiers = false; var modifiers = (Modifiers)mapmods; @@ -447,18 +455,18 @@ private static void MapModifiers(MapModifiers mapmods, bool isConstructor, out b } } - private void MapSignature(string sig, out Type returnType, out Type[] parameterTypes) + private void MapSignature(string sig, out ITypeSymbol returnType, out ITypeSymbol[] parameterTypes) { returnType = ClassLoader.RetTypeWrapperFromSig(sig, LoadMode.Link).TypeAsSignatureType; var parameterTypeWrappers = ClassLoader.ArgJavaTypeListFromSig(sig, LoadMode.Link); - parameterTypes = new Type[parameterTypeWrappers.Length]; + parameterTypes = new ITypeSymbol[parameterTypeWrappers.Length]; for (int i = 0; i < parameterTypeWrappers.Length; i++) { parameterTypes[i] = parameterTypeWrappers[i].TypeAsSignatureType; } } - protected override void EmitMapXmlMetadata(TypeBuilder typeBuilder, ClassFile classFile, RuntimeJavaField[] fields, RuntimeJavaMethod[] methods) + protected override void EmitMapXmlMetadata(ITypeSymbolBuilder typeBuilder, ClassFile classFile, RuntimeJavaField[] fields, RuntimeJavaMethod[] methods) { var mapxml = classLoader.GetMapXmlClasses(); if (mapxml != null) @@ -605,7 +613,7 @@ protected override void EmitMapXmlMetadata(TypeBuilder typeBuilder, ClassFile cl } if (clazz.Interfaces != null) { - foreach (Implements iface in clazz.Interfaces) + foreach (var iface in clazz.Interfaces) { var tw = ClassLoader.LoadClassByName(iface.Class); // NOTE since this interface won't be part of the list in the ImplementAttribute, @@ -613,16 +621,16 @@ protected override void EmitMapXmlMetadata(TypeBuilder typeBuilder, ClassFile cl typeBuilder.AddInterfaceImplementation(tw.TypeAsBaseType); if (iface.Methods != null) { - foreach (Method m in iface.Methods) + foreach (var m in iface.Methods) { var mw = tw.GetMethodWrapper(m.Name, m.Sig, false); if (mw == null) throw new InvalidOperationException("Method " + m.Name + m.Sig + " not found in interface " + tw.Name); mw.Link(); - MethodBuilder mb = mw.GetDefineMethodHelper().DefineMethod(this, typeBuilder, tw.Name + "/" + m.Name, MethodAttributes.Private | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.CheckAccessOnOverride); + var mb = mw.GetDefineMethodHelper().DefineMethod(this, typeBuilder, tw.Name + "/" + m.Name, System.Reflection.MethodAttributes.Private | System.Reflection.MethodAttributes.NewSlot | System.Reflection.MethodAttributes.Virtual | System.Reflection.MethodAttributes.Final | System.Reflection.MethodAttributes.CheckAccessOnOverride); Context.AttributeHelper.HideFromJava(mb); - typeBuilder.DefineMethodOverride(mb, (MethodInfo)mw.GetMethod()); + typeBuilder.DefineMethodOverride(mb, (IMethodSymbol)mw.GetMethod()); CodeEmitter ilgen = Context.CodeEmitterFactory.Create(mb); m.Emit(classLoader, ilgen); ilgen.DoEmit(); @@ -634,12 +642,12 @@ protected override void EmitMapXmlMetadata(TypeBuilder typeBuilder, ClassFile cl } } - protected override MethodBuilder DefineGhostMethod(TypeBuilder typeBuilder, string name, MethodAttributes attribs, RuntimeJavaMethod mw) + protected override MethodBuilder DefineGhostMethod(ITypeSymbolBuilder typeBuilder, string name, System.Reflection.MethodAttributes attribs, RuntimeJavaMethod mw) { if (typeBuilderGhostInterface != null && mw.IsVirtual) { var helper = mw.GetDefineMethodHelper(); - var stub = helper.DefineMethod(this, typeBuilder, name, MethodAttributes.Public); + var stub = helper.DefineMethod(this, typeBuilder, name, System.Reflection.MethodAttributes.Public); ((RuntimeGhostJavaMethod)mw).SetGhostMethod(stub); return helper.DefineMethod(this, typeBuilderGhostInterface, name, attribs); } @@ -647,7 +655,7 @@ protected override MethodBuilder DefineGhostMethod(TypeBuilder typeBuilder, stri return null; } - protected override void FinishGhost(TypeBuilder typeBuilder, RuntimeJavaMethod[] methods) + protected override void FinishGhost(ITypeSymbolBuilder typeBuilder, RuntimeJavaMethod[] methods) { if (typeBuilderGhostInterface != null) { @@ -664,24 +672,24 @@ protected override void FinishGhost(TypeBuilder typeBuilder, RuntimeJavaMethod[] var ilgen = Context.CodeEmitterFactory.Create(stub); var end = ilgen.DefineLabel(); var implementers = classLoader.GetGhostImplementers(this); - ilgen.Emit(OpCodes.Ldarg_0); - ilgen.Emit(OpCodes.Ldfld, ghostRefField); - ilgen.Emit(OpCodes.Dup); - ilgen.Emit(OpCodes.Isinst, typeBuilderGhostInterface); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldfld, ghostRefField); + ilgen.Emit(System.Reflection.Emit.OpCodes.Dup); + ilgen.Emit(System.Reflection.Emit.OpCodes.Isinst, typeBuilderGhostInterface); var label = ilgen.DefineLabel(); ilgen.EmitBrfalse(label); - ilgen.Emit(OpCodes.Castclass, typeBuilderGhostInterface); + ilgen.Emit(System.Reflection.Emit.OpCodes.Castclass, typeBuilderGhostInterface); for (int k = 0; k < args.Length; k++) { ilgen.EmitLdarg(k + 1); } - ilgen.Emit(OpCodes.Callvirt, (MethodInfo)methods[i].GetMethod()); + ilgen.Emit(System.Reflection.Emit.OpCodes.Callvirt, (IMethodSymbol)methods[i].GetMethod()); ilgen.EmitBr(end); ilgen.MarkLabel(label); for (int j = 0; j < implementers.Length; j++) { - ilgen.Emit(OpCodes.Dup); - ilgen.Emit(OpCodes.Isinst, implementers[j].TypeAsTBD); + ilgen.Emit(System.Reflection.Emit.OpCodes.Dup); + ilgen.Emit(System.Reflection.Emit.OpCodes.Isinst, implementers[j].TypeAsTBD); label = ilgen.DefineLabel(); ilgen.EmitBrfalse(label); var mw = implementers[j].GetMethodWrapper(methods[i].Name, methods[i].Signature, true); @@ -828,7 +836,7 @@ protected override void FinishGhost(TypeBuilder typeBuilder, RuntimeJavaMethod[] ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Ldtoken, typeBuilder); ilgen.Emit(OpCodes.Ldarg_1); - ilgen.Emit(OpCodes.Call, Context.Resolver.ResolveRuntimeType(typeof(IKVM.Runtime.GhostTag).FullName).AsReflection().GetMethod("IsGhostArrayInstance", BindingFlags.NonPublic | BindingFlags.Static)); + ilgen.Emit(OpCodes.Call, Context.Resolver.ResolveRuntimeType(typeof(IKVM.Runtime.GhostTag).FullName).GetMethod("IsGhostArrayInstance", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static)); ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); @@ -964,15 +972,15 @@ protected override TypeBuilder DefineGhostType(string mangledTypeName, TypeAttri return typeBuilder; } - internal override FieldInfo GhostRefField => ghostRefField; + internal override IFieldSymbol GhostRefField => ghostRefField; internal override void EmitCheckcast(CodeEmitter ilgen) { if (IsGhost) { - ilgen.Emit(OpCodes.Dup); - ilgen.Emit(OpCodes.Call, ghostCastMethod); - ilgen.Emit(OpCodes.Pop); + ilgen.Emit(System.Reflection.Emit.OpCodes.Dup); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, ghostCastMethod); + ilgen.Emit(System.Reflection.Emit.OpCodes.Pop); } else if (IsGhostArray) { @@ -985,8 +993,8 @@ internal override void EmitCheckcast(CodeEmitter ilgen) tw = tw.ElementTypeWrapper; } ilgen.EmitLdc_I4(rank); - ilgen.Emit(OpCodes.Call, ghostCastArrayMethod); - ilgen.Emit(OpCodes.Castclass, RuntimeArrayJavaType.MakeArrayType(Context.Types.Object, rank)); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, ghostCastArrayMethod); + ilgen.Emit(System.Reflection.Emit.OpCodes.Castclass, RuntimeArrayJavaType.MakeArrayType(Context.Types.Object, rank)); } else { @@ -998,11 +1006,11 @@ internal override void EmitInstanceOf(CodeEmitter ilgen) { if (IsGhost) { - ilgen.Emit(OpCodes.Call, ghostIsInstanceMethod); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, ghostIsInstanceMethod); } else if (IsGhostArray) { - ilgen.Emit(OpCodes.Call, ghostIsInstanceArrayMethod); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, ghostIsInstanceArrayMethod); } else { @@ -1017,12 +1025,12 @@ internal void SetAnnotation(Annotation annotation) internal override Annotation Annotation => annotation; - internal void SetEnumType(Type enumType) + internal void SetEnumType(ITypeSymbol enumType) { this.enumType = enumType; } - internal override Type EnumType => enumType; + internal override ITypeSymbol EnumType => enumType; sealed class ReplacedMethodWrapper : RuntimeJavaMethod { From 434f8b5b611ed46e8e91006ac95e4b512b2b06b0 Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Wed, 18 Sep 2024 10:55:48 -0500 Subject: [PATCH 07/51] Use safe method. --- src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs index 7037880a3..496e7b58e 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs @@ -92,7 +92,7 @@ public ReflectionMemberSymbol(ReflectionSymbolContext context, IReflectionModule public virtual MemberTypes MemberType => UnderlyingMember.MemberType; /// - public virtual int MetadataToken => UnderlyingMember.MetadataToken; + public virtual int MetadataToken => UnderlyingMember.GetMetadataTokenSafe(); /// public virtual string Name => UnderlyingMember.Name; From 41fdc5f22d436e7272fb0dcba085226485a59b40 Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Wed, 18 Sep 2024 16:46:59 -0500 Subject: [PATCH 08/51] Reintroduced IKVM Reflection. --- .../IIkvmReflectionAssemblySymbolBuilder.cs | 17 ++++++++++++ ...IIkvmReflectionConstructorSymbolBuilder.cs | 14 ++++++++++ .../Emit/IIkvmReflectionEventSymbolBuilder.cs | 14 ++++++++++ .../Emit/IIkvmReflectionFieldSymbolBuilder.cs | 14 ++++++++++ ...ectionGenericTypeParameterSymbolBuilder.cs | 22 ++++++++++++++++ .../IIkvmReflectionMemberSymbolBuilder.cs | 17 ++++++++++++ .../IIkvmReflectionMethodBaseSymbolBuilder.cs | 13 ++++++++++ .../IIkvmReflectionMethodSymbolBuilder.cs | 17 ++++++++++++ ...ectionGenericTypeParameterSymbolBuilder.cs | 5 ++-- .../ReflectionConstructorSymbolBuilder.cs | 2 +- src/IKVM.Reflection/Emit/MethodBuilder.cs | 2 +- src/IKVM.Reflection/Emit/ParameterBuilder.cs | 26 +++++++++++-------- src/IKVM.Reflection/EventInfo.cs | 8 +++--- 13 files changed, 151 insertions(+), 20 deletions(-) create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionAssemblySymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionConstructorSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionEventSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionFieldSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionGenericTypeParameterSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionMemberSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionMethodBaseSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionMethodSymbolBuilder.cs diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionAssemblySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionAssemblySymbolBuilder.cs new file mode 100644 index 000000000..c8f4ce03e --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionAssemblySymbolBuilder.cs @@ -0,0 +1,17 @@ +using IKVM.CoreLib.Symbols.Emit; +using IKVM.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + interface IIkvmReflectionAssemblySymbolBuilder : IIkvmReflectionSymbolBuilder, IAssemblySymbolBuilder, IIkvmReflectionAssemblySymbol + { + + /// + /// Gets the underlying . + /// + AssemblyBuilder UnderlyingAssemblyBuilder { get; } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionConstructorSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionConstructorSymbolBuilder.cs new file mode 100644 index 000000000..86b966f98 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionConstructorSymbolBuilder.cs @@ -0,0 +1,14 @@ +using IKVM.CoreLib.Symbols.Emit; +using IKVM.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + interface IIkvmReflectionConstructorSymbolBuilder : IIkvmReflectionSymbolBuilder, IIkvmReflectionMethodBaseSymbolBuilder, IConstructorSymbolBuilder, IIkvmReflectionConstructorSymbol + { + + ConstructorBuilder UnderlyingConstructorBuilder { get; } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionEventSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionEventSymbolBuilder.cs new file mode 100644 index 000000000..f5e3f728d --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionEventSymbolBuilder.cs @@ -0,0 +1,14 @@ +using IKVM.CoreLib.Symbols.Emit; +using IKVM.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + interface IIkvmReflectionEventSymbolBuilder : IIkvmReflectionSymbolBuilder, IIkvmReflectionMemberSymbolBuilder, IEventSymbolBuilder, IIkvmReflectionEventSymbol + { + + EventBuilder UnderlyingEventBuilder { get; } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionFieldSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionFieldSymbolBuilder.cs new file mode 100644 index 000000000..fe61f4f34 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionFieldSymbolBuilder.cs @@ -0,0 +1,14 @@ +using IKVM.CoreLib.Symbols.Emit; +using IKVM.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + interface IIkvmReflectionFieldSymbolBuilder : IIkvmReflectionSymbolBuilder, IIkvmReflectionMemberSymbolBuilder, IFieldSymbolBuilder, IIkvmReflectionFieldSymbol + { + + FieldBuilder UnderlyingFieldBuilder { get; } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionGenericTypeParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionGenericTypeParameterSymbolBuilder.cs new file mode 100644 index 000000000..889de61f2 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionGenericTypeParameterSymbolBuilder.cs @@ -0,0 +1,22 @@ +using IKVM.CoreLib.Symbols.Emit; +using IKVM.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + interface IIkvmReflectionGenericTypeParameterSymbolBuilder : IIkvmReflectionSymbolBuilder, IGenericTypeParameterSymbolBuilder, IIkvmReflectionTypeSymbol + { + + /// + /// Gets the underlying . + /// + GenericTypeParameterBuilder UnderlyingGenericTypeParameterBuilder { get; } + + /// + /// Invoked when the type containing this generic type parameter is completed. + /// + void OnComplete(); + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionMemberSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionMemberSymbolBuilder.cs new file mode 100644 index 000000000..e6d8459ce --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionMemberSymbolBuilder.cs @@ -0,0 +1,17 @@ +using IKVM.CoreLib.Symbols.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + interface IIkvmReflectionMemberSymbolBuilder : IIkvmReflectionSymbolBuilder, IMemberSymbolBuilder, IIkvmReflectionMemberSymbol + { + + /// + /// Invoked when the type responsible for this builder is completed. Implementations should update their + /// underlying type, and optionally dispatch the OnComplete invocation to downstream elements. + /// + void OnComplete(); + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionMethodBaseSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionMethodBaseSymbolBuilder.cs new file mode 100644 index 000000000..b5e6fcd57 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionMethodBaseSymbolBuilder.cs @@ -0,0 +1,13 @@ +using IKVM.CoreLib.Symbols.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + interface IIkvmReflectionMethodBaseSymbolBuilder : IIkvmReflectionSymbolBuilder, IIkvmReflectionMemberSymbolBuilder, IMethodBaseSymbolBuilder, IIkvmReflectionMethodBaseSymbol + { + + + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionMethodSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionMethodSymbolBuilder.cs new file mode 100644 index 000000000..8de047893 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionMethodSymbolBuilder.cs @@ -0,0 +1,17 @@ +using IKVM.CoreLib.Symbols.Emit; +using IKVM.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + interface IIkvmReflectionMethodSymbolBuilder : IIkvmReflectionSymbolBuilder, IIkvmReflectionMethodBaseSymbolBuilder, IMethodSymbolBuilder, IIkvmReflectionMethodSymbol + { + + /// + /// Gets the underlying . + /// + MethodBuilder UnderlyingMethodBuilder { get; } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionGenericTypeParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionGenericTypeParameterSymbolBuilder.cs index 20917942a..a9cc7500f 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionGenericTypeParameterSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionGenericTypeParameterSymbolBuilder.cs @@ -1,9 +1,8 @@ using System.Reflection.Emit; -using IKVM.CoreLib.Symbols.Reflection; -using IKVM.CoreLib.Symbols.Reflection.Emit; +using IKVM.CoreLib.Symbols.Emit; -namespace IKVM.CoreLib.Symbols.Emit +namespace IKVM.CoreLib.Symbols.Reflection.Emit { interface IReflectionGenericTypeParameterSymbolBuilder : IReflectionSymbolBuilder, IGenericTypeParameterSymbolBuilder, IReflectionTypeSymbol diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionConstructorSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionConstructorSymbolBuilder.cs index 2dbde97d2..e9692b2c9 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionConstructorSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionConstructorSymbolBuilder.cs @@ -48,7 +48,7 @@ public void SetImplementationFlags(MethodImplAttributes attributes) /// public IParameterSymbolBuilder DefineParameter(int iSequence, ParameterAttributes attributes, string? strParamName) { - return new ReflectionParameterSymbolBuilder(Context, ResolvingModule, this, UnderlyingConstructorBuilder.DefineParameter(iSequence, attributes, strParamName)); + return ResolveParameterSymbol(UnderlyingConstructorBuilder.DefineParameter(iSequence, attributes, strParamName)); } /// diff --git a/src/IKVM.Reflection/Emit/MethodBuilder.cs b/src/IKVM.Reflection/Emit/MethodBuilder.cs index db75abaf6..f0757a90d 100644 --- a/src/IKVM.Reflection/Emit/MethodBuilder.cs +++ b/src/IKVM.Reflection/Emit/MethodBuilder.cs @@ -285,7 +285,7 @@ public ParameterBuilder DefineParameter(int position, ParameterAttributes attrib parameters ??= new List(); ModuleBuilder.ParamTable.AddVirtualRecord(); - var pb = new ParameterBuilder(ModuleBuilder, position, attributes, strParamName); + var pb = new ParameterBuilder(this, position, attributes, strParamName); if (parameters.Count == 0 || position >= parameters[parameters.Count - 1].Position) { parameters.Add(pb); diff --git a/src/IKVM.Reflection/Emit/ParameterBuilder.cs b/src/IKVM.Reflection/Emit/ParameterBuilder.cs index 153c18cd5..a74563289 100644 --- a/src/IKVM.Reflection/Emit/ParameterBuilder.cs +++ b/src/IKVM.Reflection/Emit/ParameterBuilder.cs @@ -29,7 +29,7 @@ namespace IKVM.Reflection.Emit public sealed class ParameterBuilder { - readonly ModuleBuilder module; + readonly MethodBuilder method; short flags; readonly short sequence; readonly StringHandle nameIndex; @@ -39,16 +39,16 @@ public sealed class ParameterBuilder /// /// Initializes a new instance. /// - /// + /// /// /// /// - internal ParameterBuilder(ModuleBuilder module, int sequence, ParameterAttributes attribs, string name) + internal ParameterBuilder(MethodBuilder method, int sequence, ParameterAttributes attribs, string name) { - this.module = module; + this.method = method; this.flags = (short)attribs; this.sequence = (short)sequence; - this.nameIndex = name == null ? default : module.GetOrAddString(name); + this.nameIndex = name == null ? default : method.ModuleBuilder.GetOrAddString(name); this.name = name; } @@ -57,12 +57,16 @@ internal int PseudoToken get { if (lazyPseudoToken == 0) - lazyPseudoToken = module.AllocPseudoToken(); + lazyPseudoToken = method.ModuleBuilder.AllocPseudoToken(); return lazyPseudoToken; } } + public MethodInfo Method => method; + + public Module Module => method.Module; + public string Name { get { return name; } @@ -115,11 +119,11 @@ public void SetCustomAttribute(CustomAttributeBuilder customAttributeBuilder) flags |= (short)ParameterAttributes.Optional; break; case KnownCA.MarshalAsAttribute: - FieldMarshal.SetMarshalAsAttribute(module, PseudoToken, customAttributeBuilder); + FieldMarshal.SetMarshalAsAttribute(method.ModuleBuilder, PseudoToken, customAttributeBuilder); flags |= (short)ParameterAttributes.HasFieldMarshal; break; default: - module.SetCustomAttribute(PseudoToken, customAttributeBuilder); + method.ModuleBuilder.SetCustomAttribute(PseudoToken, customAttributeBuilder); break; } } @@ -127,12 +131,12 @@ public void SetCustomAttribute(CustomAttributeBuilder customAttributeBuilder) public void SetConstant(object defaultValue) { flags |= (short)ParameterAttributes.HasDefault; - module.AddConstant(PseudoToken, defaultValue); + method.ModuleBuilder.AddConstant(PseudoToken, defaultValue); } internal void WriteMetadata() { - module.Metadata.AddParameter( + method.ModuleBuilder.Metadata.AddParameter( (System.Reflection.ParameterAttributes)flags, nameIndex, sequence); @@ -141,7 +145,7 @@ internal void WriteMetadata() internal void FixupToken(int parameterToken) { if (lazyPseudoToken != 0) - module.RegisterTokenFixup(lazyPseudoToken, parameterToken); + method.ModuleBuilder.RegisterTokenFixup(lazyPseudoToken, parameterToken); } } diff --git a/src/IKVM.Reflection/EventInfo.cs b/src/IKVM.Reflection/EventInfo.cs index 5d2d3ac1e..00900534c 100644 --- a/src/IKVM.Reflection/EventInfo.cs +++ b/src/IKVM.Reflection/EventInfo.cs @@ -29,10 +29,10 @@ namespace IKVM.Reflection public abstract class EventInfo : MemberInfo { - /// - /// Initializes a new instance. - /// - internal EventInfo() + /// + /// Initializes a new instance. + /// + protected EventInfo() { } From 149ddcdba7f8a4c9d620a7ab74b1abf461a76526 Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Wed, 18 Sep 2024 19:19:38 -0500 Subject: [PATCH 09/51] More replacement. --- .../IkvmReflectionSymbolTests.cs | 665 ++++++++++----- .../IIkvmReflectionModuleSymbolBuilder.cs | 17 + .../IIkvmReflectionParameterSymbolBuilder.cs | 22 + .../IIkvmReflectionPropertySymbolBuilder.cs | 14 + .../Emit/IIkvmReflectionSymbolBuilder.cs | 19 + .../Emit/IIkvmReflectionTypeSymbolBuilder.cs | 17 + .../IkvmReflectionAssemblySymbolBuilder.cs | 202 +++++ .../IkvmReflectionConstructorSymbolBuilder.cs | 97 +++ .../IkvmReflectionCustomAttributeBuilder.cs | 29 + .../Emit/IkvmReflectionEventSymbolBuilder.cs | 163 ++++ .../Emit/IkvmReflectionFieldSymbolBuilder.cs | 145 ++++ ...ectionGenericTypeParameterSymbolBuilder.cs | 584 +++++++++++++ .../Emit/IkvmReflectionMemberSymbolBuilder.cs | 313 +++++++ .../IkvmReflectionMethodBaseSymbolBuilder.cs | 122 +++ .../Emit/IkvmReflectionMethodSymbolBuilder.cs | 150 ++++ .../Emit/IkvmReflectionModuleSymbolBuilder.cs | 382 +++++++++ .../IkvmReflectionParameterBuilderInfo.cs | 71 ++ .../IkvmReflectionParameterSymbolBuilder.cs | 164 ++++ .../IkvmReflectionPropertySymbolBuilder.cs | 184 ++++ .../Emit/IkvmReflectionSymbolBuilder.cs | 24 + .../Emit/IkvmReflectionTypeSymbolBuilder.cs | 802 ++++++++++++++++++ .../IIkvmReflectionAssemblySymbol.cs | 32 + .../IIkvmReflectionConstructorSymbol.cs | 16 + .../IIkvmReflectionEventSymbol.cs | 16 + .../IIkvmReflectionFieldSymbol.cs | 16 + .../IIkvmReflectionMemberSymbol.cs | 26 + .../IIkvmReflectionMethodBaseSymbol.cs | 16 + .../IIkvmReflectionMethodSymbol.cs | 16 + .../IIkvmReflectionModuleSymbol.cs | 123 +++ .../IIkvmReflectionParameterSymbol.cs | 26 + .../IIkvmReflectionPropertySymbol.cs | 16 + .../IkvmReflection/IIkvmReflectionSymbol.cs | 336 ++++++++ .../IIkvmReflectionTypeSymbol.cs | 16 + .../IkvmReflectionAssemblyMetadata.cs | 63 ++ .../IkvmReflectionAssemblySymbol.cs | 162 ++++ .../IkvmReflectionConstructorSymbol.cs | 34 + .../IkvmReflectionEventSymbol.cs | 104 +++ .../IkvmReflectionFieldSymbol.cs | 98 +++ ...kvmReflectionGenericTypeParameterSymbol.cs | 566 ++++++++++++ .../IkvmReflectionMemberSymbol.cs | 286 +++++++ .../IkvmReflectionMethodBaseSymbol.cs | 108 +++ .../IkvmReflectionMethodSymbol.cs | 65 ++ .../IkvmReflectionModuleMetadata.cs | 480 +++++++++++ .../IkvmReflectionModuleSymbol.cs | 320 +++++++ .../IkvmReflectionParameterSymbol.cs | 121 +++ .../IkvmReflectionPropertySymbol.cs | 121 +++ .../IkvmReflection/IkvmReflectionSymbol.cs | 549 ++++++++++++ .../IkvmReflectionSymbolContext.cs | 297 +++++++ .../IkvmReflectionSymbolExtensions.cs | 11 + .../IkvmReflection/IkvmReflectionTypeImpl.cs | 587 +++++++++++++ .../IkvmReflectionTypeSymbol.cs | 554 ++++++++++++ .../IkvmReflection/IkvmReflectionUtil.cs | 315 +++++++ .../Emit/ReflectionParameterSymbolBuilder.cs | 4 +- src/IKVM.Reflection/Emit/PropertyBuilder.cs | 11 + src/IKVM.Runtime/AttributeHelper.cs | 6 +- src/IKVM.Runtime/ByteCodeHelper.cs | 2 +- src/IKVM.Runtime/CodeEmitter.cs | 2 +- .../Java/Externs/sun/misc/Unsafe.cs | 24 +- src/IKVM.Runtime/LambdaMetafactory.cs | 132 +-- src/IKVM.Runtime/ReflectUtil.cs | 11 +- src/IKVM.Runtime/RuntimeArrayJavaType.cs | 12 - .../RuntimeByteCodeJavaType.FinishContext.cs | 182 ++-- .../RuntimeByteCodeJavaType.JavaTypeImpl.cs | 46 +- src/IKVM.Runtime/RuntimeJavaField.cs | 16 +- src/IKVM.Runtime/RuntimeJavaType.cs | 78 +- .../RuntimeManagedByteCodeJavaType.cs | 2 +- ...gedJavaType.AttributeAnnotationJavaType.cs | 6 +- ...ntimeManagedJavaType.DelegateJavaMethod.cs | 32 +- src/IKVM.Runtime/Serialization.cs | 40 +- src/IKVM.Runtime/SymbolExtensions.cs | 56 +- src/IKVM.Runtime/atomic.cs | 107 ++- src/IKVM.Runtime/compiler.cs | 86 +- 72 files changed, 9894 insertions(+), 643 deletions(-) create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionModuleSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionParameterSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionPropertySymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionTypeSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionAssemblySymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionConstructorSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionCustomAttributeBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionEventSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionFieldSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionGenericTypeParameterSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMemberSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodBaseSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionModuleSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterBuilderInfo.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionPropertySymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionTypeSymbolBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionAssemblySymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionConstructorSymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionEventSymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionFieldSymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionMemberSymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionMethodBaseSymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionMethodSymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionModuleSymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionParameterSymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionPropertySymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionSymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionTypeSymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblyMetadata.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionConstructorSymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionEventSymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionFieldSymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionGenericTypeParameterSymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodBaseSymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodSymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleMetadata.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterSymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionPropertySymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolContext.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolExtensions.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeImpl.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionUtil.cs diff --git a/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs b/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs index 47eb9aed4..b33adef9e 100644 --- a/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs +++ b/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs @@ -1,221 +1,444 @@ -//using System.IO; - -//using FluentAssertions; - -//using IKVM.CoreLib.Symbols.IkvmReflection; -//using IKVM.Reflection; - -//using Microsoft.VisualStudio.TestPlatform.PlatformAbstractions; -//using Microsoft.VisualStudio.TestTools.UnitTesting; - -//namespace IKVM.CoreLib.Tests.Symbols.IkvmReflection -//{ - -// [TestClass] -// public class IkvmReflectionSymbolTests -// { - -// class Foo -// { - -// T? field; - -// bool Method(int p1) => true; - -// } - -// Universe? universe; -// Assembly? coreAssembly; -// Assembly? thisAssembly; - -// [TestInitialize] -// public void Setup() -// { -// universe = new Universe(typeof(object).Assembly.GetName().Name); -// universe.AssemblyResolve += Universe_AssemblyResolve; -// coreAssembly = universe.LoadFile(typeof(object).Assembly.GetAssemblyLocation()); -// thisAssembly = universe.LoadFile(typeof(IkvmReflectionSymbolTests).Assembly.GetAssemblyLocation()); -// } - -// /// -// /// Attempt to load assembly from system. -// /// -// /// -// /// -// /// -// Assembly? Universe_AssemblyResolve(object sender, ResolveEventArgs args) -// { -// try -// { -// var asm = System.Reflection.Assembly.Load(args.Name); -// if (asm != null && File.Exists(asm.Location)) -// return universe!.LoadFile(asm.Location); -// } -// catch -// { - -// } - -// return null; -// } - -// [TestMethod] -// public void SameTypeShouldBeSame() -// { -// var c = new IkvmReflectionSymbolContext(); -// var s1 = c.GetOrCreateTypeSymbol(universe!.GetBuiltInType("System", "Object")); -// var s2 = c.GetOrCreateTypeSymbol(universe!.GetBuiltInType("System", "Object")); -// s1.Should().BeSameAs(s2); -// } - -// [TestMethod] -// public void GenericTypeDefinitionShouldBeSame() -// { -// var t = thisAssembly!.GetType("IKVM.CoreLib.Tests.Symbols.IkvmReflection.IkvmReflectionSymbolTests+Foo`1"); -// var c = new IkvmReflectionSymbolContext(); -// var s1 = c.GetOrCreateTypeSymbol(t); -// var s2 = c.GetOrCreateTypeSymbol(t); -// s1.Should().BeSameAs(s2); -// } - -// [TestMethod] -// public void GenericTypeShouldBeSame() -// { -// var t = thisAssembly!.GetType("IKVM.CoreLib.Tests.Symbols.IkvmReflection.IkvmReflectionSymbolTests+Foo`1").MakeGenericType(universe!.GetBuiltInType("System", "Int32")); -// var c = new IkvmReflectionSymbolContext(); -// var s1 = c.GetOrCreateTypeSymbol(t); -// var s2 = c.GetOrCreateTypeSymbol(t); -// s1.Should().BeSameAs(s2); -// } - -// [TestMethod] -// public void ArrayTypeShouldBeSame() -// { -// var t = universe!.GetBuiltInType("System", "Object").MakeArrayType(2); -// var c = new IkvmReflectionSymbolContext(); -// var s1 = c.GetOrCreateTypeSymbol(t); -// var s2 = c.GetOrCreateTypeSymbol(t); -// s1.Should().BeSameAs(s2); -// } - -// [TestMethod] -// public void SZArrayTypeShouldBeSame() -// { -// var t = universe!.GetBuiltInType("System", "Object").MakeArrayType(); -// var c = new IkvmReflectionSymbolContext(); -// var s1 = c.GetOrCreateTypeSymbol(t); -// var s2 = c.GetOrCreateTypeSymbol(t); -// s1.Should().BeSameAs(s2); -// } - -// [TestMethod] -// public unsafe void PointerTypeShouldBeSame() -// { -// var t = universe!.GetBuiltInType("System", "Int32").MakePointerType(); -// var c = new IkvmReflectionSymbolContext(); -// var s1 = c.GetOrCreateTypeSymbol(t); -// var s2 = c.GetOrCreateTypeSymbol(t); -// s1.Should().BeSameAs(s2); -// } - -// [TestMethod] -// public unsafe void ByRefTypeShouldBeSame() -// { -// var t = universe!.GetBuiltInType("System", "Int32").MakeByRefType(); -// var c = new IkvmReflectionSymbolContext(); -// var s1 = c.GetOrCreateTypeSymbol(t); -// var s2 = c.GetOrCreateTypeSymbol(t); -// s1.Should().BeSameAs(s2); -// } - -// [TestMethod] -// public void EnumTypeShouldBeSame() -// { -// var a = universe!.Load(typeof(System.AttributeTargets).Assembly.FullName); -// var t = a.GetType("System.AttributeTargets"); -// var c = new IkvmReflectionSymbolContext(); -// var s1 = c.GetOrCreateTypeSymbol(t); -// var s2 = c.GetOrCreateTypeSymbol(t); -// s1.Should().BeSameAs(s2); -// } - -// [TestMethod] -// public void CanGetType() -// { -// var t = universe!.GetBuiltInType("System", "Object"); -// var c = new IkvmReflectionSymbolContext(); -// var s = c.GetOrCreateTypeSymbol(t); -// s.Name.Should().Be("Object"); -// s.FullName.Should().Be("System.Object"); -// } - -// [TestMethod] -// public void CanGetFieldOfGenericTypeDefinition() -// { -// var t = thisAssembly!.GetType("IKVM.CoreLib.Tests.Symbols.IkvmReflection.IkvmReflectionSymbolTests+Foo`1"); -// var c = new IkvmReflectionSymbolContext(); -// var s = c.GetOrCreateTypeSymbol(t); -// s.IsGenericType.Should().BeTrue(); -// s.IsGenericTypeDefinition.Should().BeTrue(); -// var f = s.GetField("field", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); -// f.Name.Should().Be("field"); -// f.FieldType.IsGenericType.Should().BeFalse(); -// f.FieldType.IsGenericParameter.Should().BeTrue(); -// } - -// [TestMethod] -// public void CanGetFieldOfGenericType() -// { -// var t = thisAssembly!.GetType("IKVM.CoreLib.Tests.Symbols.IkvmReflection.IkvmReflectionSymbolTests+Foo`1").MakeGenericType(universe!.GetBuiltInType("System", "Int32")); -// var c = new IkvmReflectionSymbolContext(); -// var s = c.GetOrCreateTypeSymbol(t); -// s.IsGenericType.Should().BeTrue(); -// s.IsGenericTypeDefinition.Should().BeFalse(); -// var f = s.GetField("field", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); -// f.Name.Should().Be("field"); -// f.FieldType.IsGenericType.Should().BeFalse(); -// f.FieldType.IsGenericParameter.Should().BeFalse(); -// f.FieldType.Should().BeSameAs(c.GetOrCreateTypeSymbol(universe!.GetBuiltInType("System", "Int32"))); -// } - -// [TestMethod] -// public void CanGetMethod() -// { -// var t = universe!.GetBuiltInType("System", "Object"); -// var c = new IkvmReflectionSymbolContext(); -// var s = c.GetOrCreateTypeSymbol(t); -// var m = s.GetMethod("ToString"); -// m.Name.Should().Be("ToString"); -// m.ReturnType.Should().BeSameAs(c.GetOrCreateTypeSymbol(universe!.GetBuiltInType("System", "String"))); -// m.ReturnParameter.ParameterType.Should().BeSameAs(c.GetOrCreateTypeSymbol(universe!.GetBuiltInType("System", "String"))); -// m.IsGenericMethod.Should().BeFalse(); -// m.IsGenericMethodDefinition.Should().BeFalse(); -// m.IsPublic.Should().BeTrue(); -// m.IsPrivate.Should().BeFalse(); -// } - -// [System.AttributeUsage(System.AttributeTargets.Class)] -// class AttributeWithType : System.Attribute -// { - -// public AttributeWithType(System.Type type) -// { -// Type = type; -// } - -// public System.Type Type { get; } - -// } -// [TestMethod] -// public void CanReadCustomAttributes() -// { -// var c = new IkvmReflectionSymbolContext(); -// var s = c.GetOrCreateTypeSymbol(thisAssembly!.GetType("IKVM.CoreLib.Tests.Symbols.IkvmReflection.IkvmReflectionSymbolTests+ClassWithAttributeWithType")); -// var a = s.GetCustomAttribute(c.GetOrCreateTypeSymbol(thisAssembly!.GetType("IKVM.CoreLib.Tests.Symbols.IkvmReflection.IkvmReflectionSymbolTests+AttributeWithType"))); -// var v = a.Value.ConstructorArguments[0].Value; -// v.Should().BeOfType(); -// } - -// } - -//} +using System; +using System.IO; +using System.Linq; + +using FluentAssertions; + +using IKVM.CoreLib.Symbols.IkvmReflection; +using IKVM.CoreLib.Symbols.IkvmReflection.Emit; +using IKVM.Reflection; +using IKVM.Reflection.Emit; + +using Microsoft.VisualStudio.TestPlatform.PlatformAbstractions; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace IKVM.CoreLib.Tests.Symbols.IkvmReflection +{ + + [TestClass] + public class IkvmReflectionSymbolTests + { + + class Foo + { + + T? field; + + bool Method(int p1) => true; + + } + + Universe? universe; + Assembly? coreAssembly; + Assembly? thisAssembly; + + [TestInitialize] + public void Setup() + { + universe = new Universe(typeof(object).Assembly.GetName().Name); + universe.AssemblyResolve += Universe_AssemblyResolve; + coreAssembly = universe.LoadFile(typeof(object).Assembly.GetAssemblyLocation()); + thisAssembly = universe.LoadFile(typeof(IkvmReflectionSymbolTests).Assembly.GetAssemblyLocation()); + } + + /// + /// Attempt to load assembly from system. + /// + /// + /// + /// + Assembly? Universe_AssemblyResolve(object sender, IKVM.Reflection.ResolveEventArgs args) + { + try + { + var asm = System.Reflection.Assembly.Load(args.Name); + if (asm != null && File.Exists(asm.Location)) + return universe!.LoadFile(asm.Location); + } + catch + { + + } + + return null; + } + + [TestMethod] + public void SameTypeShouldBeSame() + { + var c = new IkvmReflectionSymbolContext(); + var s1 = c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.Object")); + var s2 = c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.Object")); + s1.Should().BeOfType(); + s1.Should().BeSameAs(s2); + } + + [TestMethod] + public void GenericTypeDefinitionShouldBeSame() + { + var c = new IkvmReflectionSymbolContext(); + var s1 = c.GetOrCreateTypeSymbol(thisAssembly.GetType("IKVM.CoreLib.Tests.Symbols.IkvmReflection.IkvmReflectionSymbolTests+Foo`1")); + var s2 = c.GetOrCreateTypeSymbol(thisAssembly.GetType("IKVM.CoreLib.Tests.Symbols.IkvmReflection.IkvmReflectionSymbolTests+Foo`1")); + s1.Should().BeSameAs(s2); + } + + [TestMethod] + public void GenericTypeShouldBeSame() + { + var c = new IkvmReflectionSymbolContext(); + var s1 = c.GetOrCreateTypeSymbol(thisAssembly.GetType("IKVM.CoreLib.Tests.Symbols.IkvmReflection.IkvmReflectionSymbolTests+Foo`1").MakeGenericType(coreAssembly.GetType("System.Int32"))); + var s2 = c.GetOrCreateTypeSymbol(thisAssembly.GetType("IKVM.CoreLib.Tests.Symbols.IkvmReflection.IkvmReflectionSymbolTests+Foo`1").MakeGenericType(coreAssembly.GetType("System.Int32"))); + s1.Should().BeSameAs(s2); + } + + [TestMethod] + public void ArrayTypeShouldBeSame() + { + var c = new IkvmReflectionSymbolContext(); + var s1 = c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.Object").MakeArrayType(2)); + var s2 = c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.Object").MakeArrayType(2)); + s1.Should().BeSameAs(s2); + } + + [TestMethod] + public void SZArrayTypeShouldBeSame() + { + var c = new IkvmReflectionSymbolContext(); + var s1 = c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.Int32").MakeArrayType()); + var s2 = c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.Int32").MakeArrayType()); + s1.Should().BeSameAs(s2); + } + + [TestMethod] + public unsafe void PointerTypeShouldBeSame() + { + var c = new IkvmReflectionSymbolContext(); + var s1 = c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.Int32").MakePointerType()); + var s2 = c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.Int32").MakePointerType()); + s1.Should().BeSameAs(s2); + } + + [TestMethod] + public unsafe void ByRefTypeShouldBeSame() + { + var c = new IkvmReflectionSymbolContext(); + var s1 = c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.Int32").MakeByRefType()); + var s2 = c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.Int32").MakeByRefType()); + s1.Should().BeSameAs(s2); + } + + [TestMethod] + public void EnumTypeShouldBeSame() + { + var c = new IkvmReflectionSymbolContext(); + var s1 = c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.AttributeTargets")); + var s2 = c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.AttributeTargets")); + s1.Should().BeSameAs(s2); + } + + [TestMethod] + public void CanResolveType() + { + var c = new IkvmReflectionSymbolContext(); + var s = c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.Object")); + s.Name.Should().Be("Object"); + s.FullName.Should().Be("System.Object"); + } + + [TestMethod] + public void CanResolveFieldOfGenericTypeDefinition() + { + var c = new IkvmReflectionSymbolContext(); + var s = c.GetOrCreateTypeSymbol(thisAssembly.GetType("IKVM.CoreLib.Tests.Symbols.IkvmReflection.IkvmReflectionSymbolTests+Foo`1")); + s.IsGenericType.Should().BeTrue(); + s.IsGenericTypeDefinition.Should().BeTrue(); + var f = s.GetField("field", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); + f.Name.Should().Be("field"); + f.FieldType.IsGenericType.Should().BeFalse(); + f.FieldType.IsGenericParameter.Should().BeTrue(); + } + + [TestMethod] + public void CanResolveFieldOfGenericType() + { + var c = new IkvmReflectionSymbolContext(); + var s = c.GetOrCreateTypeSymbol(thisAssembly.GetType("IKVM.CoreLib.Tests.Symbols.IkvmReflection.IkvmReflectionSymbolTests+Foo`1").MakeGenericType(coreAssembly.GetType("System.Int32"))); + s.IsGenericType.Should().BeTrue(); + s.IsGenericTypeDefinition.Should().BeFalse(); + var f = s.GetField("field", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); + f.Name.Should().Be("field"); + f.FieldType.IsGenericType.Should().BeFalse(); + f.FieldType.IsGenericParameter.Should().BeFalse(); + f.FieldType.Should().BeSameAs(c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.Int32"))); + } + + [TestMethod] + public void CanResolveMethod() + { + var c = new IkvmReflectionSymbolContext(); + var s = c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.Object")); + var m = s.GetMethod("ToString"); + m.Name.Should().Be("ToString"); + m.ReturnType.Should().BeSameAs(c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.String"))); + m.ReturnParameter.ParameterType.Should().BeSameAs(c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.String"))); + m.IsGenericMethod.Should().BeFalse(); + m.IsGenericMethodDefinition.Should().BeFalse(); + m.IsPublic.Should().BeTrue(); + m.IsPrivate.Should().BeFalse(); + } + + [TestMethod] + public void CanResolveGenericMethod() + { + var c = new IkvmReflectionSymbolContext(); + var s = c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.ValueTuple")); + var m = s.GetMethods().FirstOrDefault(i => i.Name == "Create" && i.GetGenericArguments().Length == 1); + m.Name.Should().Be("Create"); + m.ReturnType.Should().BeSameAs(c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.ValueTuple`1")).MakeGenericType(m.GetGenericArguments()[0])); + m.ReturnParameter.ParameterType.Should().BeSameAs(c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.ValueTuple`1")).MakeGenericType(m.GetGenericArguments()[0])); + m.IsGenericMethod.Should().BeTrue(); + m.IsGenericMethodDefinition.Should().BeTrue(); + m.IsPublic.Should().BeTrue(); + m.IsPrivate.Should().BeFalse(); + } + + [TestMethod] + public void CanResolveParameters() + { + var c = new IkvmReflectionSymbolContext(); + var s = c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.Object")); + var m = s.GetMethod("ReferenceEquals"); + m.Name.Should().Be("ReferenceEquals"); + m.ReturnType.Should().BeSameAs(c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.Boolean"))); + m.ReturnParameter.ParameterType.Should().BeSameAs(c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.Boolean"))); + m.IsGenericMethod.Should().BeFalse(); + m.IsGenericMethodDefinition.Should().BeFalse(); + m.IsPublic.Should().BeTrue(); + m.IsPrivate.Should().BeFalse(); + var p = m.GetParameters(); + p.Length.Should().Be(2); + p[0].Name.Should().Be("objA"); + p[0].ParameterType.Should().Be(c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.Object"))); + p[1].Name.Should().Be("objB"); + p[1].ParameterType.Should().Be(c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.Object"))); + } + + [AttributeUsage(AttributeTargets.Class)] + class AttributeWithType : Attribute + { + + public AttributeWithType(System.Type type) + { + Type = type; + } + + public System.Type Type { get; } + + } + + [AttributeWithType(typeof(object))] + class ClassWithAttributeWithType + { + + + + } + + [TestMethod] + public void CanReadCustomAttributes() + { + var c = new IkvmReflectionSymbolContext(); + var s = c.GetOrCreateTypeSymbol(thisAssembly.GetType("IKVM.CoreLib.Tests.Symbols.IkvmReflection.IkvmReflectionSymbolTests+ClassWithAttributeWithType")); + var a = s.GetCustomAttribute(c.GetOrCreateTypeSymbol(thisAssembly.GetType("IKVM.CoreLib.Tests.Symbols.IkvmReflection.IkvmReflectionSymbolTests+AttributeWithType"))); + var v = a.Value.ConstructorArguments[0].Value; + v.Should().BeOfType(); + } + + [TestMethod] + public void CanResolveAssemblyBuilder() + { + var c = new IkvmReflectionSymbolContext(); + var a = universe.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Save); + var assemblySymbol = c.GetOrCreateAssemblySymbol(a); + assemblySymbol.Should().BeOfType(); + assemblySymbol.Should().BeSameAs(c.GetOrCreateAssemblySymbol(a)); + } + + [TestMethod] + public void CanResolveModuleBuilder() + { + var c = new IkvmReflectionSymbolContext(); + var a = universe.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Save); + var m = a.DefineDynamicModule("DynamicModule", "DynamicModule.dll"); + var moduleSymbol = c.GetOrCreateModuleSymbol(m); + moduleSymbol.Should().BeOfType(); + moduleSymbol.Should().BeSameAs(c.GetOrCreateModuleSymbol(m)); + } + + [TestMethod] + public void CanResolveTypeBuilder() + { + var c = new IkvmReflectionSymbolContext(); + var a = universe.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Save); + var m = a.DefineDynamicModule("DynamicModule", "DynamicModule.dll"); + + var type1 = m.DefineType("DynamicType1"); + var type1Symbol = c.GetOrCreateTypeSymbol(type1); + type1Symbol.Should().BeOfType(); + type1Symbol.Should().BeSameAs(c.GetOrCreateTypeSymbol(type1)); + } + + [TestMethod] + public void CanResolveMultipleTypeBuilders() + { + var c = new IkvmReflectionSymbolContext(); + var a = universe.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Save); + var m = a.DefineDynamicModule("DynamicModule", "DynamicModule.dll"); + + var type1 = m.DefineType("DynamicType1"); + var type1Symbol = c.GetOrCreateTypeSymbol(type1); + type1Symbol.Should().BeOfType(); + type1Symbol.Should().BeSameAs(c.GetOrCreateTypeSymbol(type1)); + type1.CreateType(); + + var type2 = m.DefineType("DynamicType2"); + var type2Symbol = c.GetOrCreateTypeSymbol(type2); + type2Symbol.Should().BeOfType(); + type2Symbol.Should().BeSameAs(c.GetOrCreateTypeSymbol(type2)); + } + + [TestMethod] + public void CanResolveMethodBuilder() + { + var c = new IkvmReflectionSymbolContext(); + var a = universe.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Save); + var m = a.DefineDynamicModule("DynamicModule", "DynamicModule.dll"); + var t = m.DefineType("DynamicType"); + + var method1 = t.DefineMethod("DynamicMethod1", MethodAttributes.Public | MethodAttributes.Static); + var method1Symbol = c.GetOrCreateMethodSymbol(method1); + method1Symbol.Should().BeOfType(); + method1Symbol.Should().BeSameAs(c.GetOrCreateMethodSymbol(method1)); + } + + [TestMethod] + public void CanResolveMultipleMethodBuilders() + { + var c = new IkvmReflectionSymbolContext(); + var a = universe.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Save); + var m = a.DefineDynamicModule("DynamicModule", "DynamicModule.dll"); + var t = m.DefineType("DynamicType"); + + var method1 = t.DefineMethod("DynamicMethod1", MethodAttributes.Public | MethodAttributes.Static); + var method1Symbol = c.GetOrCreateMethodSymbol(method1); + method1Symbol.Should().BeOfType(); + method1Symbol.Should().BeSameAs(c.GetOrCreateMethodSymbol(method1)); + + var method2 = t.DefineMethod("DynamicMethod2", MethodAttributes.Public | MethodAttributes.Static); + var method2Symbol = c.GetOrCreateMethodSymbol(method2); + method2Symbol.Should().BeOfType(); + method2Symbol.Should().BeSameAs(c.GetOrCreateMethodSymbol(method2)); + } + + [TestMethod] + public void CanResolveFieldBuilder() + { + var c = new IkvmReflectionSymbolContext(); + var a = universe.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Save); + var m = a.DefineDynamicModule("DynamicModule", "DynamicModule.dll"); + var t = m.DefineType("DynamicType"); + + var field = t.DefineField("dynamicField", coreAssembly.GetType("System.Object"), FieldAttributes.Public); + var fieldSymbol = c.GetOrCreateFieldSymbol(field); + fieldSymbol.Should().BeOfType(); + fieldSymbol.Should().BeSameAs(c.GetOrCreateFieldSymbol(field)); + } + + [TestMethod] + public void CanResolveMultipleFieldBuilders() + { + var c = new IkvmReflectionSymbolContext(); + var a = universe.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Save); + var m = a.DefineDynamicModule("DynamicModule", "DynamicModule.dll"); + var t = m.DefineType("DynamicType"); + + var field1 = t.DefineField("dynamicField1", coreAssembly.GetType("System.Object"), FieldAttributes.Public); + var field1Symbol = c.GetOrCreateFieldSymbol(field1); + field1Symbol.Should().BeOfType(); + field1Symbol.Should().BeSameAs(c.GetOrCreateFieldSymbol(field1)); + + var field2 = t.DefineField("dynamicField2", coreAssembly.GetType("System.Object"), FieldAttributes.Public); + var field2Symbol = c.GetOrCreateFieldSymbol(field2); + field2Symbol.Should().BeOfType(); + field2Symbol.Should().BeSameAs(c.GetOrCreateFieldSymbol(field2)); + } + + [TestMethod] + public void CanResolvePropertyBuilder() + { + var c = new IkvmReflectionSymbolContext(); + var a = universe.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Save); + var m = a.DefineDynamicModule("DynamicModule", "DynamicModule.dll"); + var t = m.DefineType("DynamicType"); + + var property = t.DefineProperty("DynamicProperty", PropertyAttributes.None, coreAssembly.GetType("System.Object"), []); + var propertySymbol = c.GetOrCreatePropertySymbol(property); + propertySymbol.Should().BeOfType(); + propertySymbol.Should().BeSameAs(c.GetOrCreatePropertySymbol(property)); + } + + [TestMethod] + public void CanResolveMultiplePropertyBuilders() + { + var c = new IkvmReflectionSymbolContext(); + var a = universe.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Save); + var m = a.DefineDynamicModule("DynamicModule", "DynamicModule.dll"); + var t = m.DefineType("DynamicType"); + + var property1 = t.DefineProperty("DynamicProperty1", PropertyAttributes.None, coreAssembly.GetType("System.Object"), []); + var property1Symbol = c.GetOrCreatePropertySymbol(property1); + property1Symbol.Should().BeOfType(); + property1Symbol.Should().BeSameAs(c.GetOrCreatePropertySymbol(property1)); + + var property2 = t.DefineProperty("DynamicProperty2", PropertyAttributes.None, coreAssembly.GetType("System.Object"), []); + var property2Symbol = c.GetOrCreatePropertySymbol(property2); + property2Symbol.Should().BeOfType(); + property2Symbol.Should().BeSameAs(c.GetOrCreatePropertySymbol(property2)); + } + + [TestMethod] + public void CanResolveEventBuilder() + { + var c = new IkvmReflectionSymbolContext(); + var a = universe.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Save); + var m = a.DefineDynamicModule("DynamicModule", "DynamicModule.dll"); + var t = m.DefineType("DynamicType"); + + var event1 = t.DefineEvent("DynamicEvent", EventAttributes.None, coreAssembly.GetType("System.EventHandler")); + var event1Symbol = c.GetOrCreateEventSymbol(event1); + event1Symbol.Should().BeOfType(); + event1Symbol.Should().BeSameAs(c.GetOrCreateEventSymbol(event1)); + } + + [TestMethod] + public void CanResolveMultipleEventBuilders() + { + var c = new IkvmReflectionSymbolContext(); + var a = universe.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Save); + var m = a.DefineDynamicModule("DynamicModule", "DynamicModule.dll"); + var t = m.DefineType("DynamicType"); + + var event1 = t.DefineEvent("DynamicEvent", EventAttributes.None, coreAssembly.GetType("System.EventHandler")); + var event1Symbol = c.GetOrCreateEventSymbol(event1); + event1Symbol.Should().BeOfType(); + event1Symbol.Should().BeSameAs(c.GetOrCreateEventSymbol(event1)); + + var event2 = t.DefineEvent("DynamicEvent", EventAttributes.None, coreAssembly.GetType("System.EventHandler")); + var event2Symbol = c.GetOrCreateEventSymbol(event2); + event2Symbol.Should().BeOfType(); + event2Symbol.Should().BeSameAs(c.GetOrCreateEventSymbol(event2)); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionModuleSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionModuleSymbolBuilder.cs new file mode 100644 index 000000000..564c9e551 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionModuleSymbolBuilder.cs @@ -0,0 +1,17 @@ +using IKVM.CoreLib.Symbols.Emit; +using IKVM.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + interface IIkvmReflectionModuleSymbolBuilder : IIkvmReflectionSymbolBuilder, IModuleSymbolBuilder, IIkvmReflectionModuleSymbol + { + + /// + /// Gets the underlying . + /// + ModuleBuilder UnderlyingModuleBuilder { get; } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionParameterSymbolBuilder.cs new file mode 100644 index 000000000..8d74fa945 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionParameterSymbolBuilder.cs @@ -0,0 +1,22 @@ +using IKVM.CoreLib.Symbols.Emit; +using IKVM.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + interface IIkvmReflectionParameterSymbolBuilder : IIkvmReflectionSymbolBuilder, IParameterSymbolBuilder, IIkvmReflectionParameterSymbol + { + + /// + /// Gets the underlying . + /// + ParameterBuilder UnderlyingParameterBuilder { get; } + + /// + /// Invoked when the owning method of this parameter is completed. + /// + void OnComplete(); + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionPropertySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionPropertySymbolBuilder.cs new file mode 100644 index 000000000..a52039bdd --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionPropertySymbolBuilder.cs @@ -0,0 +1,14 @@ +using IKVM.CoreLib.Symbols.Emit; +using IKVM.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + interface IIkvmReflectionPropertySymbolBuilder : IIkvmReflectionSymbolBuilder, IIkvmReflectionMemberSymbolBuilder, IPropertySymbolBuilder, IIkvmReflectionPropertySymbol + { + + PropertyBuilder UnderlyingPropertyBuilder { get; } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionSymbolBuilder.cs new file mode 100644 index 000000000..ce5e76e98 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionSymbolBuilder.cs @@ -0,0 +1,19 @@ +using IKVM.CoreLib.Symbols.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + interface IIkvmReflectionSymbolBuilder : ISymbolBuilder + { + + } + + interface IIkvmReflectionSymbolBuilder : IIkvmReflectionSymbolBuilder, ISymbolBuilder + where TSymbol : IIkvmReflectionSymbol + { + + + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionTypeSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionTypeSymbolBuilder.cs new file mode 100644 index 000000000..c16eeb22c --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionTypeSymbolBuilder.cs @@ -0,0 +1,17 @@ +using IKVM.CoreLib.Symbols.Emit; +using IKVM.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + interface IIkvmReflectionTypeSymbolBuilder : IIkvmReflectionSymbolBuilder, IIkvmReflectionMemberSymbolBuilder, ITypeSymbolBuilder, IIkvmReflectionTypeSymbol + { + + /// + /// Gets the underlying . + /// + TypeBuilder UnderlyingTypeBuilder { get; } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionAssemblySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionAssemblySymbolBuilder.cs new file mode 100644 index 000000000..21a7d7b02 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionAssemblySymbolBuilder.cs @@ -0,0 +1,202 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using IKVM.CoreLib.Symbols.Emit; +using IKVM.Reflection; +using IKVM.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + class IkvmReflectionAssemblySymbolBuilder : IkvmReflectionSymbolBuilder, IIkvmReflectionAssemblySymbolBuilder + { + + readonly AssemblyBuilder _builder; + IkvmReflectionAssemblyMetadata _metadata; + + /// + /// Initializes a new instance. + /// + /// + /// + public IkvmReflectionAssemblySymbolBuilder(IkvmReflectionSymbolContext context, AssemblyBuilder builder) : + base(context) + { + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + _metadata = new IkvmReflectionAssemblyMetadata(this); + } + + /// + public Assembly UnderlyingAssembly => UnderlyingAssemblyBuilder; + + /// + public AssemblyBuilder UnderlyingAssemblyBuilder => _builder; + + #region IAssemblySymbolBuilder + + /// + public IModuleSymbolBuilder DefineModule(string name) + { + return GetOrCreateModuleSymbol(UnderlyingAssemblyBuilder.DefineDynamicModule(name, name + ".dll")); + } + + /// + public IModuleSymbolBuilder DefineModule(string name, string fileName) + { + return GetOrCreateModuleSymbol(UnderlyingAssemblyBuilder.DefineDynamicModule(name, fileName)); + } + + /// + public IModuleSymbolBuilder DefineModule(string name, string fileName, bool emitSymbolInfo) + { + return GetOrCreateModuleSymbol(UnderlyingAssemblyBuilder.DefineDynamicModule(name, fileName, emitSymbolInfo)); + } + + /// + public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) + { + _builder.SetCustomAttribute(con.Unpack(), binaryAttribute); + } + + /// + public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) + { + _builder.SetCustomAttribute(((IkvmReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); + } + + #endregion + + #region IAssemblySymbol + + /// + public IEnumerable DefinedTypes => ResolveTypeSymbols(UnderlyingAssembly.DefinedTypes); + + /// + public IMethodSymbol? EntryPoint => ResolveMethodSymbol(UnderlyingAssembly.EntryPoint); + + /// + public IEnumerable ExportedTypes => ResolveTypeSymbols(UnderlyingAssembly.ExportedTypes); + + /// + public string? FullName => UnderlyingAssembly.FullName; + + /// + public string ImageRuntimeVersion => UnderlyingAssembly.ImageRuntimeVersion; + + /// + public IModuleSymbol ManifestModule => ResolveModuleSymbol(UnderlyingAssembly.ManifestModule); + + /// + public IEnumerable Modules => ResolveModuleSymbols(UnderlyingAssembly.Modules); + + /// + public override bool IsComplete => _builder == null; + + /// + public ITypeSymbol[] GetExportedTypes() + { + return ResolveTypeSymbols(UnderlyingAssembly.GetExportedTypes()); + } + + /// + public IModuleSymbol? GetModule(string name) + { + return ResolveModuleSymbol(UnderlyingAssembly.GetModule(name)); + } + + /// + public IModuleSymbol[] GetModules() + { + return ResolveModuleSymbols(UnderlyingAssembly.GetModules()); + } + + /// + public IModuleSymbol[] GetModules(bool getResourceModules) + { + return ResolveModuleSymbols(UnderlyingAssembly.GetModules(getResourceModules)); + } + + /// + public System.Reflection.AssemblyName GetName() + { + return UnderlyingAssembly.GetName().ToAssemblyName(); + } + + /// + public System.Reflection.AssemblyName GetName(bool copiedName) + { + return UnderlyingAssembly.GetName(copiedName).ToAssemblyName(); + } + + /// + public System.Reflection.AssemblyName[] GetReferencedAssemblies() + { + return UnderlyingAssembly.GetReferencedAssemblies().ToAssemblyNames(); + } + + /// + public ITypeSymbol? GetType(string name, bool throwOnError) + { + return ResolveTypeSymbol(UnderlyingAssembly.GetType(name, throwOnError)); + } + + /// + public ITypeSymbol? GetType(string name, bool throwOnError, bool ignoreCase) + { + return ResolveTypeSymbol(UnderlyingAssembly.GetType(name, throwOnError, ignoreCase)); + } + + /// + public ITypeSymbol? GetType(string name) + { + return ResolveTypeSymbol(UnderlyingAssembly.GetType(name)); + } + + /// + public ITypeSymbol[] GetTypes() + { + return ResolveTypeSymbols(UnderlyingAssembly.GetTypes()); + } + + /// + public CustomAttribute[] GetCustomAttributes(bool inherit = false) + { + return ResolveCustomAttributes(UnderlyingAssembly.GetCustomAttributesData()); + } + + /// + public CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) + { + return ResolveCustomAttributes(UnderlyingAssembly.__GetCustomAttributes(attributeType.Unpack(), inherit)); + } + + /// + public CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) + { + return ResolveCustomAttribute(UnderlyingAssembly.__GetCustomAttributes(attributeType.Unpack(), inherit).FirstOrDefault()); + } + + /// + public bool IsDefined(ITypeSymbol attributeType, bool inherit = false) + { + return UnderlyingAssembly.IsDefined(attributeType.Unpack(), inherit); + } + + #endregion + + /// + public IIkvmReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) + { + return _metadata.GetOrCreateModuleSymbol(module); + } + + /// + public IIkvmReflectionModuleSymbolBuilder GetOrCreateModuleSymbol(ModuleBuilder module) + { + return (IIkvmReflectionModuleSymbolBuilder)_metadata.GetOrCreateModuleSymbol(module); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionConstructorSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionConstructorSymbolBuilder.cs new file mode 100644 index 000000000..962750a1a --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionConstructorSymbolBuilder.cs @@ -0,0 +1,97 @@ +using System; + +using IKVM.CoreLib.Symbols.Emit; +using IKVM.Reflection; +using IKVM.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + class IkvmReflectionConstructorSymbolBuilder : IkvmReflectionMethodBaseSymbolBuilder, IIkvmReflectionConstructorSymbolBuilder + { + + ConstructorBuilder? _builder; + ConstructorInfo _ctor; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + /// + public IkvmReflectionConstructorSymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol resolvingModule, IIkvmReflectionTypeSymbol resolvingType, ConstructorBuilder builder) : + base(context, resolvingModule, resolvingType) + { + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + _ctor = _builder; + } + + /// + public ConstructorInfo UnderlyingConstructor => _ctor; + + /// + public override MethodBase UnderlyingMethodBase => UnderlyingConstructor; + + /// + public ConstructorBuilder UnderlyingConstructorBuilder => _builder ?? throw new InvalidOperationException(); + + #region IConstructorSymbolBuilder + + /// + public void SetImplementationFlags(System.Reflection.MethodImplAttributes attributes) + { + UnderlyingConstructorBuilder.SetImplementationFlags((MethodImplAttributes)attributes); + } + + /// + public IParameterSymbolBuilder DefineParameter(int iSequence, System.Reflection.ParameterAttributes attributes, string? strParamName) + { + return ResolveParameterSymbol(UnderlyingConstructorBuilder.DefineParameter(iSequence, (ParameterAttributes)attributes, strParamName)); + } + + /// + public IILGenerator GetILGenerator() + { + throw new NotImplementedException(); + } + + /// + public IILGenerator GetILGenerator(int streamSize) + { + throw new NotImplementedException(); + } + + /// + public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) + { + UnderlyingConstructorBuilder.SetCustomAttribute(((IkvmReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); + } + + /// + public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) + { + UnderlyingConstructorBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); + } + + #endregion + + #region IConstructorSymbol + + /// + public override bool IsComplete => _builder == null; + + #endregion + + /// + public override void OnComplete() + { + _ctor = (ConstructorInfo?)ResolvingModule.UnderlyingModule.ResolveMethod(MetadataToken) ?? throw new InvalidOperationException(); + _builder = null; + base.OnComplete(); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionCustomAttributeBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionCustomAttributeBuilder.cs new file mode 100644 index 000000000..3e9abec0f --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionCustomAttributeBuilder.cs @@ -0,0 +1,29 @@ +using System; + +using IKVM.CoreLib.Symbols.Emit; +using IKVM.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + class IkvmReflectionCustomAttributeBuilder : ICustomAttributeBuilder + { + + readonly CustomAttributeBuilder _builder; + + /// + /// Initializes a new instance. + /// + public IkvmReflectionCustomAttributeBuilder(CustomAttributeBuilder builder) + { + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + } + + /// + /// Gets the underlying reflection . + /// + internal CustomAttributeBuilder UnderlyingBuilder => _builder; + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionEventSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionEventSymbolBuilder.cs new file mode 100644 index 000000000..385d80655 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionEventSymbolBuilder.cs @@ -0,0 +1,163 @@ +using System; + +using IKVM.CoreLib.Symbols.Emit; +using IKVM.Reflection; +using IKVM.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + class IkvmReflectionEventSymbolBuilder : IkvmReflectionMemberSymbolBuilder, IIkvmReflectionEventSymbolBuilder + { + + EventBuilder? _builder; + EventInfo _event; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + /// + public IkvmReflectionEventSymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol resolvingModule, IIkvmReflectionTypeSymbol resolvingType, EventBuilder builder) : + base(context, resolvingModule, resolvingType) + { + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + _event = _builder; + } + + /// + public EventInfo UnderlyingEvent => _event; + + /// + public EventBuilder UnderlyingEventBuilder => _builder ?? throw new NotImplementedException(); + + /// + public override MemberInfo UnderlyingMember => UnderlyingEvent; + + #region IEventSymbolBuilder + + /// + public void SetAddOnMethod(IMethodSymbolBuilder mdBuilder) + { + UnderlyingEventBuilder.SetAddOnMethod(((IIkvmReflectionMethodSymbolBuilder)mdBuilder).UnderlyingMethodBuilder); + } + + /// + public void SetRemoveOnMethod(IMethodSymbolBuilder mdBuilder) + { + UnderlyingEventBuilder.SetRemoveOnMethod(((IIkvmReflectionMethodSymbolBuilder)mdBuilder).UnderlyingMethodBuilder); + } + + /// + public void SetRaiseMethod(IMethodSymbolBuilder mdBuilder) + { + UnderlyingEventBuilder.SetRaiseMethod(((IIkvmReflectionMethodSymbolBuilder)mdBuilder).UnderlyingMethodBuilder); + } + + /// + public void AddOtherMethod(IMethodSymbolBuilder mdBuilder) + { + UnderlyingEventBuilder.AddOtherMethod(((IIkvmReflectionMethodSymbolBuilder)mdBuilder).UnderlyingMethodBuilder); + } + + /// + public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) + { + UnderlyingEventBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); + } + + /// + public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) + { + UnderlyingEventBuilder.SetCustomAttribute(((IkvmReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); + } + + #endregion + + #region IEventSymbol + + /// + public System.Reflection.EventAttributes Attributes => (System.Reflection.EventAttributes)UnderlyingEvent.Attributes; + + /// + public ITypeSymbol? EventHandlerType => ResolveTypeSymbol(UnderlyingEvent.EventHandlerType); + + /// + public bool IsSpecialName => UnderlyingEvent.IsSpecialName; + + /// + public IMethodSymbol? AddMethod => ResolveMethodSymbol(UnderlyingEvent.AddMethod); + + /// + public IMethodSymbol? RemoveMethod => ResolveMethodSymbol(UnderlyingEvent.RemoveMethod); + + /// + public IMethodSymbol? RaiseMethod => ResolveMethodSymbol(UnderlyingEvent.RaiseMethod); + + /// + public override bool IsComplete => _builder == null; + + /// + public IMethodSymbol? GetAddMethod() + { + return ResolveMethodSymbol(UnderlyingEvent.GetAddMethod()); + } + + /// + public IMethodSymbol? GetAddMethod(bool nonPublic) + { + return ResolveMethodSymbol(UnderlyingEvent.GetAddMethod(nonPublic)); + } + + /// + public IMethodSymbol? GetRemoveMethod() + { + return ResolveMethodSymbol(UnderlyingEvent.GetRemoveMethod()); + } + + /// + public IMethodSymbol? GetRemoveMethod(bool nonPublic) + { + return ResolveMethodSymbol(UnderlyingEvent.GetRemoveMethod(nonPublic)); + } + + /// + public IMethodSymbol? GetRaiseMethod() + { + return ResolveMethodSymbol(UnderlyingEvent.GetRaiseMethod()); + } + + /// + public IMethodSymbol? GetRaiseMethod(bool nonPublic) + { + return ResolveMethodSymbol(UnderlyingEvent.GetRaiseMethod(nonPublic)); + } + + /// + public IMethodSymbol[] GetOtherMethods() + { + return ResolveMethodSymbols(UnderlyingEvent.GetOtherMethods()); + } + + /// + public IMethodSymbol[] GetOtherMethods(bool nonPublic) + { + return ResolveMethodSymbols(UnderlyingEvent.GetOtherMethods(nonPublic)); + } + + #endregion + + /// + public override void OnComplete() + { + _event = (EventInfo?)ResolvingModule.UnderlyingModule.ResolveMember(MetadataToken) ?? throw new InvalidOperationException(); + _builder = null; + base.OnComplete(); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionFieldSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionFieldSymbolBuilder.cs new file mode 100644 index 000000000..b485e6561 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionFieldSymbolBuilder.cs @@ -0,0 +1,145 @@ +using System; + +using IKVM.CoreLib.Symbols.Emit; +using IKVM.Reflection; +using IKVM.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + class IkvmReflectionFieldSymbolBuilder : IkvmReflectionMemberSymbolBuilder, IIkvmReflectionFieldSymbolBuilder + { + + FieldBuilder? _builder; + FieldInfo _field; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + /// + public IkvmReflectionFieldSymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol resolvingModule, IIkvmReflectionTypeSymbol? resolvingType, FieldBuilder builder) : + base(context, resolvingModule, resolvingType) + { + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + _field = _builder; + } + + /// + public FieldInfo UnderlyingField => _field; + + /// + public override MemberInfo UnderlyingMember => UnderlyingField; + + /// + public FieldBuilder UnderlyingFieldBuilder => _builder ?? throw new InvalidOperationException(); + + #region IFieldSymbolBuilder + + /// + public void SetConstant(object? defaultValue) + { + UnderlyingFieldBuilder.SetConstant(defaultValue); + } + + /// + public void SetOffset(int iOffset) + { + UnderlyingFieldBuilder.SetOffset(iOffset); + } + + /// + public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) + { + UnderlyingFieldBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); + } + + /// + public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) + { + UnderlyingFieldBuilder.SetCustomAttribute(((IkvmReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); + } + + #endregion + + #region IFieldSymbol + + /// + public System.Reflection.FieldAttributes Attributes => (System.Reflection.FieldAttributes)UnderlyingField.Attributes; + + /// + public ITypeSymbol FieldType => ResolveTypeSymbol(UnderlyingField.FieldType); + + /// + public bool IsSpecialName => UnderlyingField.IsSpecialName; + + /// + public bool IsAssembly => UnderlyingField.IsAssembly; + + /// + public bool IsFamily => UnderlyingField.IsFamily; + + /// + public bool IsFamilyAndAssembly => UnderlyingField.IsFamilyAndAssembly; + + /// + public bool IsFamilyOrAssembly => UnderlyingField.IsFamilyOrAssembly; + + /// + public bool IsInitOnly => UnderlyingField.IsInitOnly; + + /// + public bool IsLiteral => UnderlyingField.IsLiteral; + + /// + public bool IsNotSerialized => UnderlyingField.IsNotSerialized; + + /// + public bool IsPinvokeImpl => UnderlyingField.IsPinvokeImpl; + + /// + public bool IsPrivate => UnderlyingField.IsPrivate; + + /// + public bool IsPublic => UnderlyingField.IsPublic; + + /// + public bool IsStatic => UnderlyingField.IsStatic; + + /// + public override bool IsComplete => _builder == null; + + /// + public ITypeSymbol[] GetOptionalCustomModifiers() + { + return ResolveTypeSymbols(UnderlyingField.GetOptionalCustomModifiers()); + } + + /// + public ITypeSymbol[] GetRequiredCustomModifiers() + { + return ResolveTypeSymbols(UnderlyingField.GetRequiredCustomModifiers()); + } + + /// + public object? GetRawConstantValue() + { + return UnderlyingField.GetRawConstantValue(); + } + + #endregion + + /// + public override void OnComplete() + { + _field = ResolvingModule.UnderlyingModule.ResolveField(MetadataToken) ?? throw new InvalidOperationException(); + _builder = null; + base.OnComplete(); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionGenericTypeParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionGenericTypeParameterSymbolBuilder.cs new file mode 100644 index 000000000..011eb9985 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionGenericTypeParameterSymbolBuilder.cs @@ -0,0 +1,584 @@ +using System; + +using IKVM.Reflection; +using IKVM.Reflection.Emit; + +using Type = IKVM.Reflection.Type; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + class IkvmReflectionGenericTypeParameterSymbolBuilder : IkvmReflectionMemberSymbolBuilder, IIkvmReflectionGenericTypeParameterSymbolBuilder + { + + readonly IIkvmReflectionMethodSymbol? _resolvingMethod; + + GenericTypeParameterBuilder? _builder; + Type _type; + IkvmReflectionTypeImpl _impl; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + /// + /// + public IkvmReflectionGenericTypeParameterSymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol resolvingModule, IIkvmReflectionTypeSymbol? resolvingType, IIkvmReflectionMethodSymbol? resolvingMethod, GenericTypeParameterBuilder builder) : + base(context, resolvingModule, resolvingType) + { + _resolvingMethod = resolvingMethod; + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + _type = _builder; + _impl = new IkvmReflectionTypeImpl(this); + } + + /// + public Type UnderlyingType => _type; + + /// + public override MemberInfo UnderlyingMember => UnderlyingType; + + /// + public GenericTypeParameterBuilder UnderlyingGenericTypeParameterBuilder => _builder ?? throw new InvalidOperationException(); + + #region ITypeSymbolBuilder + + /// + public void SetBaseTypeConstraint(ITypeSymbol? baseTypeConstraint) + { + UnderlyingGenericTypeParameterBuilder.SetBaseTypeConstraint(baseTypeConstraint?.Unpack()); + } + + /// + public void SetGenericParameterAttributes(System.Reflection.GenericParameterAttributes genericParameterAttributes) + { + UnderlyingGenericTypeParameterBuilder.SetGenericParameterAttributes((GenericParameterAttributes)genericParameterAttributes); + } + + /// + public void SetInterfaceConstraints(params ITypeSymbol[]? interfaceConstraints) + { + UnderlyingGenericTypeParameterBuilder.SetInterfaceConstraints(interfaceConstraints?.Unpack()); + } + + #endregion + + #region ITypeSymbol + + /// + public System.Reflection.TypeAttributes Attributes => (System.Reflection.TypeAttributes)_impl.Attributes; + + /// + public IAssemblySymbol Assembly => _impl.Assembly; + + /// + public IMethodBaseSymbol? DeclaringMethod => _impl.DeclaringMethod; + + /// + public string? AssemblyQualifiedName => _impl.AssemblyQualifiedName; + + /// + public string? FullName => _impl.FullName; + + /// + public string? Namespace => _impl.Namespace; + + /// + public TypeCode TypeCode => _impl.TypeCode; + + /// + public ITypeSymbol? BaseType => _impl.BaseType; + + /// + public bool ContainsGenericParameters => _impl.ContainsGenericParameters; + + /// + public System.Reflection.GenericParameterAttributes GenericParameterAttributes => (System.Reflection.GenericParameterAttributes)_impl.GenericParameterAttributes; + + /// + public int GenericParameterPosition => _impl.GenericParameterPosition; + + /// + public ITypeSymbol[] GenericTypeArguments => _impl.GenericTypeArguments; + + /// + public bool IsConstructedGenericType => _impl.IsConstructedGenericType; + + /// + public bool IsGenericType => _impl.IsGenericType; + + /// + public bool IsGenericTypeDefinition => _impl.IsGenericTypeDefinition; + + /// + public bool IsGenericParameter => _impl.IsGenericParameter; + + /// + public bool IsAutoLayout => _impl.IsAutoLayout; + + /// + public bool IsExplicitLayout => _impl.IsExplicitLayout; + + /// + public bool IsLayoutSequential => _impl.IsLayoutSequential; + + /// + public bool HasElementType => _impl.HasElementType; + + /// + public bool IsClass => _impl.IsClass; + + /// + public bool IsValueType => _impl.IsValueType; + + /// + public bool IsInterface => _impl.IsInterface; + + /// + public bool IsPrimitive => _impl.IsPrimitive; + + /// + public bool IsSZArray => _impl.IsSZArray; + + /// + public bool IsArray => _impl.IsArray; + + /// + public bool IsEnum => _impl.IsEnum; + + /// + public bool IsPointer => _impl.IsPointer; + + /// + public bool IsFunctionPointer => _impl.IsFunctionPointer; + + /// + public bool IsUnmanagedFunctionPointer => _impl.IsUnmanagedFunctionPointer; + + /// + public bool IsByRef => _impl.IsByRef; + + /// + public bool IsAbstract => _impl.IsAbstract; + + /// + public bool IsSealed => _impl.IsSealed; + + /// + public bool IsVisible => _impl.IsVisible; + + /// + public bool IsPublic => _impl.IsPublic; + + /// + public bool IsNotPublic => _impl.IsNotPublic; + + /// + public bool IsNested => _impl.IsNested; + + /// + public bool IsNestedAssembly => _impl.IsNestedAssembly; + + /// + public bool IsNestedFamANDAssem => _impl.IsNestedFamANDAssem; + + /// + public bool IsNestedFamily => _impl.IsNestedFamily; + + /// + public bool IsNestedFamORAssem => _impl.IsNestedFamORAssem; + + /// + public bool IsNestedPrivate => _impl.IsNestedPrivate; + + /// + public bool IsNestedPublic => _impl.IsNestedPublic; + + /// + public bool IsSerializable => _impl.IsSerializable; + + /// + public bool IsSignatureType => _impl.IsSignatureType; + + /// + public bool IsSpecialName => _impl.IsSpecialName; + + /// + public IConstructorSymbol? TypeInitializer => _impl.TypeInitializer; + + /// + public override bool IsComplete => _builder == null; + + /// + public int GetArrayRank() + { + return _impl.GetArrayRank(); + } + + /// + public IMemberSymbol[] GetDefaultMembers() + { + return _impl.GetDefaultMembers(); + } + + /// + public ITypeSymbol? GetElementType() + { + return _impl.GetElementType(); + } + + /// + public string? GetEnumName(object value) + { + return _impl.GetEnumName(value); + } + + /// + public string[] GetEnumNames() + { + return _impl.GetEnumNames(); + } + + /// + public ITypeSymbol GetEnumUnderlyingType() + { + return _impl.GetEnumUnderlyingType(); + } + + /// + public ITypeSymbol[] GetGenericArguments() + { + return _impl.GetGenericArguments(); + } + + /// + public ITypeSymbol[] GetGenericParameterConstraints() + { + return _impl.GetGenericParameterConstraints(); + } + + /// + public ITypeSymbol GetGenericTypeDefinition() + { + return _impl.GetGenericTypeDefinition(); + } + + /// + public ITypeSymbol? GetInterface(string name) + { + return _impl.GetInterface(name); + } + + /// + public ITypeSymbol? GetInterface(string name, bool ignoreCase) + { + return _impl.GetInterface(name, ignoreCase); + } + + /// + public ITypeSymbol[] GetInterfaces(bool inherit = true) + { + return _impl.GetInterfaces(inherit); + } + + /// + public InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) + { + return _impl.GetInterfaceMap(interfaceType); + } + + /// + public IMemberSymbol[] GetMember(string name) + { + return _impl.GetMember(name); + } + + /// + public IMemberSymbol[] GetMember(string name, System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetMember(name, bindingAttr); + } + + /// + public IMemberSymbol[] GetMember(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetMember(name, type, bindingAttr); + } + + /// + public IMemberSymbol[] GetMembers() + { + return _impl.GetMembers(); + } + + /// + public IMemberSymbol[] GetMembers(System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetMembers(bindingAttr); + } + + public IConstructorSymbol? GetConstructor(ITypeSymbol[] types) + { + return _impl.GetConstructor(types); + } + + /// + public IConstructorSymbol? GetConstructor(System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) + { + return _impl.GetConstructor(bindingAttr, types); + } + + /// + public IConstructorSymbol[] GetConstructors() + { + return _impl.GetConstructors(); + } + + /// + public IConstructorSymbol[] GetConstructors(System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetConstructors(bindingAttr); + } + + /// + public IFieldSymbol? GetField(string name) + { + return _impl.GetField(name); + } + + /// + public IFieldSymbol? GetField(string name, System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetField(name, bindingAttr); + } + + /// + public IFieldSymbol[] GetFields() + { + return _impl.GetFields(); + } + + /// + public IFieldSymbol[] GetFields(System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetFields(bindingAttr); + } + + /// + public IMethodSymbol? GetMethod(string name) + { + return _impl.GetMethod(name); + } + + /// + public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) + { + return _impl.GetMethod(name, types); + } + + /// + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetMethod(name, bindingAttr); + } + + /// + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) + { + return _impl.GetMethod(name, bindingAttr, types); + } + + /// + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + { + return _impl.GetMethod(name, bindingAttr, callConvention, types, modifiers); + } + + /// + public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + { + return _impl.GetMethod(name, genericParameterCount, bindingAttr, callConvention, types, modifiers); + } + + /// + public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + { + return _impl.GetMethod(name, genericParameterCount, bindingAttr, types, modifiers); + } + + /// + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + { + return _impl.GetMethod(name, bindingAttr, types, modifiers); + } + + /// + public IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + { + return _impl.GetMethod(name, genericParameterCount, types, modifiers); + } + + /// + public IMethodSymbol[] GetMethods() + { + return _impl.GetMethods(); + } + + /// + public IMethodSymbol[] GetMethods(System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetMethods(bindingAttr); + } + + /// + public IPropertySymbol? GetProperty(string name) + { + return _impl.GetProperty(name); + } + + /// + public IPropertySymbol? GetProperty(string name, System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetProperty(name, bindingAttr); + } + + /// + public IPropertySymbol? GetProperty(string name, ITypeSymbol[] types) + { + return _impl.GetProperty(name, types); + } + + /// + public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types) + { + return _impl.GetProperty(name, returnType, types); + } + + /// + public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) + { + return _impl.GetProperty(name, returnType); + } + + /// + public IPropertySymbol[] GetProperties() + { + return _impl.GetProperties(); + } + + /// + public IPropertySymbol[] GetProperties(System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetProperties(bindingAttr); + } + + /// + public IEventSymbol? GetEvent(string name) + { + return _impl.GetEvent(name); + } + + /// + public IEventSymbol? GetEvent(string name, System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetEvent(name, bindingAttr); + } + + /// + public IEventSymbol[] GetEvents() + { + return _impl.GetEvents(); + } + + /// + public IEventSymbol[] GetEvents(System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetEvents(bindingAttr); + } + + /// + public ITypeSymbol? GetNestedType(string name) + { + return _impl.GetNestedType(name); + } + + /// + public ITypeSymbol? GetNestedType(string name, System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetNestedType(name, bindingAttr); + } + + /// + public ITypeSymbol[] GetNestedTypes() + { + return _impl.GetNestedTypes(); + } + + /// + public ITypeSymbol[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetNestedTypes(); + } + + /// + public bool IsAssignableFrom(ITypeSymbol? c) + { + return _impl.IsAssignableFrom(c); + } + + /// + public bool IsSubclassOf(ITypeSymbol c) + { + return _impl.IsSubclassOf(c); + } + + /// + public bool IsEnumDefined(object value) + { + return _impl.IsEnumDefined(value); + } + + /// + public ITypeSymbol MakeArrayType() + { + return _impl.MakeArrayType(); + } + + /// + public ITypeSymbol MakeArrayType(int rank) + { + return _impl.MakeArrayType(rank); + } + + /// + public ITypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments) + { + return _impl.MakeGenericType(typeArguments); + } + + /// + public ITypeSymbol MakePointerType() + { + return _impl.MakePointerType(); + } + + /// + public ITypeSymbol MakeByRefType() + { + return _impl.MakeByRefType(); + } + + #endregion + + /// + public override void OnComplete() + { + throw new NotImplementedException(); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMemberSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMemberSymbolBuilder.cs new file mode 100644 index 000000000..1b643dfda --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMemberSymbolBuilder.cs @@ -0,0 +1,313 @@ +using System; +using System.Diagnostics.CodeAnalysis; +using System.Linq; + +using IKVM.Reflection; +using IKVM.Reflection.Emit; + +using Type = IKVM.Reflection.Type; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + abstract class IkvmReflectionMemberSymbolBuilder : IkvmReflectionSymbolBuilder, IIkvmReflectionMemberSymbolBuilder + { + + readonly IIkvmReflectionModuleSymbol _resolvingModule; + readonly IIkvmReflectionTypeSymbol? _resolvingType; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + public IkvmReflectionMemberSymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol resolvingModule, IIkvmReflectionTypeSymbol? resolvingType) : + base(context) + { + _resolvingModule = resolvingModule ?? throw new ArgumentNullException(nameof(resolvingModule)); + _resolvingType = resolvingType; + } + + #region IMemberSymbol + + /// + public abstract MemberInfo UnderlyingMember { get; } + + /// + public IIkvmReflectionModuleSymbol ResolvingModule => _resolvingModule; + + /// + public IIkvmReflectionTypeSymbol? ResolvingType => ResolvingType; + + /// + public virtual IModuleSymbol Module => ResolveModuleSymbol(UnderlyingMember.Module)!; + + /// + public virtual ITypeSymbol? DeclaringType => ResolveTypeSymbol(UnderlyingMember.DeclaringType)!; + + /// + public virtual System.Reflection.MemberTypes MemberType => (System.Reflection.MemberTypes)UnderlyingMember.MemberType; + + /// + public virtual int MetadataToken => UnderlyingMember.MetadataToken; + + /// + public virtual string Name => UnderlyingMember.Name; + + /// + public CustomAttribute[] GetCustomAttributes(bool inherit = false) + { + return ResolveCustomAttributes(UnderlyingMember.__GetCustomAttributes(null, inherit)); + } + + /// + public virtual CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) + { + return ResolveCustomAttributes(UnderlyingMember.__GetCustomAttributes(attributeType.Unpack(), inherit)); + } + + /// + public virtual CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) + { + return ResolveCustomAttribute(UnderlyingMember.__GetCustomAttributes(attributeType.Unpack(), inherit).FirstOrDefault()); + } + + /// + public virtual bool IsDefined(ITypeSymbol attributeType, bool inherit = false) + { + return UnderlyingMember.IsDefined(attributeType.Unpack(), inherit); + } + + #endregion + + /// + [return: NotNullIfNotNull(nameof(type))] + public override IIkvmReflectionTypeSymbol? ResolveTypeSymbol(Type? type) + { + if (type is null) + return null; + + if (UnderlyingMember == type) + return (IIkvmReflectionTypeSymbol)this; + + if (_resolvingType != null && type == _resolvingType.UnderlyingType) + return _resolvingType; + + if (type.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateTypeSymbol(type); + + return base.ResolveTypeSymbol(type); + } + + /// + [return: NotNullIfNotNull("type")] + public override IIkvmReflectionTypeSymbolBuilder ResolveTypeSymbol(TypeBuilder type) + { + if (type is null) + throw new ArgumentNullException(nameof(type)); + + if (UnderlyingMember == type) + return (IIkvmReflectionTypeSymbolBuilder)this; + + if (_resolvingType != null && type == _resolvingType.UnderlyingType) + return (IIkvmReflectionTypeSymbolBuilder)_resolvingType; + + if (type.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateTypeSymbol(type); + + return base.ResolveTypeSymbol(type); + } + + /// + [return: NotNullIfNotNull(nameof(ctor))] + public override IIkvmReflectionConstructorSymbol? ResolveConstructorSymbol(ConstructorInfo? ctor) + { + if (ctor is null) + return null; + + if (UnderlyingMember == ctor) + return (IIkvmReflectionConstructorSymbol)this; + + if (ctor.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateConstructorSymbol(ctor); + + return base.ResolveConstructorSymbol(ctor); + } + + /// + [return: NotNullIfNotNull(nameof(ctor))] + public override IIkvmReflectionConstructorSymbolBuilder ResolveConstructorSymbol(ConstructorBuilder ctor) + { + if (ctor is null) + throw new ArgumentNullException(nameof(ctor)); + + if (UnderlyingMember == ctor) + return (IIkvmReflectionConstructorSymbolBuilder)this; + + if (ctor.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateConstructorSymbol(ctor); + + return base.ResolveConstructorSymbol(ctor); + } + + /// + [return: NotNullIfNotNull(nameof(method))] + public override IIkvmReflectionMethodSymbol? ResolveMethodSymbol(MethodInfo? method) + { + if (method is null) + return null; + + if (UnderlyingMember == method) + return (IIkvmReflectionMethodSymbol)this; + + if (method.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateMethodSymbol(method); + + return base.ResolveMethodSymbol(method); + } + + /// + [return: NotNullIfNotNull(nameof(method))] + public override IIkvmReflectionMethodSymbolBuilder ResolveMethodSymbol(MethodBuilder method) + { + if (method is null) + throw new ArgumentNullException(nameof(method)); + + if (UnderlyingMember == method) + return (IIkvmReflectionMethodSymbolBuilder)this; + + if (method.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateMethodSymbol(method); + + return base.ResolveMethodSymbol(method); + } + + /// + [return: NotNullIfNotNull(nameof(field))] + public override IIkvmReflectionFieldSymbol? ResolveFieldSymbol(FieldInfo? field) + { + if (field is null) + return null; + + if (UnderlyingMember == field) + return (IIkvmReflectionFieldSymbol)this; + + if (field.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateFieldSymbol(field); + + return base.ResolveFieldSymbol(field); + } + + /// + [return: NotNullIfNotNull(nameof(field))] + public override IIkvmReflectionFieldSymbolBuilder ResolveFieldSymbol(FieldBuilder field) + { + if (field is null) + throw new ArgumentNullException(nameof(field)); + + if (UnderlyingMember == field) + return (IIkvmReflectionFieldSymbolBuilder)this; + + if (field.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateFieldSymbol(field); + + return base.ResolveFieldSymbol(field); + } + + /// + [return: NotNullIfNotNull(nameof(property))] + public override IIkvmReflectionPropertySymbol? ResolvePropertySymbol(PropertyInfo? property) + { + if (property is null) + return null; + + if (UnderlyingMember == property) + return (IIkvmReflectionPropertySymbol)this; + + if (property.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreatePropertySymbol(property); + + return base.ResolvePropertySymbol(property); + } + + /// + [return: NotNullIfNotNull(nameof(property))] + public override IIkvmReflectionPropertySymbolBuilder ResolvePropertySymbol(PropertyBuilder property) + { + if (property is null) + throw new ArgumentNullException(nameof(property)); + + if (UnderlyingMember == property) + return (IIkvmReflectionPropertySymbolBuilder)this; + + if (property.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreatePropertySymbol(property); + + return base.ResolvePropertySymbol(property); + } + + /// + [return: NotNullIfNotNull(nameof(@event))] + public override IIkvmReflectionEventSymbol? ResolveEventSymbol(EventInfo? @event) + { + if (@event is null) + return null; + + if (UnderlyingMember == @event) + return (IIkvmReflectionEventSymbol)this; + + if (@event.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateEventSymbol(@event); + + return base.ResolveEventSymbol(@event); + } + + /// + [return: NotNullIfNotNull(nameof(@event))] + public override IIkvmReflectionEventSymbolBuilder ResolveEventSymbol(EventBuilder @event) + { + if (@event is null) + throw new ArgumentNullException(nameof(@event)); + + if (@event.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateEventSymbol(@event); + + return base.ResolveEventSymbol(@event); + } + + /// + [return: NotNullIfNotNull(nameof(parameter))] + public override IIkvmReflectionParameterSymbol? ResolveParameterSymbol(ParameterInfo? parameter) + { + if (parameter is null) + throw new ArgumentNullException(nameof(parameter)); + + if (parameter.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateParameterSymbol(parameter); + + return base.ResolveParameterSymbol(parameter); + } + + /// + [return: NotNullIfNotNull(nameof(parameter))] + public override IIkvmReflectionParameterSymbolBuilder ResolveParameterSymbol(ParameterBuilder parameter) + { + if (parameter is null) + throw new ArgumentNullException(nameof(parameter)); + + if (parameter.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateParameterSymbol(parameter); + + return base.ResolveParameterSymbol(parameter); + } + + /// + public virtual void OnComplete() + { + + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodBaseSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodBaseSymbolBuilder.cs new file mode 100644 index 000000000..b6a2326dd --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodBaseSymbolBuilder.cs @@ -0,0 +1,122 @@ +using IKVM.Reflection; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + abstract class IkvmReflectionMethodBaseSymbolBuilder : IkvmReflectionMemberSymbolBuilder, IIkvmReflectionMethodBaseSymbolBuilder + { + + /// + /// Initializes a new instance. + /// + /// + /// + /// + public IkvmReflectionMethodBaseSymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol resolvingModule, IIkvmReflectionTypeSymbol? resolvingType) : + base(context, resolvingModule, resolvingType) + { + + } + + /// + public abstract MethodBase UnderlyingMethodBase { get; } + + /// + public override MemberInfo UnderlyingMember => UnderlyingMethodBase; + + #region IMethodBaseSymbol + + /// + public System.Reflection.MethodAttributes Attributes => (System.Reflection.MethodAttributes)UnderlyingMethodBase.Attributes; + + /// + public System.Reflection.CallingConventions CallingConvention => (System.Reflection.CallingConventions)UnderlyingMethodBase.CallingConvention; + + /// + public bool ContainsGenericParameters => UnderlyingMethodBase.ContainsGenericParameters; + + /// + public bool IsAbstract => UnderlyingMethodBase.IsAbstract; + + /// + public bool IsAssembly => UnderlyingMethodBase.IsAssembly; + + /// + public bool IsConstructor => UnderlyingMethodBase.IsConstructor; + + /// + public bool IsFamily => UnderlyingMethodBase.IsFamily; + + /// + public bool IsFamilyAndAssembly => UnderlyingMethodBase.IsFamilyAndAssembly; + + /// + public bool IsFamilyOrAssembly => UnderlyingMethodBase.IsFamilyOrAssembly; + + /// + public bool IsFinal => UnderlyingMethodBase.IsFinal; + + /// + public bool IsGenericMethod => UnderlyingMethodBase.IsGenericMethod; + + /// + public bool IsGenericMethodDefinition => UnderlyingMethodBase.IsGenericMethodDefinition; + + /// + public bool IsHideBySig => UnderlyingMethodBase.IsHideBySig; + + /// + public bool IsPrivate => UnderlyingMethodBase.IsPrivate; + + /// + public bool IsPublic => UnderlyingMethodBase.IsPublic; + + /// + public bool IsStatic => UnderlyingMethodBase.IsStatic; + + /// + public bool IsVirtual => UnderlyingMethodBase.IsVirtual; + + /// + public bool IsSpecialName => UnderlyingMethodBase.IsSpecialName; + + /// + public System.Reflection.MethodImplAttributes MethodImplementationFlags => (System.Reflection.MethodImplAttributes)UnderlyingMethodBase.MethodImplementationFlags; + + /// + public ITypeSymbol[] GetGenericArguments() + { + return ResolveTypeSymbols(UnderlyingMethodBase.GetGenericArguments()); + } + + /// + public System.Reflection.MethodImplAttributes GetMethodImplementationFlags() + { + return (System.Reflection.MethodImplAttributes)UnderlyingMethodBase.GetMethodImplementationFlags(); + } + + /// + public IParameterSymbol[] GetParameters() + { + return ResolveParameterSymbols(UnderlyingMethodBase.GetParameters()); + } + + #endregion + + /// + public override void OnComplete() + { + foreach (var i in GetGenericArguments()) + if (i is IIkvmReflectionGenericTypeParameterSymbolBuilder b) + b.OnComplete(); + + foreach (var i in GetParameters()) + if (i is IIkvmReflectionParameterSymbolBuilder b) + b.OnComplete(); + + base.OnComplete(); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodSymbolBuilder.cs new file mode 100644 index 000000000..db3c96967 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodSymbolBuilder.cs @@ -0,0 +1,150 @@ +using System; + +using IKVM.CoreLib.Symbols.Emit; +using IKVM.Reflection; +using IKVM.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + class IkvmReflectionMethodSymbolBuilder : IkvmReflectionMethodBaseSymbolBuilder, IIkvmReflectionMethodSymbolBuilder + { + + MethodBuilder? _builder; + MethodInfo _method; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + /// + public IkvmReflectionMethodSymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol resolvingModule, IIkvmReflectionTypeSymbol? resolvingType, MethodBuilder builder) : + base(context, resolvingModule, resolvingType) + { + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + _method = _builder; + } + + /// + public MethodInfo UnderlyingMethod => _method; + + /// + public override MethodBase UnderlyingMethodBase => UnderlyingMethod; + + /// + public MethodBuilder UnderlyingMethodBuilder => _builder ?? throw new InvalidOperationException(); + + #region IMethodSymbolBuilder + + /// + public void SetImplementationFlags(System.Reflection.MethodImplAttributes attributes) + { + UnderlyingMethodBuilder.SetImplementationFlags((MethodImplAttributes)attributes); + } + + /// + public void SetParameters(params ITypeSymbol[] parameterTypes) + { + UnderlyingMethodBuilder.SetParameters(parameterTypes.Unpack()); + } + + /// + public void SetReturnType(ITypeSymbol? returnType) + { + UnderlyingMethodBuilder.SetReturnType(returnType?.Unpack()); + } + + /// + public void SetSignature(ITypeSymbol? returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers) + { + UnderlyingMethodBuilder.SetSignature(returnType?.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack()); + } + + public IGenericTypeParameterSymbolBuilder[] DefineGenericParameters(params string[] names) + { + var l = UnderlyingMethodBuilder.DefineGenericParameters(names); + var a = new IGenericTypeParameterSymbolBuilder[l.Length]; + for (int i = 0; i < l.Length; i++) + a[i] = new IkvmReflectionGenericTypeParameterSymbolBuilder(Context, ResolvingModule, ResolvingType, this, l[i]); + + return a; + } + + /// + public IParameterSymbolBuilder DefineParameter(int position, System.Reflection.ParameterAttributes attributes, string? strParamName) + { + return ResolveParameterSymbol(UnderlyingMethodBuilder.DefineParameter(position, (ParameterAttributes)attributes, strParamName)); + } + + public IILGenerator GetILGenerator() + { + throw new NotImplementedException(); + } + + public IILGenerator GetILGenerator(int size) + { + throw new NotImplementedException(); + } + + /// + public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) + { + UnderlyingMethodBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); + } + + /// + public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) + { + UnderlyingMethodBuilder.SetCustomAttribute(((IkvmReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); + } + + #endregion + + #region IMethodSymbol + + /// + public IParameterSymbol ReturnParameter => ResolveParameterSymbol(UnderlyingMethod.ReturnParameter); + + /// + public ITypeSymbol ReturnType => ResolveTypeSymbol(UnderlyingMethod.ReturnType); + + /// + public ICustomAttributeProvider ReturnTypeCustomAttributes => throw new NotImplementedException(); + + /// + public override bool IsComplete => _builder == null; + + /// + public IMethodSymbol GetBaseDefinition() + { + return ResolveMethodSymbol(UnderlyingMethod.GetBaseDefinition()); + } + + /// + public IMethodSymbol GetGenericMethodDefinition() + { + return ResolveMethodSymbol(UnderlyingMethod.GetGenericMethodDefinition()); + } + + /// + public IMethodSymbol MakeGenericMethod(params ITypeSymbol[] typeArguments) + { + return ResolveMethodSymbol(UnderlyingMethod.MakeGenericMethod(typeArguments.Unpack())); + } + + #endregion + + /// + public override void OnComplete() + { + _method = (MethodInfo?)ResolvingModule.UnderlyingModule.ResolveMethod(MetadataToken) ?? throw new InvalidOperationException(); + _builder = null; + base.OnComplete(); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionModuleSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionModuleSymbolBuilder.cs new file mode 100644 index 000000000..deb3feca4 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionModuleSymbolBuilder.cs @@ -0,0 +1,382 @@ +using System; +using System.Linq; + +using IKVM.CoreLib.Symbols.Emit; +using IKVM.Reflection; +using IKVM.Reflection.Emit; + +using Type = IKVM.Reflection.Type; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + class IkvmReflectionModuleSymbolBuilder : IkvmReflectionSymbolBuilder, IIkvmReflectionModuleSymbolBuilder + { + + readonly IIkvmReflectionAssemblySymbol _resolvingAssembly; + + readonly ModuleBuilder _builder; + IkvmReflectionModuleMetadata _metadata; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + public IkvmReflectionModuleSymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionAssemblySymbol resolvingAssembly, ModuleBuilder builder) : + base(context) + { + _resolvingAssembly = resolvingAssembly ?? throw new ArgumentNullException(nameof(resolvingAssembly)); + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + _metadata = new IkvmReflectionModuleMetadata(this); + } + + /// + public Module UnderlyingModule => UnderlyingModuleBuilder; + + /// + public ModuleBuilder UnderlyingModuleBuilder => _builder; + + /// + public IIkvmReflectionAssemblySymbol ResolvingAssembly => _resolvingAssembly; + + #region IModuleSymbolBuilder + + /// + public ITypeSymbolBuilder DefineType(string name) + { + return ResolveTypeSymbol(UnderlyingModuleBuilder.DefineType(name)); + } + + /// + public ITypeSymbolBuilder DefineType(string name, System.Reflection.TypeAttributes attr, ITypeSymbol? parent, int typesize) + { + return ResolveTypeSymbol(UnderlyingModuleBuilder.DefineType(name, (TypeAttributes)attr, parent?.Unpack(), typesize)); + } + + /// + public ITypeSymbolBuilder DefineType(string name, System.Reflection.TypeAttributes attr, ITypeSymbol? parent) + { + return ResolveTypeSymbol(UnderlyingModuleBuilder.DefineType(name, (TypeAttributes)attr, parent?.Unpack())); + } + + /// + public ITypeSymbolBuilder DefineType(string name, System.Reflection.TypeAttributes attr) + { + return ResolveTypeSymbol(UnderlyingModuleBuilder.DefineType(name, (TypeAttributes)attr)); + } + + /// + public ITypeSymbolBuilder DefineType(string name, System.Reflection.TypeAttributes attr, ITypeSymbol? parent, System.Reflection.Emit.PackingSize packsize) + { + return ResolveTypeSymbol(UnderlyingModuleBuilder.DefineType(name, (TypeAttributes)attr, parent?.Unpack(), (PackingSize)packsize)); + } + + /// + public ITypeSymbolBuilder DefineType(string name, System.Reflection.TypeAttributes attr, ITypeSymbol? parent, System.Reflection.Emit.PackingSize packingSize, int typesize) + { + return ResolveTypeSymbol(UnderlyingModuleBuilder.DefineType(name, (TypeAttributes)attr, parent?.Unpack(), (PackingSize)packingSize, typesize)); + } + + /// + public ITypeSymbolBuilder DefineType(string name, System.Reflection.TypeAttributes attr, ITypeSymbol? parent, ITypeSymbol[]? interfaces) + { + return ResolveTypeSymbol(UnderlyingModuleBuilder.DefineType(name, (TypeAttributes)attr, parent?.Unpack(), interfaces?.Unpack())); + } + + /// + public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) + { + UnderlyingModuleBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); + } + + /// + public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) + { + UnderlyingModuleBuilder.SetCustomAttribute(((IkvmReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); + } + + #endregion + + #region IModuleSymbol + + /// + public IAssemblySymbol Assembly => ResolveAssemblySymbol(UnderlyingModule.Assembly); + + /// + public string FullyQualifiedName => UnderlyingModule.FullyQualifiedName; + + /// + public int MetadataToken => UnderlyingModule.MetadataToken; + + /// + public Guid ModuleVersionId => UnderlyingModule.ModuleVersionId; + + /// + public string Name => UnderlyingModule.Name; + + /// + public string ScopeName => UnderlyingModule.ScopeName; + + /// + public override bool IsComplete => _builder == null; + + /// + public IFieldSymbol? GetField(string name) + { + return ResolveFieldSymbol(UnderlyingModule.GetField(name)); + } + + /// + public IFieldSymbol? GetField(string name, System.Reflection.BindingFlags bindingAttr) + { + return ResolveFieldSymbol(UnderlyingModule.GetField(name, (BindingFlags)bindingAttr)); + } + + /// + public IFieldSymbol[] GetFields(System.Reflection.BindingFlags bindingFlags) + { + return ResolveFieldSymbols(UnderlyingModule.GetFields((BindingFlags)bindingFlags))!; + } + + /// + public IFieldSymbol[] GetFields() + { + return ResolveFieldSymbols(UnderlyingModule.GetFields())!; + } + + /// + public IMethodSymbol? GetMethod(string name) + { + return ResolveMethodSymbol(UnderlyingModule.GetMethod(name)); + } + + /// + public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) + { + return ResolveMethodSymbol(UnderlyingModule.GetMethod(name, types.Unpack())); + } + + /// + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + { + return ResolveMethodSymbol(UnderlyingModule.GetMethod(name, (BindingFlags)bindingAttr, null, (CallingConventions)callConvention, types.Unpack(), modifiers?.Unpack())); + } + + /// + public IMethodSymbol[] GetMethods() + { + return ResolveMethodSymbols(UnderlyingModule.GetMethods())!; + } + + /// + public IMethodSymbol[] GetMethods(System.Reflection.BindingFlags bindingFlags) + { + return ResolveMethodSymbols(UnderlyingModule.GetMethods((BindingFlags)bindingFlags))!; + } + + /// + public ITypeSymbol? GetType(string className) + { + return ResolveTypeSymbol(UnderlyingModule.GetType(className)); + } + + /// + public ITypeSymbol? GetType(string className, bool ignoreCase) + { + return ResolveTypeSymbol(UnderlyingModule.GetType(className, ignoreCase)); + } + + /// + public ITypeSymbol? GetType(string className, bool throwOnError, bool ignoreCase) + { + return ResolveTypeSymbol(UnderlyingModule.GetType(className, throwOnError, ignoreCase)); + } + + /// + public ITypeSymbol[] GetTypes() + { + return ResolveTypeSymbols(UnderlyingModule.GetTypes())!; + } + + /// + public bool IsResource() + { + return UnderlyingModule.IsResource(); + } + + /// + public IFieldSymbol? ResolveField(int metadataToken) + { + return ResolveFieldSymbol(UnderlyingModule.ResolveField(metadataToken)); + } + + /// + public IFieldSymbol? ResolveField(int metadataToken, ITypeSymbol[]? genericTypeArguments, ITypeSymbol[]? genericMethodArguments) + { + return ResolveFieldSymbol(UnderlyingModule.ResolveField(metadataToken, genericTypeArguments?.Unpack(), genericMethodArguments?.Unpack())); + } + + /// + public IMemberSymbol? ResolveMember(int metadataToken) + { + return ResolveMemberSymbol(UnderlyingModule.ResolveMember(metadataToken)); + } + + /// + public IMemberSymbol? ResolveMember(int metadataToken, ITypeSymbol[]? genericTypeArguments, ITypeSymbol[]? genericMethodArguments) + { + return ResolveMemberSymbol(UnderlyingModule.ResolveMember(metadataToken, genericTypeArguments?.Unpack(), genericMethodArguments?.Unpack())); + } + + /// + public IMethodBaseSymbol? ResolveMethod(int metadataToken, ITypeSymbol[]? genericTypeArguments, ITypeSymbol[]? genericMethodArguments) + { + return ResolveMethodBaseSymbol(UnderlyingModule.ResolveMethod(metadataToken, genericTypeArguments?.Unpack(), genericMethodArguments?.Unpack())); + } + + /// + public IMethodBaseSymbol? ResolveMethod(int metadataToken) + { + return ResolveMethodBaseSymbol(UnderlyingModule.ResolveMethod(metadataToken)); + } + + /// + public byte[] ResolveSignature(int metadataToken) + { + return UnderlyingModule.ResolveSignature(metadataToken); + } + + /// + public string ResolveString(int metadataToken) + { + return UnderlyingModule.ResolveString(metadataToken); + } + + /// + public ITypeSymbol ResolveType(int metadataToken) + { + return ResolveTypeSymbol(UnderlyingModule.ResolveType(metadataToken)); + } + + /// + public ITypeSymbol ResolveType(int metadataToken, ITypeSymbol[]? genericTypeArguments, ITypeSymbol[]? genericMethodArguments) + { + return ResolveTypeSymbol(UnderlyingModule.ResolveType(metadataToken, genericTypeArguments?.Unpack(), genericMethodArguments?.Unpack())); + } + + /// + public CustomAttribute[] GetCustomAttributes(bool inherit = false) + { + return ResolveCustomAttributes(UnderlyingModule.GetCustomAttributesData()); + } + + /// + public virtual CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) + { + return ResolveCustomAttributes(UnderlyingModule.__GetCustomAttributes(attributeType.Unpack(), inherit)); + } + + /// + public virtual CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) + { + return ResolveCustomAttribute(UnderlyingModule.__GetCustomAttributes(attributeType.Unpack(), inherit).FirstOrDefault()); + } + + /// + public bool IsDefined(ITypeSymbol attributeType, bool inherit = false) + { + return UnderlyingModule.IsDefined(attributeType.Unpack(), false); + } + + #endregion + + /// + public IIkvmReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) + { + return _metadata.GetOrCreateTypeSymbol(type); + } + + /// + public IIkvmReflectionTypeSymbolBuilder GetOrCreateTypeSymbol(TypeBuilder type) + { + return _metadata.GetOrCreateTypeSymbol(type); + } + + /// + public IIkvmReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) + { + return _metadata.GetOrCreateConstructorSymbol(ctor); + } + + /// + public IIkvmReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor) + { + return _metadata.GetOrCreateConstructorSymbol(ctor); + } + + /// + public IIkvmReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) + { + return _metadata.GetOrCreateMethodSymbol(method); + } + + /// + public IIkvmReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method) + { + return _metadata.GetOrCreateMethodSymbol(method); + } + + /// + public IIkvmReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) + { + return _metadata.GetOrCreateFieldSymbol(field); + } + + /// + public IIkvmReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field) + { + return _metadata.GetOrCreateFieldSymbol(field); + } + + /// + public IIkvmReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) + { + return _metadata.GetOrCreatePropertySymbol(property); + } + + /// + public IIkvmReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property) + { + return _metadata.GetOrCreatePropertySymbol(property); + } + + /// + public IIkvmReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) + { + return _metadata.GetOrCreateEventSymbol(@event); + } + + /// + public IIkvmReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event) + { + return _metadata.GetOrCreateEventSymbol(@event); + } + + /// + public IIkvmReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) + { + return _metadata.GetOrCreateParameterSymbol(parameter); + } + + /// + public IIkvmReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter) + { + return _metadata.GetOrCreateParameterSymbol(parameter); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterBuilderInfo.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterBuilderInfo.cs new file mode 100644 index 000000000..ea7a2a744 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterBuilderInfo.cs @@ -0,0 +1,71 @@ +using System; + +using IKVM.Reflection; +using IKVM.Reflection.Emit; + +using Type = IKVM.Reflection.Type; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + /// + /// Fake implementation that wraps a , which does not extend . + /// + class IkvmReflectionParameterBuilderInfo : ParameterInfo + { + + readonly ParameterBuilder _builder; + readonly Func _getDefaultValue; + + /// + /// Initialies a new instance. + /// + /// + /// + /// + /// + public IkvmReflectionParameterBuilderInfo(ParameterBuilder builder, Func getDefaultValue) + { + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + _getDefaultValue = getDefaultValue ?? throw new ArgumentNullException(nameof(getDefaultValue)); + } + + /// + public override ParameterAttributes Attributes => (ParameterAttributes)_builder.Attributes; + + /// + public override MemberInfo Member => throw new NotImplementedException(); + + /// + public override Type ParameterType => ((MethodBase)Member).GetParameters()[Position].ParameterType; + + /// + public override Module Module => _builder.Module; + + /// + public override string? Name => _builder.Name; + + /// + public override int Position => _builder.Position; + + /// + public override int MetadataToken => throw new NotImplementedException(); + + /// + public override object? RawDefaultValue => _getDefaultValue(); + + /// + public override CustomModifiers __GetCustomModifiers() + { + throw new NotImplementedException(); + } + + /// + public override bool __TryGetFieldMarshal(out FieldMarshal fieldMarshal) + { + throw new NotImplementedException(); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterSymbolBuilder.cs new file mode 100644 index 000000000..fa7506bd8 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterSymbolBuilder.cs @@ -0,0 +1,164 @@ +using System; +using System.Linq; + +using IKVM.CoreLib.Symbols.Emit; +using IKVM.Reflection; +using IKVM.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + class IkvmReflectionParameterSymbolBuilder : IkvmReflectionSymbolBuilder, IIkvmReflectionParameterSymbolBuilder + { + + readonly IIkvmReflectionModuleSymbol _resolvingModule; + readonly IIkvmReflectionMethodBaseSymbol _resolvingMethod; + + ParameterBuilder? _builder; + ParameterInfo _parameter; + + object? _constant; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + public IkvmReflectionParameterSymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol resolvingModule, IIkvmReflectionMethodBaseSymbol resolvingMethod, ParameterBuilder builder) : + base(context) + { + _resolvingModule = resolvingModule ?? throw new ArgumentNullException(nameof(resolvingModule)); + _resolvingMethod = resolvingMethod ?? throw new ArgumentNullException(nameof(resolvingMethod)); + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + _parameter = new IkvmReflectionParameterBuilderInfo(_builder, () => _constant); + } + + /// + public IIkvmReflectionModuleSymbol ResolvingModule => _resolvingMethod.ResolvingModule; + + /// + public IIkvmReflectionMethodBaseSymbol ResolvingMethod => _resolvingMethod; + + /// + public ParameterInfo UnderlyingParameter => _parameter; + + /// + public ParameterBuilder UnderlyingParameterBuilder => _builder ?? throw new InvalidOperationException(); + + #region IParameterSymbolBuilder + + /// + public void SetConstant(object? defaultValue) + { + UnderlyingParameterBuilder.SetConstant(_constant = defaultValue); + } + + /// + public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) + { + UnderlyingParameterBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); + } + + /// + public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) + { + UnderlyingParameterBuilder.SetCustomAttribute(((IkvmReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); + } + + #endregion + + #region IParameterSymbol + + /// + public System.Reflection.ParameterAttributes Attributes => (System.Reflection.ParameterAttributes)UnderlyingParameter.Attributes; + + /// + public object? DefaultValue => UnderlyingParameter.RawDefaultValue; + + /// + public bool HasDefaultValue => UnderlyingParameter.HasDefaultValue; + + /// + public bool IsIn => UnderlyingParameter.IsIn; + + /// + public bool IsLcid => UnderlyingParameter.IsLcid; + + /// + public bool IsOptional => UnderlyingParameter.IsOptional; + + /// + public bool IsOut => UnderlyingParameter.IsOut; + + /// + public bool IsRetval => UnderlyingParameter.IsRetval; + + /// + public IMemberSymbol Member => ResolveMemberSymbol(UnderlyingParameter.Member); + + /// + public int MetadataToken => UnderlyingParameter.MetadataToken; + + /// + public string? Name => UnderlyingParameter.Name; + + /// + public ITypeSymbol ParameterType => ResolveTypeSymbol(UnderlyingParameter.ParameterType); + + /// + public int Position => UnderlyingParameter.Position; + + /// + public override bool IsComplete => _builder == null; + + /// + public CustomAttribute[] GetCustomAttributes(bool inherit = false) + { + return ResolveCustomAttributes(UnderlyingParameter.GetCustomAttributesData()); + } + + /// + public virtual CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) + { + return ResolveCustomAttributes(UnderlyingParameter.__GetCustomAttributes(attributeType.Unpack(), inherit)); + } + + /// + public virtual CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) + { + return ResolveCustomAttribute(UnderlyingParameter.__GetCustomAttributes(attributeType.Unpack(), inherit).FirstOrDefault()); + } + + /// + public virtual bool IsDefined(ITypeSymbol attributeType, bool inherit = false) + { + return UnderlyingParameter.IsDefined(attributeType.Unpack(), inherit); + } + + /// + public ITypeSymbol[] GetOptionalCustomModifiers() + { + return ResolveTypeSymbols(UnderlyingParameter.GetOptionalCustomModifiers()); + } + + /// + public ITypeSymbol[] GetRequiredCustomModifiers() + { + return ResolveTypeSymbols(UnderlyingParameter.GetRequiredCustomModifiers()); + } + + #endregion + + /// + public void OnComplete() + { + var p = ResolvingMethod.UnderlyingMethodBase.GetParameters(); + _parameter = p[Position]; + _builder = null; + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionPropertySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionPropertySymbolBuilder.cs new file mode 100644 index 000000000..8ec05eeff --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionPropertySymbolBuilder.cs @@ -0,0 +1,184 @@ +using System; + +using IKVM.CoreLib.Symbols.Emit; +using IKVM.Reflection; +using IKVM.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + class IkvmReflectionPropertySymbolBuilder : IkvmReflectionMemberSymbolBuilder, IIkvmReflectionPropertySymbolBuilder + { + + PropertyBuilder? _builder; + PropertyInfo _property; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + /// + public IkvmReflectionPropertySymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol resolvingModule, IIkvmReflectionTypeSymbol resolvingType, PropertyBuilder builder) : + base(context, resolvingModule, resolvingType) + { + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + _property = _builder; + } + + /// + public PropertyInfo UnderlyingProperty => _property; + + /// + public PropertyBuilder UnderlyingPropertyBuilder => _builder ?? throw new InvalidOperationException(); + + /// + public override MemberInfo UnderlyingMember => UnderlyingProperty; + + #region IPropertySymbol + + /// + public void SetConstant(object? defaultValue) + { + UnderlyingPropertyBuilder.SetConstant(defaultValue); + } + + /// + public void SetGetMethod(IMethodSymbolBuilder mdBuilder) + { + UnderlyingPropertyBuilder.SetGetMethod(((IIkvmReflectionMethodSymbolBuilder)mdBuilder).UnderlyingMethodBuilder); + } + + /// + public void SetSetMethod(IMethodSymbolBuilder mdBuilder) + { + UnderlyingPropertyBuilder.SetSetMethod(((IIkvmReflectionMethodSymbolBuilder)mdBuilder).UnderlyingMethodBuilder); + } + + /// + public void AddOtherMethod(IMethodSymbolBuilder mdBuilder) + { + UnderlyingPropertyBuilder.AddOtherMethod(((IIkvmReflectionMethodSymbolBuilder)mdBuilder).UnderlyingMethodBuilder); + } + + /// + public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) + { + UnderlyingPropertyBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); + } + + /// + public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) + { + UnderlyingPropertyBuilder.SetCustomAttribute(((IkvmReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); + } + + #endregion + + #region IPropertySymbol + + /// + public System.Reflection.PropertyAttributes Attributes => (System.Reflection.PropertyAttributes)UnderlyingProperty.Attributes; + + /// + public bool CanRead => UnderlyingProperty.CanRead; + + /// + public bool CanWrite => UnderlyingProperty.CanWrite; + + /// + public bool IsSpecialName => UnderlyingProperty.IsSpecialName; + + /// + public ITypeSymbol PropertyType => ResolveTypeSymbol(UnderlyingProperty.PropertyType); + + /// + public IMethodSymbol? GetMethod => ResolveMethodSymbol(UnderlyingProperty.GetMethod); + + /// + public IMethodSymbol? SetMethod => ResolveMethodSymbol(UnderlyingProperty.SetMethod); + + /// + public override bool IsComplete => _builder == null; + + /// + public object? GetRawConstantValue() + { + return UnderlyingProperty.GetRawConstantValue(); + } + + /// + public IMethodSymbol[] GetAccessors() + { + return ResolveMethodSymbols(UnderlyingProperty.GetAccessors()); + } + + /// + public IMethodSymbol[] GetAccessors(bool nonPublic) + { + return ResolveMethodSymbols(UnderlyingProperty.GetAccessors(nonPublic)); + } + + /// + public IParameterSymbol[] GetIndexParameters() + { + return ResolveParameterSymbols(UnderlyingProperty.GetIndexParameters()); + } + + /// + public IMethodSymbol? GetGetMethod() + { + return ResolveMethodSymbol(UnderlyingProperty.GetGetMethod()); + } + + /// + public IMethodSymbol? GetGetMethod(bool nonPublic) + { + return ResolveMethodSymbol(UnderlyingProperty.GetGetMethod(nonPublic)); + } + + /// + public IMethodSymbol? GetSetMethod() + { + return ResolveMethodSymbol(UnderlyingProperty.GetSetMethod()); + } + + /// + public IMethodSymbol? GetSetMethod(bool nonPublic) + { + return ResolveMethodSymbol(UnderlyingProperty.GetSetMethod(nonPublic)); + } + + /// + public ITypeSymbol GetModifiedPropertyType() + { + throw new NotImplementedException(); + } + + /// + public ITypeSymbol[] GetOptionalCustomModifiers() + { + return ResolveTypeSymbols(UnderlyingProperty.GetOptionalCustomModifiers()); + } + + /// + public ITypeSymbol[] GetRequiredCustomModifiers() + { + return ResolveTypeSymbols(UnderlyingProperty.GetRequiredCustomModifiers()); + } + +#endregion + + /// + public override void OnComplete() + { + _property = (PropertyInfo?)ResolvingModule.UnderlyingModule.ResolveMember(MetadataToken) ?? throw new InvalidOperationException(); + _builder = null; + base.OnComplete(); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionSymbolBuilder.cs new file mode 100644 index 000000000..f00d73726 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionSymbolBuilder.cs @@ -0,0 +1,24 @@ +using IKVM.CoreLib.Symbols.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + /// + /// Reflection-specific implementation of . + /// + abstract class IkvmReflectionSymbolBuilder : IkvmReflectionSymbol, IIkvmReflectionSymbolBuilder + { + + /// + /// Initializes a new instance. + /// + /// + protected IkvmReflectionSymbolBuilder(IkvmReflectionSymbolContext context) : + base(context) + { + + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionTypeSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionTypeSymbolBuilder.cs new file mode 100644 index 000000000..323f309d1 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionTypeSymbolBuilder.cs @@ -0,0 +1,802 @@ +using System; +using System.Runtime.InteropServices; + +using IKVM.CoreLib.Symbols.Emit; +using IKVM.Reflection; +using IKVM.Reflection.Emit; + +using Type = IKVM.Reflection.Type; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + class IkvmReflectionTypeSymbolBuilder : IkvmReflectionMemberSymbolBuilder, IIkvmReflectionTypeSymbolBuilder + { + + TypeBuilder? _builder; + Type _type; + IkvmReflectionTypeImpl _impl; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + public IkvmReflectionTypeSymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol resolvingModule, TypeBuilder builder) : + base(context, resolvingModule, null) + { + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + _type = _builder; + _impl = new IkvmReflectionTypeImpl(this); + } + + /// + public Type UnderlyingType => _type; + + /// + public override MemberInfo UnderlyingMember => UnderlyingType; + + /// + public TypeBuilder UnderlyingTypeBuilder => _builder ?? throw new InvalidOperationException(); + + #region ITypeSymbolBuilder + + /// + public void SetParent(ITypeSymbol? parent) + { + UnderlyingTypeBuilder.SetParent(parent?.Unpack()); + } + + /// + public IGenericTypeParameterSymbolBuilder[] DefineGenericParameters(params string[] names) + { + var l = UnderlyingTypeBuilder.DefineGenericParameters(names); + var a = new IGenericTypeParameterSymbolBuilder[l.Length]; + for (int i = 0; i < l.Length; i++) + a[i] = new IkvmReflectionGenericTypeParameterSymbolBuilder(Context, ResolvingModule, this, null, l[i]); + + return a; + } + + /// + public void AddInterfaceImplementation(ITypeSymbol interfaceType) + { + UnderlyingTypeBuilder.AddInterfaceImplementation(interfaceType.Unpack()); + } + + /// + public IConstructorSymbolBuilder DefineConstructor(System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, ITypeSymbol[]? parameterTypes) + { + return ResolveConstructorSymbol(UnderlyingTypeBuilder.DefineConstructor((MethodAttributes)attributes, (CallingConventions)callingConvention, parameterTypes?.Unpack())); + } + + /// + public IConstructorSymbolBuilder DefineConstructor(System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? requiredCustomModifiers, ITypeSymbol[][]? optionalCustomModifiers) + { + return ResolveConstructorSymbol(UnderlyingTypeBuilder.DefineConstructor((MethodAttributes)attributes, (CallingConventions)callingConvention, parameterTypes?.Unpack(), requiredCustomModifiers?.Unpack(), optionalCustomModifiers?.Unpack())); + } + + /// + public IConstructorSymbolBuilder DefineDefaultConstructor(System.Reflection.MethodAttributes attributes) + { + return ResolveConstructorSymbol(UnderlyingTypeBuilder.DefineDefaultConstructor((MethodAttributes)attributes)); + } + + /// + public IEventSymbolBuilder DefineEvent(string name, System.Reflection.EventAttributes attributes, ITypeSymbol eventtype) + { + return ResolveEventSymbol(UnderlyingTypeBuilder.DefineEvent(name, (EventAttributes)attributes, eventtype.Unpack())); + } + + /// + public IFieldSymbolBuilder DefineField(string fieldName, ITypeSymbol type, System.Reflection.FieldAttributes attributes) + { + return ResolveFieldSymbol(UnderlyingTypeBuilder.DefineField(fieldName, type.Unpack(), (FieldAttributes)attributes)); + } + + /// + public IFieldSymbolBuilder DefineField(string fieldName, ITypeSymbol type, ITypeSymbol[]? requiredCustomModifiers, ITypeSymbol[]? optionalCustomModifiers, System.Reflection.FieldAttributes attributes) + { + return ResolveFieldSymbol(UnderlyingTypeBuilder.DefineField(fieldName, type.Unpack(), requiredCustomModifiers?.Unpack(), optionalCustomModifiers?.Unpack(), (FieldAttributes)attributes)); + } + + /// + public IMethodSymbolBuilder DefineMethod(string name, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers) + { + return ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, (MethodAttributes)attributes, (CallingConventions)callingConvention, returnType?.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack())); + } + + /// + public IMethodSymbolBuilder DefineMethod(string name, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes) + { + return ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, (MethodAttributes)attributes, (CallingConventions)callingConvention, returnType?.Unpack(), parameterTypes?.Unpack())); + } + + /// + public IMethodSymbolBuilder DefineMethod(string name, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention) + { + return ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, (MethodAttributes)attributes, (CallingConventions)callingConvention)); + } + + /// + public IMethodSymbolBuilder DefineMethod(string name, System.Reflection.MethodAttributes attributes) + { + return ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, (MethodAttributes)attributes)); + } + + /// + public IMethodSymbolBuilder DefineMethod(string name, System.Reflection.MethodAttributes attributes, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes) + { + return ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, (MethodAttributes)attributes, returnType?.Unpack(), parameterTypes?.Unpack())); + } + + /// + public void DefineMethodOverride(IMethodSymbolBuilder methodInfoBody, IMethodSymbol methodInfoDeclaration) + { + UnderlyingTypeBuilder.DefineMethodOverride(methodInfoBody.Unpack(), methodInfoDeclaration.Unpack()); + } + + /// + public ITypeSymbolBuilder DefineNestedType(string name, System.Reflection.TypeAttributes attr, ITypeSymbol? parent, ITypeSymbol[]? interfaces) + { + return ResolveTypeSymbol(UnderlyingTypeBuilder.DefineNestedType(name, (TypeAttributes)attr, parent?.Unpack(), interfaces?.Unpack())); + } + + /// + public ITypeSymbolBuilder DefineNestedType(string name, System.Reflection.TypeAttributes attr, ITypeSymbol? parent, System.Reflection.Emit.PackingSize packSize, int typeSize) + { + return ResolveTypeSymbol(UnderlyingTypeBuilder.DefineNestedType(name, (TypeAttributes)attr, parent?.Unpack(), (PackingSize)packSize, typeSize)); + } + + /// + public ITypeSymbolBuilder DefineNestedType(string name, System.Reflection.TypeAttributes attr, ITypeSymbol? parent, System.Reflection.Emit.PackingSize packSize) + { + return (ITypeSymbolBuilder)ResolveTypeSymbol(UnderlyingTypeBuilder.DefineNestedType(name, (TypeAttributes)attr, parent?.Unpack(), (PackingSize)packSize)); + } + + /// + public ITypeSymbolBuilder DefineNestedType(string name) + { + return (ITypeSymbolBuilder)ResolveTypeSymbol(UnderlyingTypeBuilder.DefineNestedType(name)); + } + + /// + public ITypeSymbolBuilder DefineNestedType(string name, System.Reflection.TypeAttributes attr, ITypeSymbol? parent) + { + return (ITypeSymbolBuilder)ResolveTypeSymbol(UnderlyingTypeBuilder.DefineNestedType(name, (TypeAttributes)attr, parent?.Unpack())); + } + + /// + public ITypeSymbolBuilder DefineNestedType(string name, System.Reflection.TypeAttributes attr) + { + return (ITypeSymbolBuilder)ResolveTypeSymbol(UnderlyingTypeBuilder.DefineNestedType(name, (TypeAttributes)attr)); + } + + /// + public ITypeSymbolBuilder DefineNestedType(string name, System.Reflection.TypeAttributes attr, ITypeSymbol? parent, int typeSize) + { + return (ITypeSymbolBuilder)ResolveTypeSymbol(UnderlyingTypeBuilder.DefineNestedType(name, (TypeAttributes)attr, parent?.Unpack(), typeSize)); + } + + /// + public IMethodSymbolBuilder DefinePInvokeMethod(string name, string dllName, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet) + { + return (IMethodSymbolBuilder)ResolveMethodSymbol(UnderlyingTypeBuilder.DefinePInvokeMethod(name, dllName, (MethodAttributes)attributes, (CallingConventions)callingConvention, returnType?.Unpack(), parameterTypes?.Unpack(), nativeCallConv, nativeCharSet)); + } + + /// + public IMethodSymbolBuilder DefinePInvokeMethod(string name, string dllName, string entryName, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet) + { + return (IMethodSymbolBuilder)ResolveMethodSymbol(UnderlyingTypeBuilder.DefinePInvokeMethod(name, dllName, entryName, (MethodAttributes)attributes, (CallingConventions)callingConvention, returnType?.Unpack(), parameterTypes?.Unpack(), nativeCallConv, nativeCharSet)); + } + + /// + public IMethodSymbolBuilder DefinePInvokeMethod(string name, string dllName, string entryName, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers, CallingConvention nativeCallConv, CharSet nativeCharSet) + { + return (IMethodSymbolBuilder)ResolveMethodSymbol(UnderlyingTypeBuilder.DefinePInvokeMethod(name, dllName, entryName, (MethodAttributes)attributes, (CallingConventions)callingConvention, returnType?.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack(), nativeCallConv, nativeCharSet)); + } + + /// + public IPropertySymbolBuilder DefineProperty(string name, System.Reflection.PropertyAttributes attributes, ITypeSymbol returnType, ITypeSymbol[]? parameterTypes) + { + return (IPropertySymbolBuilder)ResolvePropertySymbol(UnderlyingTypeBuilder.DefineProperty(name, (PropertyAttributes)attributes, returnType.Unpack(), parameterTypes?.Unpack())); + } + + /// + public IPropertySymbolBuilder DefineProperty(string name, System.Reflection.PropertyAttributes attributes, System.Reflection.CallingConventions callingConvention, ITypeSymbol returnType, ITypeSymbol[]? parameterTypes) + { + return (IPropertySymbolBuilder)ResolvePropertySymbol(UnderlyingTypeBuilder.DefineProperty(name, (PropertyAttributes)attributes, (CallingConventions)callingConvention, returnType.Unpack(), parameterTypes?.Unpack())); + } + + /// + public IPropertySymbolBuilder DefineProperty(string name, System.Reflection.PropertyAttributes attributes, ITypeSymbol returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers) + { + return (IPropertySymbolBuilder)ResolvePropertySymbol(UnderlyingTypeBuilder.DefineProperty(name, (PropertyAttributes)attributes, returnType.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack())); + } + + /// + public IPropertySymbolBuilder DefineProperty(string name, System.Reflection.PropertyAttributes attributes, System.Reflection.CallingConventions callingConvention, ITypeSymbol returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers) + { + return (IPropertySymbolBuilder)ResolvePropertySymbol(UnderlyingTypeBuilder.DefineProperty(name, (PropertyAttributes)attributes, (CallingConventions)callingConvention, returnType.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack())); + } + + /// + public IConstructorSymbolBuilder DefineTypeInitializer() + { + return (IConstructorSymbolBuilder)ResolveConstructorSymbol(UnderlyingTypeBuilder.DefineTypeInitializer()); + } + /// + public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) + { + UnderlyingTypeBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); + } + + /// + public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) + { + UnderlyingTypeBuilder.SetCustomAttribute(((IkvmReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); + } + + #endregion + + #region ITypeSymbol + + /// + public System.Reflection.TypeAttributes Attributes => _impl.Attributes; + + /// + public IAssemblySymbol Assembly => _impl.Assembly; + + /// + public IMethodBaseSymbol? DeclaringMethod => _impl.DeclaringMethod; + + /// + public string? AssemblyQualifiedName => _impl.AssemblyQualifiedName; + + /// + public string? FullName => _impl.FullName; + + /// + public string? Namespace => _impl.Namespace; + + /// + public TypeCode TypeCode => _impl.TypeCode; + + /// + public ITypeSymbol? BaseType => _impl.BaseType; + + /// + public bool ContainsGenericParameters => _impl.ContainsGenericParameters; + + /// + public System.Reflection.GenericParameterAttributes GenericParameterAttributes => _impl.GenericParameterAttributes; + + /// + public int GenericParameterPosition => _impl.GenericParameterPosition; + + /// + public ITypeSymbol[] GenericTypeArguments => _impl.GenericTypeArguments; + + /// + public bool IsConstructedGenericType => _impl.IsConstructedGenericType; + + /// + public bool IsGenericType => _impl.IsGenericType; + + /// + public bool IsGenericTypeDefinition => _impl.IsGenericTypeDefinition; + + /// + public bool IsGenericParameter => _impl.IsGenericParameter; + + /// + public bool IsAutoLayout => _impl.IsAutoLayout; + + /// + public bool IsExplicitLayout => _impl.IsExplicitLayout; + + /// + public bool IsLayoutSequential => _impl.IsLayoutSequential; + + /// + public bool HasElementType => _impl.HasElementType; + + /// + public bool IsClass => _impl.IsClass; + + /// + public bool IsValueType => _impl.IsValueType; + + /// + public bool IsInterface => _impl.IsInterface; + + /// + public bool IsPrimitive => _impl.IsPrimitive; + + /// + public bool IsSZArray => _impl.IsSZArray; + + /// + public bool IsArray => _impl.IsArray; + + /// + public bool IsEnum => _impl.IsEnum; + + /// + public bool IsPointer => _impl.IsPointer; + + /// + public bool IsFunctionPointer => _impl.IsFunctionPointer; + + /// + public bool IsUnmanagedFunctionPointer => _impl.IsUnmanagedFunctionPointer; + + /// + public bool IsByRef => _impl.IsByRef; + + /// + public bool IsAbstract => _impl.IsAbstract; + + /// + public bool IsSealed => _impl.IsSealed; + + /// + public bool IsVisible => _impl.IsVisible; + + /// + public bool IsPublic => _impl.IsPublic; + + /// + public bool IsNotPublic => _impl.IsNotPublic; + + /// + public bool IsNested => _impl.IsNested; + + /// + public bool IsNestedAssembly => _impl.IsNestedAssembly; + + /// + public bool IsNestedFamANDAssem => _impl.IsNestedFamANDAssem; + + /// + public bool IsNestedFamily => _impl.IsNestedFamily; + + /// + public bool IsNestedFamORAssem => _impl.IsNestedFamORAssem; + + /// + public bool IsNestedPrivate => _impl.IsNestedPrivate; + + /// + public bool IsNestedPublic => _impl.IsNestedPublic; + + /// + public bool IsSerializable => _impl.IsSerializable; + + /// + public bool IsSignatureType => _impl.IsSignatureType; + + /// + public bool IsSpecialName => _impl.IsSpecialName; + + /// + public IConstructorSymbol? TypeInitializer => _impl.TypeInitializer; + + /// + public override bool IsComplete => _builder == null; + + /// + public int GetArrayRank() + { + return _impl.GetArrayRank(); + } + + /// + public IMemberSymbol[] GetDefaultMembers() + { + return _impl.GetDefaultMembers(); + } + + /// + public ITypeSymbol? GetElementType() + { + return _impl.GetElementType(); + } + + /// + public string? GetEnumName(object value) + { + return _impl.GetEnumName(value); + } + + /// + public string[] GetEnumNames() + { + return _impl.GetEnumNames(); + } + + /// + public ITypeSymbol GetEnumUnderlyingType() + { + return _impl.GetEnumUnderlyingType(); + } + + /// + public ITypeSymbol[] GetGenericArguments() + { + return _impl.GetGenericArguments(); + } + + /// + public ITypeSymbol[] GetGenericParameterConstraints() + { + return _impl.GetGenericParameterConstraints(); + } + + /// + public ITypeSymbol GetGenericTypeDefinition() + { + return _impl.GetGenericTypeDefinition(); + } + + /// + public ITypeSymbol? GetInterface(string name) + { + return _impl.GetInterface(name); + } + + /// + public ITypeSymbol? GetInterface(string name, bool ignoreCase) + { + return _impl.GetInterface(name, ignoreCase); + } + + /// + public ITypeSymbol[] GetInterfaces(bool inherit = true) + { + return _impl.GetInterfaces(inherit); + } + + /// + public InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) + { + return _impl.GetInterfaceMap(interfaceType); + } + + /// + public IMemberSymbol[] GetMember(string name) + { + return _impl.GetMember(name); + } + + /// + public IMemberSymbol[] GetMember(string name, System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetMember(name, bindingAttr); + } + + /// + public IMemberSymbol[] GetMember(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetMember(name, type, bindingAttr); + } + + /// + public IMemberSymbol[] GetMembers() + { + return _impl.GetMembers(); + } + + /// + public IMemberSymbol[] GetMembers(System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetMembers(bindingAttr); + } + + public IConstructorSymbol? GetConstructor(ITypeSymbol[] types) + { + return _impl.GetConstructor(types); + } + + /// + public IConstructorSymbol? GetConstructor(System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) + { + return _impl.GetConstructor(bindingAttr, types); + } + + /// + public IConstructorSymbol[] GetConstructors() + { + return _impl.GetConstructors(); + } + + /// + public IConstructorSymbol[] GetConstructors(System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetConstructors(bindingAttr); + } + + /// + public IFieldSymbol? GetField(string name) + { + return _impl.GetField(name); + } + + /// + public IFieldSymbol? GetField(string name, System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetField(name, bindingAttr); + } + + /// + public IFieldSymbol[] GetFields() + { + return _impl.GetFields(); + } + + /// + public IFieldSymbol[] GetFields(System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetFields(bindingAttr); + } + + /// + public IMethodSymbol? GetMethod(string name) + { + return _impl.GetMethod(name); + } + + /// + public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) + { + return _impl.GetMethod(name, types); + } + + /// + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetMethod(name, bindingAttr); + } + + /// + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) + { + return _impl.GetMethod(name, bindingAttr, types); + } + + /// + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + { + return _impl.GetMethod(name, bindingAttr, callConvention, types, modifiers); + } + + /// + public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + { + return _impl.GetMethod(name, genericParameterCount, bindingAttr, callConvention, types, modifiers); + } + + /// + public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + { + return _impl.GetMethod(name, genericParameterCount, bindingAttr, types, modifiers); + } + + /// + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + { + return _impl.GetMethod(name, bindingAttr, types, modifiers); + } + + /// + public IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + { + return _impl.GetMethod(name, genericParameterCount, types, modifiers); + } + + /// + public IMethodSymbol[] GetMethods() + { + return _impl.GetMethods(); + } + + /// + public IMethodSymbol[] GetMethods(System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetMethods(bindingAttr); + } + + /// + public IPropertySymbol? GetProperty(string name) + { + return _impl.GetProperty(name); + } + + /// + public IPropertySymbol? GetProperty(string name, System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetProperty(name, bindingAttr); + } + + /// + public IPropertySymbol? GetProperty(string name, ITypeSymbol[] types) + { + return _impl.GetProperty(name, types); + } + + /// + public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types) + { + return _impl.GetProperty(name, returnType, types); + } + + /// + public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) + { + return _impl.GetProperty(name, returnType); + } + + /// + public IPropertySymbol[] GetProperties() + { + return _impl.GetProperties(); + } + + /// + public IPropertySymbol[] GetProperties(System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetProperties(bindingAttr); + } + + /// + public IEventSymbol? GetEvent(string name) + { + return _impl.GetEvent(name); + } + + /// + public IEventSymbol? GetEvent(string name, System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetEvent(name, bindingAttr); + } + + /// + public IEventSymbol[] GetEvents() + { + return _impl.GetEvents(); + } + + /// + public IEventSymbol[] GetEvents(System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetEvents(bindingAttr); + } + + /// + public ITypeSymbol? GetNestedType(string name) + { + return _impl.GetNestedType(name); + } + + /// + public ITypeSymbol? GetNestedType(string name, System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetNestedType(name, bindingAttr); + } + + /// + public ITypeSymbol[] GetNestedTypes() + { + return _impl.GetNestedTypes(); + } + + /// + public ITypeSymbol[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetNestedTypes(); + } + + /// + public bool IsAssignableFrom(ITypeSymbol? c) + { + return _impl.IsAssignableFrom(c); + } + + /// + public bool IsSubclassOf(ITypeSymbol c) + { + return _impl.IsSubclassOf(c); + } + + /// + public bool IsEnumDefined(object value) + { + return _impl.IsEnumDefined(value); + } + + /// + public ITypeSymbol MakeArrayType() + { + return _impl.MakeArrayType(); + } + + /// + public ITypeSymbol MakeArrayType(int rank) + { + return _impl.MakeArrayType(rank); + } + + /// + public ITypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments) + { + return _impl.MakeGenericType(typeArguments); + } + + /// + public ITypeSymbol MakePointerType() + { + return _impl.MakePointerType(); + } + + /// + public ITypeSymbol MakeByRefType() + { + return _impl.MakeByRefType(); + } + + #endregion + + /// + public void Complete() + { + if (_builder != null) + { + // complete type + if (_builder.IsCreated() == false) + _builder.CreateType(); + + // force module to reresolve + Context.GetOrCreateModuleSymbol(ResolvingModule.UnderlyingModule); + OnComplete(); + } + } + + /// + public override void OnComplete() + { + const System.Reflection.BindingFlags DefaultBindingFlags = System.Reflection.BindingFlags.DeclaredOnly | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Static; + + _type = ResolvingModule.UnderlyingModule.ResolveType(MetadataToken); + _builder = null; + + foreach (var i in GetGenericArguments()) + if (i is IIkvmReflectionGenericTypeParameterSymbolBuilder b) + b.OnComplete(); + + foreach (var i in GetConstructors(DefaultBindingFlags)) + if (i is IIkvmReflectionConstructorSymbolBuilder b) + b.OnComplete(); + + foreach (var i in GetMethods(DefaultBindingFlags)) + if (i is IIkvmReflectionMethodSymbolBuilder b) + b.OnComplete(); + + foreach (var i in GetFields(DefaultBindingFlags)) + if (i is IIkvmReflectionFieldSymbolBuilder b) + b.OnComplete(); + + foreach (var i in GetProperties(DefaultBindingFlags)) + if (i is IIkvmReflectionPropertySymbolBuilder b) + b.OnComplete(); + + foreach (var m in GetEvents(DefaultBindingFlags)) + if (m is IIkvmReflectionPropertySymbolBuilder b) + b.OnComplete(); + + base.OnComplete(); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionAssemblySymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionAssemblySymbol.cs new file mode 100644 index 000000000..73df3a3be --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionAssemblySymbol.cs @@ -0,0 +1,32 @@ +using IKVM.CoreLib.Symbols.IkvmReflection.Emit; +using IKVM.Reflection; +using IKVM.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + interface IIkvmReflectionAssemblySymbol : IIkvmReflectionSymbol, IAssemblySymbol + { + + /// + /// Gets a reference to the underlying . + /// + Assembly UnderlyingAssembly { get; } + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IIkvmReflectionModuleSymbol GetOrCreateModuleSymbol(Module module); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IIkvmReflectionModuleSymbolBuilder GetOrCreateModuleSymbol(ModuleBuilder module); + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionConstructorSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionConstructorSymbol.cs new file mode 100644 index 000000000..13a843199 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionConstructorSymbol.cs @@ -0,0 +1,16 @@ +using IKVM.Reflection; + +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + interface IIkvmReflectionConstructorSymbol : IIkvmReflectionMethodBaseSymbol, IConstructorSymbol + { + + /// + /// Gets the underlying . + /// + ConstructorInfo UnderlyingConstructor { get; } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionEventSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionEventSymbol.cs new file mode 100644 index 000000000..b4395531a --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionEventSymbol.cs @@ -0,0 +1,16 @@ +using IKVM.Reflection; + +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + interface IIkvmReflectionEventSymbol : IIkvmReflectionMemberSymbol, IEventSymbol + { + + /// + /// Gets the underlying . + /// + EventInfo UnderlyingEvent { get; } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionFieldSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionFieldSymbol.cs new file mode 100644 index 000000000..a45d4aa00 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionFieldSymbol.cs @@ -0,0 +1,16 @@ +using IKVM.Reflection; + +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + interface IIkvmReflectionFieldSymbol : IIkvmReflectionMemberSymbol, IFieldSymbol + { + + /// + /// Gets the underlying . + /// + FieldInfo UnderlyingField { get; } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionMemberSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionMemberSymbol.cs new file mode 100644 index 000000000..a0fa12943 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionMemberSymbol.cs @@ -0,0 +1,26 @@ +using IKVM.Reflection; + +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + interface IIkvmReflectionMemberSymbol : IIkvmReflectionSymbol, IMemberSymbol + { + + /// + /// Gets the resolving module. + /// + IIkvmReflectionModuleSymbol ResolvingModule { get; } + + /// + /// Gets the resolving type. + /// + IIkvmReflectionTypeSymbol? ResolvingType { get; } + + /// + /// Gets the underlying . + /// + MemberInfo UnderlyingMember { get; } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionMethodBaseSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionMethodBaseSymbol.cs new file mode 100644 index 000000000..483704f37 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionMethodBaseSymbol.cs @@ -0,0 +1,16 @@ +using IKVM.Reflection; + +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + interface IIkvmReflectionMethodBaseSymbol : IIkvmReflectionMemberSymbol, IMethodBaseSymbol + { + + /// + /// Gets the underlying . + /// + MethodBase UnderlyingMethodBase { get; } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionMethodSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionMethodSymbol.cs new file mode 100644 index 000000000..c91b72a6b --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionMethodSymbol.cs @@ -0,0 +1,16 @@ +using IKVM.Reflection; + +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + interface IIkvmReflectionMethodSymbol : IIkvmReflectionMethodBaseSymbol, IMethodSymbol + { + + /// + /// Gets the underlying . + /// + MethodInfo UnderlyingMethod { get; } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionModuleSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionModuleSymbol.cs new file mode 100644 index 000000000..9c5129c3d --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionModuleSymbol.cs @@ -0,0 +1,123 @@ +using IKVM.CoreLib.Symbols.IkvmReflection.Emit; +using IKVM.Reflection; +using IKVM.Reflection.Emit; + +using Type = IKVM.Reflection.Type; + +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + interface IIkvmReflectionModuleSymbol : IIkvmReflectionSymbol, IModuleSymbol + { + + /// + /// Gets the which contains this . + /// + IIkvmReflectionAssemblySymbol ResolvingAssembly { get; } + + /// + /// Gets the underlying . + /// + Module UnderlyingModule { get; } + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IIkvmReflectionTypeSymbol GetOrCreateTypeSymbol(Type type); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IIkvmReflectionTypeSymbolBuilder GetOrCreateTypeSymbol(TypeBuilder type); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IIkvmReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IIkvmReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IIkvmReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IIkvmReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IIkvmReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IIkvmReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IIkvmReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IIkvmReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IIkvmReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IIkvmReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IIkvmReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IIkvmReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter); + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionParameterSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionParameterSymbol.cs new file mode 100644 index 000000000..ddc2d8eb7 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionParameterSymbol.cs @@ -0,0 +1,26 @@ +using IKVM.Reflection; + +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + interface IIkvmReflectionParameterSymbol : IIkvmReflectionSymbol, IParameterSymbol + { + + /// + /// Gets the module that resolved the parameter. + /// + IIkvmReflectionModuleSymbol ResolvingModule { get; } + + /// + /// Gets the method that resolved the parameter. + /// + IIkvmReflectionMethodBaseSymbol ResolvingMethod { get; } + + /// + /// Gets the underlying . + /// + ParameterInfo UnderlyingParameter { get; } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionPropertySymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionPropertySymbol.cs new file mode 100644 index 000000000..57e05528e --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionPropertySymbol.cs @@ -0,0 +1,16 @@ +using IKVM.Reflection; + +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + interface IIkvmReflectionPropertySymbol : IIkvmReflectionMemberSymbol, IPropertySymbol + { + + /// + /// Gets the underlying . + /// + PropertyInfo UnderlyingProperty { get; } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionSymbol.cs new file mode 100644 index 000000000..891dc53f8 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionSymbol.cs @@ -0,0 +1,336 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Diagnostics.CodeAnalysis; + +using IKVM.CoreLib.Symbols.IkvmReflection.Emit; +using IKVM.Reflection; +using IKVM.Reflection.Emit; + +using Type = IKVM.Reflection.Type; + +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + interface IIkvmReflectionSymbol : ISymbol + { + + /// + /// Gets the that contains this symbol. + /// + IkvmReflectionSymbolContext Context { get; } + + /// + /// Resolves the symbol for the specified assembly. + /// + /// + /// + [return: NotNullIfNotNull(nameof(assembly))] + IIkvmReflectionAssemblySymbol? ResolveAssemblySymbol(Assembly? assembly); + + /// + /// Resolves the symbol for the specified assembly builder. + /// + /// + /// + [return: NotNullIfNotNull(nameof(assembly))] + IIkvmReflectionAssemblySymbolBuilder ResolveAssemblySymbol(AssemblyBuilder assembly); + + /// + /// Resolves the symbols for the specified assemblies. + /// + /// + /// + [return: NotNullIfNotNull(nameof(assemblies))] + IIkvmReflectionAssemblySymbol[]? ResolveAssemblySymbols(Assembly[]? assemblies); + + /// + /// Resolves the symbol for the specified module. + /// + /// + /// + [return: NotNullIfNotNull(nameof(module))] + IIkvmReflectionModuleSymbol? ResolveModuleSymbol(Module? module); + + /// + /// Resolves the symbol for the specified module. + /// + /// + /// + [return: NotNullIfNotNull(nameof(module))] + IIkvmReflectionModuleSymbolBuilder ResolveModuleSymbol(ModuleBuilder module); + + /// + /// Resolves the symbols for the specified modules. + /// + /// + /// + [return: NotNullIfNotNull(nameof(modules))] + IIkvmReflectionModuleSymbol[]? ResolveModuleSymbols(Module[]? modules); + + /// + /// Resolves the symbols for the specified modules. + /// + /// + /// + IEnumerable ResolveModuleSymbols(IEnumerable modules); + + /// + /// Resolves the symbol for the specified member. + /// + /// + /// + [return: NotNullIfNotNull(nameof(member))] + IIkvmReflectionMemberSymbol? ResolveMemberSymbol(MemberInfo? member); + + /// + /// Resolves the symbols for the specified members. + /// + /// + /// + [return: NotNullIfNotNull(nameof(types))] + IIkvmReflectionMemberSymbol[]? ResolveMemberSymbols(MemberInfo[]? types); + + /// + /// Resolves the symbol for the specified type. + /// + /// + /// + [return: NotNullIfNotNull(nameof(type))] + IIkvmReflectionTypeSymbol? ResolveTypeSymbol(Type? type); + + /// + /// Resolves the symbol for the specified type. + /// + /// + /// + [return: NotNullIfNotNull(nameof(type))] + IIkvmReflectionTypeSymbolBuilder ResolveTypeSymbol(TypeBuilder type); + + /// + /// Resolves the symbols for the specified types. + /// + /// + /// + [return: NotNullIfNotNull(nameof(types))] + IIkvmReflectionTypeSymbol[]? ResolveTypeSymbols(Type[]? types); + + /// + /// Resolves the symbols for the specified types. + /// + /// + /// + IEnumerable ResolveTypeSymbols(IEnumerable types); + + /// + /// Resolves the symbol for the specified method. + /// + /// + /// + [return: NotNullIfNotNull(nameof(method))] + IIkvmReflectionMethodBaseSymbol? ResolveMethodBaseSymbol(MethodBase? method); + + /// + /// Resolves the symbol for the specified constructor. + /// + /// + /// + [return: NotNullIfNotNull(nameof(ctor))] + IIkvmReflectionConstructorSymbol? ResolveConstructorSymbol(ConstructorInfo? ctor); + + /// + /// Resolves the symbol for the specified constructor. + /// + /// + /// + [return: NotNullIfNotNull(nameof(ctor))] + IIkvmReflectionConstructorSymbolBuilder ResolveConstructorSymbol(ConstructorBuilder ctor); + + /// + /// Resolves the symbols for the specified constructors. + /// + /// + /// + [return: NotNullIfNotNull(nameof(ctors))] + IIkvmReflectionConstructorSymbol[]? ResolveConstructorSymbols(ConstructorInfo[]? ctors); + + /// + /// Resolves the symbol for the specified method. + /// + /// + /// + [return: NotNullIfNotNull(nameof(method))] + IIkvmReflectionMethodSymbol? ResolveMethodSymbol(MethodInfo? method); + + /// + /// Resolves the symbol for the specified method. + /// + /// + /// + [return: NotNullIfNotNull(nameof(method))] + IIkvmReflectionMethodSymbolBuilder ResolveMethodSymbol(MethodBuilder method); + + /// + /// Resolves the symbols for the specified methods. + /// + /// + /// + [return: NotNullIfNotNull(nameof(methods))] + IIkvmReflectionMethodSymbol[]? ResolveMethodSymbols(MethodInfo[]? methods); + + /// + /// Resolves the symbol for the specified field. + /// + /// + /// + [return: NotNullIfNotNull(nameof(field))] + IIkvmReflectionFieldSymbol? ResolveFieldSymbol(FieldInfo? field); + + /// + /// Resolves the symbol for the specified field. + /// + /// + /// + [return: NotNullIfNotNull(nameof(field))] + IIkvmReflectionFieldSymbolBuilder ResolveFieldSymbol(FieldBuilder field); + + /// + /// Resolves the symbols for the specified fields. + /// + /// + /// + [return: NotNullIfNotNull(nameof(fields))] + IIkvmReflectionFieldSymbol[]? ResolveFieldSymbols(FieldInfo[]? fields); + + /// + /// Resolves the symbol for the specified property. + /// + /// + /// + [return: NotNullIfNotNull(nameof(property))] + IIkvmReflectionPropertySymbol? ResolvePropertySymbol(PropertyInfo? property); + + /// + /// Resolves the symbol for the specified property. + /// + /// + /// + [return: NotNullIfNotNull(nameof(property))] + IIkvmReflectionPropertySymbolBuilder ResolvePropertySymbol(PropertyBuilder property); + + /// + /// Resolves the symbols for the specified properties. + /// + /// + /// + [return: NotNullIfNotNull(nameof(properties))] + IIkvmReflectionPropertySymbol[]? ResolvePropertySymbols(PropertyInfo[]? properties); + + /// + /// Resolves the symbol for the specified event. + /// + /// + /// + [return: NotNullIfNotNull(nameof(@event))] + IIkvmReflectionEventSymbol? ResolveEventSymbol(EventInfo? @event); + + /// + /// Resolves the symbol for the specified event. + /// + /// + /// + [return: NotNullIfNotNull(nameof(@event))] + IIkvmReflectionEventSymbolBuilder ResolveEventSymbol(EventBuilder @event); + + /// + /// Resolves the symbols for the specified events. + /// + /// + /// + [return: NotNullIfNotNull(nameof(events))] + IIkvmReflectionEventSymbol[]? ResolveEventSymbols(EventInfo[]? events); + + /// + /// Resolves the symbol for the specified parameter. + /// + /// + /// + [return: NotNullIfNotNull(nameof(parameter))] + IIkvmReflectionParameterSymbol? ResolveParameterSymbol(ParameterInfo? parameter); + + /// + /// Resolves the symbol for the specified parameter. + /// + /// + /// + [return: NotNullIfNotNull(nameof(parameter))] + IIkvmReflectionParameterSymbolBuilder? ResolveParameterSymbol(ParameterBuilder parameter); + + /// + /// Resolves the symbols for the specified parameters. + /// + /// + /// + [return: NotNullIfNotNull(nameof(parameters))] + IIkvmReflectionParameterSymbol[]? ResolveParameterSymbols(ParameterInfo[]? parameters); + + /// + /// Transforms a custom set of custom attribute data records to a symbol record. + /// + /// + /// + [return: NotNullIfNotNull(nameof(attributes))] + CustomAttribute[]? ResolveCustomAttributes(IList? attributes); + + /// + /// Transforms a custom set of custom attribute data records to a symbol record. + /// + /// + /// + IEnumerable ResolveCustomAttributes(IEnumerable attributes); + + /// + /// Transforms a custom attribute data record to a symbol record. + /// + /// + /// + [return: NotNullIfNotNull(nameof(customAttributeData))] + CustomAttribute? ResolveCustomAttribute(CustomAttributeData? customAttributeData); + + /// + /// Transforms a list of values into symbols. + /// + /// + /// + ImmutableArray ResolveCustomAttributeTypedArguments(IList args); + + /// + /// Transforms a values into a symbol. + /// + /// + /// + CustomAttributeTypedArgument ResolveCustomAttributeTypedArgument(IKVM.Reflection.CustomAttributeTypedArgument arg); + + /// + /// Transforms the type as appropriate. + /// + /// + /// + object? ResolveCustomAttributeTypedValue(object? value); + + /// + /// Transforms a list of values into symbols. + /// + /// + /// + ImmutableArray ResolveCustomAttributeNamedArguments(IList args); + + /// + /// Transforms a values into a symbol. + /// + /// + /// + CustomAttributeNamedArgument ResolveCustomAttributeNamedArgument(IKVM.Reflection.CustomAttributeNamedArgument arg); + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionTypeSymbol.cs new file mode 100644 index 000000000..fd6281149 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionTypeSymbol.cs @@ -0,0 +1,16 @@ +using Type = IKVM.Reflection.Type; + +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + interface IIkvmReflectionTypeSymbol : IIkvmReflectionMemberSymbol, ITypeSymbol + { + + /// + /// Gets the underlying . + /// + Type UnderlyingType { get; } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblyMetadata.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblyMetadata.cs new file mode 100644 index 000000000..11dfb7115 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblyMetadata.cs @@ -0,0 +1,63 @@ +using System; +using System.Reflection.Metadata.Ecma335; +using System.Threading; + +using IKVM.CoreLib.Collections; +using IKVM.CoreLib.Symbols.IkvmReflection.Emit; +using IKVM.CoreLib.Threading; +using IKVM.Reflection; +using IKVM.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + struct IkvmReflectionAssemblyMetadata + { + + readonly IIkvmReflectionAssemblySymbol _symbol; + + IndexRangeDictionary _moduleSymbols = new(initialCapacity: 1, maxCapacity: 32); + ReaderWriterLockSlim? _moduleLock; + + /// + /// Initializes a new instance. + /// + /// + /// + public IkvmReflectionAssemblyMetadata(IIkvmReflectionAssemblySymbol symbol) + { + _symbol = symbol ?? throw new ArgumentNullException(nameof(symbol)); + } + + /// + /// Gets or creates the cached for the module. + /// + /// + /// + /// + public IIkvmReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) + { + if (module is null) + throw new ArgumentNullException(nameof(module)); + + // create lock on demand + if (_moduleLock == null) + Interlocked.CompareExchange(ref _moduleLock, new ReaderWriterLockSlim(), null); + + using (_moduleLock.CreateUpgradeableReadLock()) + { + var row = MetadataTokens.GetRowNumber(MetadataTokens.ModuleReferenceHandle(module.MetadataToken)); + if (_moduleSymbols[row] == null) + using (_moduleLock.CreateWriteLock()) + if (module is ModuleBuilder builder) + return _moduleSymbols[row] = new IkvmReflectionModuleSymbolBuilder(_symbol.Context, _symbol, builder); + else + return _moduleSymbols[row] = new IkvmReflectionModuleSymbol(_symbol.Context, _symbol, module); + else + return _moduleSymbols[row] ?? throw new InvalidOperationException(); + } + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs new file mode 100644 index 000000000..eb728f551 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs @@ -0,0 +1,162 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using IKVM.CoreLib.Symbols.IkvmReflection.Emit; +using IKVM.Reflection; +using IKVM.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + class IkvmReflectionAssemblySymbol : IkvmReflectionSymbol, IIkvmReflectionAssemblySymbol + { + + readonly Assembly _assembly; + IkvmReflectionAssemblyMetadata _impl; + + /// + /// Initializes a new instance. + /// + /// + /// + public IkvmReflectionAssemblySymbol(IkvmReflectionSymbolContext context, Assembly assembly) : + base(context) + { + _assembly = assembly ?? throw new ArgumentNullException(nameof(assembly)); + _impl = new IkvmReflectionAssemblyMetadata(this); + } + + /// + /// Gets the underlying instance. + /// + public Assembly UnderlyingAssembly => _assembly; + + #region IAssemblySymbol + + /// + public IEnumerable DefinedTypes => ResolveTypeSymbols(_assembly.DefinedTypes); + + /// + public IMethodSymbol? EntryPoint => ResolveMethodSymbol(_assembly.EntryPoint); + + /// + public IEnumerable ExportedTypes => ResolveTypeSymbols(_assembly.ExportedTypes); + + /// + public string? FullName => _assembly.FullName; + + /// + public string ImageRuntimeVersion => _assembly.ImageRuntimeVersion; + + /// + public IModuleSymbol ManifestModule => ResolveModuleSymbol(_assembly.ManifestModule); + + /// + public IEnumerable Modules => ResolveModuleSymbols(_assembly.Modules); + + /// + public ITypeSymbol[] GetExportedTypes() + { + return ResolveTypeSymbols(_assembly.GetExportedTypes()); + } + + /// + public IModuleSymbol? GetModule(string name) + { + return ResolveModuleSymbol(_assembly.GetModule(name)); + } + + /// + public IModuleSymbol[] GetModules() + { + return ResolveModuleSymbols(_assembly.GetModules()); + } + + /// + public IModuleSymbol[] GetModules(bool getResourceModules) + { + return ResolveModuleSymbols(_assembly.GetModules(getResourceModules)); + } + + /// + public System.Reflection.AssemblyName GetName() + { + return _assembly.GetName().ToAssemblyName(); + } + + /// + public System.Reflection.AssemblyName GetName(bool copiedName) + { + return _assembly.GetName().ToAssemblyName(); + } + + /// + public System.Reflection.AssemblyName[] GetReferencedAssemblies() + { + return _assembly.GetReferencedAssemblies().ToAssemblyNames(); + } + + /// + public ITypeSymbol? GetType(string name, bool throwOnError) + { + return ResolveTypeSymbol(_assembly.GetType(name, throwOnError)); + } + + /// + public ITypeSymbol? GetType(string name, bool throwOnError, bool ignoreCase) + { + return ResolveTypeSymbol(_assembly.GetType(name, throwOnError, ignoreCase)); + } + + /// + public ITypeSymbol? GetType(string name) + { + return ResolveTypeSymbol(_assembly.GetType(name)); + } + + /// + public ITypeSymbol[] GetTypes() + { + return ResolveTypeSymbols(_assembly.GetTypes()); + } + + /// + public CustomAttribute[] GetCustomAttributes(bool inherit = false) + { + return ResolveCustomAttributes(_assembly.GetCustomAttributesData()); + } + + /// + public CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) + { + return ResolveCustomAttributes(_assembly.__GetCustomAttributes(attributeType.Unpack(), inherit)); + } + + /// + public CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) + { + return ResolveCustomAttribute(_assembly.__GetCustomAttributes(attributeType.Unpack(), inherit).FirstOrDefault()); + } + + /// + public bool IsDefined(ITypeSymbol attributeType, bool inherit = false) + { + return _assembly.IsDefined(attributeType.Unpack(), inherit); + } + + #endregion + + public IIkvmReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) + { + return _impl.GetOrCreateModuleSymbol(module); + } + + public IIkvmReflectionModuleSymbolBuilder GetOrCreateModuleSymbol(ModuleBuilder module) + { + return (IIkvmReflectionModuleSymbolBuilder)_impl.GetOrCreateModuleSymbol(module); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionConstructorSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionConstructorSymbol.cs new file mode 100644 index 000000000..10d812f16 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionConstructorSymbol.cs @@ -0,0 +1,34 @@ +using System; + +using IKVM.Reflection; + +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + class IkvmReflectionConstructorSymbol : IkvmReflectionMethodBaseSymbol, IIkvmReflectionConstructorSymbol + { + + readonly ConstructorInfo _ctor; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + public IkvmReflectionConstructorSymbol(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol resolvingModule, IIkvmReflectionTypeSymbol resolvingType, ConstructorInfo ctor) : + base(context, resolvingModule, resolvingType) + { + _ctor = ctor ?? throw new ArgumentNullException(nameof(ctor)); + } + + /// + public ConstructorInfo UnderlyingConstructor => _ctor; + + /// + public override MethodBase UnderlyingMethodBase => UnderlyingConstructor; + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionEventSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionEventSymbol.cs new file mode 100644 index 000000000..ce1e1f497 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionEventSymbol.cs @@ -0,0 +1,104 @@ +using System; + +using IKVM.Reflection; + +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + class IkvmReflectionEventSymbol : IkvmReflectionMemberSymbol, IIkvmReflectionEventSymbol + { + + readonly EventInfo _event; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + public IkvmReflectionEventSymbol(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol resolvingModule, IIkvmReflectionTypeSymbol resolvingType, EventInfo @event) : + base(context, resolvingModule, resolvingType) + { + _event = @event ?? throw new ArgumentNullException(nameof(@event)); + } + + /// + public EventInfo UnderlyingEvent => _event; + + /// + public override MemberInfo UnderlyingMember => UnderlyingEvent; + + #region IEventSymbol + + /// + public System.Reflection.EventAttributes Attributes => (System.Reflection.EventAttributes)UnderlyingEvent.Attributes; + + /// + public ITypeSymbol? EventHandlerType => ResolveTypeSymbol(UnderlyingEvent.EventHandlerType); + + /// + public bool IsSpecialName => UnderlyingEvent.IsSpecialName; + + /// + public IMethodSymbol? AddMethod => ResolveMethodSymbol(UnderlyingEvent.AddMethod); + + /// + public IMethodSymbol? RemoveMethod => ResolveMethodSymbol(UnderlyingEvent.RemoveMethod); + + /// + public IMethodSymbol? RaiseMethod => ResolveMethodSymbol(UnderlyingEvent.RaiseMethod); + + /// + public IMethodSymbol? GetAddMethod() + { + return ResolveMethodSymbol(UnderlyingEvent.GetAddMethod()); + } + + /// + public IMethodSymbol? GetAddMethod(bool nonPublic) + { + return ResolveMethodSymbol(UnderlyingEvent.GetAddMethod(nonPublic)); + } + + /// + public IMethodSymbol? GetRemoveMethod() + { + return ResolveMethodSymbol(UnderlyingEvent.GetRemoveMethod()); + } + + /// + public IMethodSymbol? GetRemoveMethod(bool nonPublic) + { + return ResolveMethodSymbol(UnderlyingEvent.GetRemoveMethod(nonPublic)); + } + + /// + public IMethodSymbol? GetRaiseMethod() + { + return ResolveMethodSymbol(UnderlyingEvent.GetRaiseMethod()); + } + + /// + public IMethodSymbol? GetRaiseMethod(bool nonPublic) + { + return ResolveMethodSymbol(UnderlyingEvent.GetRaiseMethod(nonPublic)); + } + + /// + public IMethodSymbol[] GetOtherMethods() + { + return ResolveMethodSymbols(UnderlyingEvent.GetOtherMethods()); + } + + /// + public IMethodSymbol[] GetOtherMethods(bool nonPublic) + { + return ResolveMethodSymbols(UnderlyingEvent.GetOtherMethods(nonPublic)); + } + + #endregion + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionFieldSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionFieldSymbol.cs new file mode 100644 index 000000000..bd7c50578 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionFieldSymbol.cs @@ -0,0 +1,98 @@ +using System; + +using IKVM.Reflection; + +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + class IkvmReflectionFieldSymbol : IkvmReflectionMemberSymbol, IIkvmReflectionFieldSymbol + { + + readonly FieldInfo _field; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + public IkvmReflectionFieldSymbol(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol resolvingModule, IIkvmReflectionTypeSymbol? resolvingType, FieldInfo field) : + base(context, resolvingModule, resolvingType) + { + _field = field ?? throw new ArgumentNullException(nameof(field)); + } + + /// + public FieldInfo UnderlyingField => _field; + + /// + public override MemberInfo UnderlyingMember => UnderlyingField; + + #region IFieldSymbol + + /// + public System.Reflection.FieldAttributes Attributes => (System.Reflection.FieldAttributes)UnderlyingField.Attributes; + + /// + public ITypeSymbol FieldType => ResolveTypeSymbol(UnderlyingField.FieldType); + + /// + public bool IsSpecialName => UnderlyingField.IsSpecialName; + + /// + public bool IsAssembly => UnderlyingField.IsAssembly; + + /// + public bool IsFamily => UnderlyingField.IsFamily; + + /// + public bool IsFamilyAndAssembly => UnderlyingField.IsFamilyAndAssembly; + + /// + public bool IsFamilyOrAssembly => UnderlyingField.IsFamilyOrAssembly; + + /// + public bool IsInitOnly => UnderlyingField.IsInitOnly; + + /// + public bool IsLiteral => UnderlyingField.IsLiteral; + + /// + public bool IsNotSerialized => UnderlyingField.IsNotSerialized; + + /// + public bool IsPinvokeImpl => UnderlyingField.IsPinvokeImpl; + + /// + public bool IsPrivate => UnderlyingField.IsPrivate; + + /// + public bool IsPublic => UnderlyingField.IsPublic; + + /// + public bool IsStatic => UnderlyingField.IsStatic; + + /// + public ITypeSymbol[] GetOptionalCustomModifiers() + { + return ResolveTypeSymbols(UnderlyingField.GetOptionalCustomModifiers()); + } + + /// + public ITypeSymbol[] GetRequiredCustomModifiers() + { + return ResolveTypeSymbols(UnderlyingField.GetRequiredCustomModifiers()); + } + + /// + public object? GetRawConstantValue() + { + return UnderlyingField.GetRawConstantValue(); + } + + #endregion + + } + +} \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionGenericTypeParameterSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionGenericTypeParameterSymbol.cs new file mode 100644 index 000000000..a685c97dc --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionGenericTypeParameterSymbol.cs @@ -0,0 +1,566 @@ +using System; +using System.Diagnostics.CodeAnalysis; + +using IKVM.Reflection; + +using Type = IKVM.Reflection.Type; + +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + class IkvmReflectionGenericTypeParameterSymbol : IkvmReflectionMemberSymbol, IIkvmReflectionTypeSymbol + { + + readonly IIkvmReflectionMethodSymbol? _resolvingMethod; + readonly Type _type; + IkvmReflectionTypeImpl _impl; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + /// + /// + public IkvmReflectionGenericTypeParameterSymbol(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol resolvingModule, IIkvmReflectionTypeSymbol? resolvingType, IIkvmReflectionMethodSymbol? resolvingMethod, Type type) : + base(context, resolvingModule, resolvingType) + { + _resolvingMethod = resolvingMethod; + _type = type ?? throw new ArgumentNullException(nameof(type)); + _impl = new IkvmReflectionTypeImpl(this); + } + + /// + public Type UnderlyingType => _type; + + /// + public override MemberInfo UnderlyingMember => UnderlyingType; + + /// + /// Gets the method base that declares this type parameter. + /// + public IIkvmReflectionMethodBaseSymbol? ResolvingMethodBase => _resolvingMethod; + + #region ITypeSymbol + + /// + public System.Reflection.TypeAttributes Attributes => _impl.Attributes; + + /// + public IAssemblySymbol Assembly => _impl.Assembly; + + /// + public IMethodBaseSymbol? DeclaringMethod => _impl.DeclaringMethod; + + /// + public string? AssemblyQualifiedName => _impl.AssemblyQualifiedName; + + /// + public string? FullName => _impl.FullName; + + /// + public string? Namespace => _impl.Namespace; + + /// + public TypeCode TypeCode => _impl.TypeCode; + + /// + public ITypeSymbol? BaseType => _impl.BaseType; + + /// + public bool ContainsGenericParameters => _impl.ContainsGenericParameters; + + /// + public System.Reflection.GenericParameterAttributes GenericParameterAttributes => _impl.GenericParameterAttributes; + + /// + public int GenericParameterPosition => _impl.GenericParameterPosition; + + /// + public ITypeSymbol[] GenericTypeArguments => _impl.GenericTypeArguments; + + /// + public bool IsConstructedGenericType => _impl.IsConstructedGenericType; + + /// + public bool IsGenericType => _impl.IsGenericType; + + /// + public bool IsGenericTypeDefinition => _impl.IsGenericTypeDefinition; + + /// + public bool IsGenericParameter => _impl.IsGenericParameter; + + /// + public bool IsAutoLayout => _impl.IsAutoLayout; + + /// + public bool IsExplicitLayout => _impl.IsExplicitLayout; + + /// + public bool IsLayoutSequential => _impl.IsLayoutSequential; + + /// + public bool HasElementType => _impl.HasElementType; + + /// + public bool IsClass => _impl.IsClass; + + /// + public bool IsValueType => _impl.IsValueType; + + /// + public bool IsInterface => _impl.IsInterface; + + /// + public bool IsPrimitive => _impl.IsPrimitive; + + /// + public bool IsSZArray => _impl.IsSZArray; + + /// + public bool IsArray => _impl.IsArray; + + /// + public bool IsEnum => _impl.IsEnum; + + /// + public bool IsPointer => _impl.IsPointer; + + /// + public bool IsFunctionPointer => _impl.IsFunctionPointer; + + /// + public bool IsUnmanagedFunctionPointer => _impl.IsUnmanagedFunctionPointer; + + /// + public bool IsByRef => _impl.IsByRef; + + /// + public bool IsAbstract => _impl.IsAbstract; + + /// + public bool IsSealed => _impl.IsSealed; + + /// + public bool IsVisible => _impl.IsVisible; + + /// + public bool IsPublic => _impl.IsPublic; + + /// + public bool IsNotPublic => _impl.IsNotPublic; + + /// + public bool IsNested => _impl.IsNested; + + /// + public bool IsNestedAssembly => _impl.IsNestedAssembly; + + /// + public bool IsNestedFamANDAssem => _impl.IsNestedFamANDAssem; + + /// + public bool IsNestedFamily => _impl.IsNestedFamily; + + /// + public bool IsNestedFamORAssem => _impl.IsNestedFamORAssem; + + /// + public bool IsNestedPrivate => _impl.IsNestedPrivate; + + /// + public bool IsNestedPublic => _impl.IsNestedPublic; + + /// + public bool IsSerializable => _impl.IsSerializable; + + /// + public bool IsSignatureType => _impl.IsSignatureType; + + /// + public bool IsSpecialName => _impl.IsSpecialName; + + /// + public IConstructorSymbol? TypeInitializer => throw new NotImplementedException(); + + /// + public int GetArrayRank() + { + return _impl.GetArrayRank(); + } + + /// + public IMemberSymbol[] GetDefaultMembers() + { + return _impl.GetDefaultMembers(); + } + + /// + public ITypeSymbol? GetElementType() + { + return _impl.GetElementType(); + } + + /// + public string? GetEnumName(object value) + { + return _impl.GetEnumName(value); + } + + /// + public string[] GetEnumNames() + { + return _impl.GetEnumNames(); + } + + /// + public ITypeSymbol GetEnumUnderlyingType() + { + return _impl.GetEnumUnderlyingType(); + } + + /// + public ITypeSymbol[] GetGenericArguments() + { + return _impl.GetGenericArguments(); + } + + /// + public ITypeSymbol[] GetGenericParameterConstraints() + { + return _impl.GetGenericParameterConstraints(); + } + + /// + public ITypeSymbol GetGenericTypeDefinition() + { + return _impl.GetGenericTypeDefinition(); + } + + /// + public ITypeSymbol? GetInterface(string name) + { + return _impl.GetInterface(name); + } + + /// + public ITypeSymbol? GetInterface(string name, bool ignoreCase) + { + return _impl.GetInterface(name, ignoreCase); + } + + /// + public ITypeSymbol[] GetInterfaces(bool inherit = true) + { + return _impl.GetInterfaces(inherit); + } + + /// + public InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) + { + return _impl.GetInterfaceMap(interfaceType); + } + + /// + public IMemberSymbol[] GetMember(string name) + { + return _impl.GetMember(name); + } + + /// + public IMemberSymbol[] GetMember(string name, System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetMember(name, bindingAttr); + } + + /// + public IMemberSymbol[] GetMember(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetMember(name, type, bindingAttr); + } + + /// + public IMemberSymbol[] GetMembers() + { + return _impl.GetMembers(); + } + + /// + public IMemberSymbol[] GetMembers(System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetMembers(bindingAttr); + } + + public IConstructorSymbol? GetConstructor(ITypeSymbol[] types) + { + return _impl.GetConstructor(types); + } + + /// + public IConstructorSymbol? GetConstructor(System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) + { + return _impl.GetConstructor(bindingAttr, types); + } + + /// + public IConstructorSymbol[] GetConstructors() + { + return _impl.GetConstructors(); + } + + /// + public IConstructorSymbol[] GetConstructors(System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetConstructors(bindingAttr); + } + + /// + public IFieldSymbol? GetField(string name) + { + return _impl.GetField(name); + } + + /// + public IFieldSymbol? GetField(string name, System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetField(name, bindingAttr); + } + + /// + public IFieldSymbol[] GetFields() + { + return _impl.GetFields(); + } + + /// + public IFieldSymbol[] GetFields(System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetFields(bindingAttr); + } + + /// + public IMethodSymbol? GetMethod(string name) + { + return _impl.GetMethod(name); + } + + /// + public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) + { + return _impl.GetMethod(name, types); + } + + /// + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetMethod(name, bindingAttr); + } + + /// + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) + { + return _impl.GetMethod(name, bindingAttr, types); + } + + /// + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + { + return _impl.GetMethod(name, bindingAttr, callConvention, types, modifiers); + } + + /// + public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + { + return _impl.GetMethod(name, genericParameterCount, bindingAttr, callConvention, types, modifiers); + } + + /// + public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + { + return _impl.GetMethod(name, genericParameterCount, bindingAttr, types, modifiers); + } + + /// + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + { + return _impl.GetMethod(name, bindingAttr, types, modifiers); + } + + /// + public IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + { + return _impl.GetMethod(name, genericParameterCount, types, modifiers); + } + + /// + public IMethodSymbol[] GetMethods() + { + return _impl.GetMethods(); + } + + /// + public IMethodSymbol[] GetMethods(System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetMethods(bindingAttr); + } + + /// + public IPropertySymbol? GetProperty(string name) + { + return _impl.GetProperty(name); + } + + /// + public IPropertySymbol? GetProperty(string name, System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetProperty(name, bindingAttr); + } + + /// + public IPropertySymbol? GetProperty(string name, ITypeSymbol[] types) + { + return _impl.GetProperty(name, types); + } + + /// + public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types) + { + return _impl.GetProperty(name, returnType, types); + } + + /// + public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) + { + return _impl.GetProperty(name, returnType); + } + + /// + public IPropertySymbol[] GetProperties() + { + return _impl.GetProperties(); + } + + /// + public IPropertySymbol[] GetProperties(System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetProperties(bindingAttr); + } + + /// + public IEventSymbol? GetEvent(string name) + { + return _impl.GetEvent(name); + } + + /// + public IEventSymbol? GetEvent(string name, System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetEvent(name, bindingAttr); + } + + /// + public IEventSymbol[] GetEvents() + { + return _impl.GetEvents(); + } + + /// + public IEventSymbol[] GetEvents(System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetEvents(bindingAttr); + } + + /// + public ITypeSymbol? GetNestedType(string name) + { + return _impl.GetNestedType(name); + } + + /// + public ITypeSymbol? GetNestedType(string name, System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetNestedType(name, bindingAttr); + } + + /// + public ITypeSymbol[] GetNestedTypes() + { + return _impl.GetNestedTypes(); + } + + /// + public ITypeSymbol[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetNestedTypes(); + } + + /// + public bool IsAssignableFrom(ITypeSymbol? c) + { + return _impl.IsAssignableFrom(c); + } + + /// + public bool IsSubclassOf(ITypeSymbol c) + { + return _impl.IsSubclassOf(c); + } + + /// + public bool IsEnumDefined(object value) + { + return _impl.IsEnumDefined(value); + } + + /// + public ITypeSymbol MakeArrayType() + { + return _impl.MakeArrayType(); + } + + /// + public ITypeSymbol MakeArrayType(int rank) + { + return _impl.MakeArrayType(rank); + } + + /// + public ITypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments) + { + return _impl.MakeGenericType(typeArguments); + } + + /// + public ITypeSymbol MakePointerType() + { + return _impl.MakePointerType(); + } + + /// + public ITypeSymbol MakeByRefType() + { + return _impl.MakeByRefType(); + } + + #endregion + + /// + /// Resolves the symbol for the specified type. + /// + /// + /// + [return: NotNullIfNotNull(nameof(type))] + public override IIkvmReflectionTypeSymbol? ResolveTypeSymbol(Type? type) + { + if (type == _type) + return this; + else + return base.ResolveTypeSymbol(type); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs new file mode 100644 index 000000000..22ed03a6c --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs @@ -0,0 +1,286 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; + +using IKVM.CoreLib.Symbols.IkvmReflection.Emit; +using IKVM.Reflection; +using IKVM.Reflection.Emit; + +using Type = IKVM.Reflection.Type; + +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + /// + /// Obtains information about the attributes of a member and provides access to member metadata. + /// + abstract class IkvmReflectionMemberSymbol : IkvmReflectionSymbol, IIkvmReflectionMemberSymbol + { + + readonly IIkvmReflectionModuleSymbol _resolvingModule; + readonly IIkvmReflectionTypeSymbol? _resolvingType; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + public IkvmReflectionMemberSymbol(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol resolvingModule, IIkvmReflectionTypeSymbol? resolvingType) : + base(context) + { + _resolvingModule = resolvingModule ?? throw new ArgumentNullException(nameof(resolvingModule)); + _resolvingType = resolvingType; + } + + /// + public abstract MemberInfo UnderlyingMember { get; } + + /// + /// Gets the which contains the metadata of this member. + /// + public IIkvmReflectionModuleSymbol ResolvingModule => _resolvingModule; + + /// + /// Gets the which contains the metadata of this member, or null if the member is not a member of a type. + /// + public IIkvmReflectionTypeSymbol? ResolvingType => _resolvingType; + + #region IMemberSymbol + + /// + public virtual IModuleSymbol Module => ResolveModuleSymbol(UnderlyingMember.Module)!; + + /// + public virtual ITypeSymbol? DeclaringType => ResolveTypeSymbol(UnderlyingMember.DeclaringType)!; + + /// + public virtual System.Reflection.MemberTypes MemberType => (System.Reflection.MemberTypes)UnderlyingMember.MemberType; + + /// + public virtual int MetadataToken => UnderlyingMember.MetadataToken; + + /// + public virtual string Name => UnderlyingMember.Name; + + /// + public virtual CustomAttribute[] GetCustomAttributes(bool inherit = false) + { + return ResolveCustomAttributes(UnderlyingMember.__GetCustomAttributes(null, inherit))!; + } + + /// + public virtual CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) + { + return ResolveCustomAttributes(UnderlyingMember.__GetCustomAttributes(attributeType.Unpack(), inherit)); + } + + /// + public virtual CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) + { + return ResolveCustomAttribute(UnderlyingMember.__GetCustomAttributes(attributeType.Unpack(), inherit).FirstOrDefault()); + } + + /// + public virtual bool IsDefined(ITypeSymbol attributeType, bool inherit = false) + { + return UnderlyingMember.IsDefined(attributeType.Unpack(), inherit); + } + + #endregion + + /// + [return: NotNullIfNotNull(nameof(type))] + public override IIkvmReflectionTypeSymbol? ResolveTypeSymbol(Type? type) + { + if (type is null) + return null; + + if (type == UnderlyingMember) + return (IIkvmReflectionTypeSymbol)this; + + if (_resolvingType != null && type == _resolvingType.UnderlyingType) + return _resolvingType; + + if (type.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateTypeSymbol(type); + + return base.ResolveTypeSymbol(type); + } + + /// + [return: NotNullIfNotNull(nameof(ctor))] + public override IIkvmReflectionConstructorSymbol? ResolveConstructorSymbol(ConstructorInfo? ctor) + { + if (ctor is null) + return null; + + if (ctor == UnderlyingMember) + return (IIkvmReflectionConstructorSymbol)this; + + if (ctor.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateConstructorSymbol(ctor); + + return base.ResolveConstructorSymbol(ctor); + } + + /// + [return: NotNullIfNotNull(nameof(ctor))] + public override IIkvmReflectionConstructorSymbolBuilder ResolveConstructorSymbol(ConstructorBuilder ctor) + { + if (ctor is null) + throw new ArgumentNullException(nameof(ctor)); + + if (ctor.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateConstructorSymbol(ctor); + + return base.ResolveConstructorSymbol(ctor); + } + + /// + [return: NotNullIfNotNull(nameof(method))] + public override IIkvmReflectionMethodSymbol? ResolveMethodSymbol(MethodInfo? method) + { + if (method is null) + return null; + + if (method == UnderlyingMember) + return (IIkvmReflectionMethodSymbol)this; + + if (method.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateMethodSymbol(method); + + return base.ResolveMethodSymbol(method); + } + + /// + [return: NotNullIfNotNull(nameof(method))] + public override IIkvmReflectionMethodSymbolBuilder ResolveMethodSymbol(MethodBuilder method) + { + if (method is null) + throw new ArgumentNullException(nameof(method)); + + if (method.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateMethodSymbol(method); + + return base.ResolveMethodSymbol(method); + } + + /// + [return: NotNullIfNotNull(nameof(field))] + public override IIkvmReflectionFieldSymbol? ResolveFieldSymbol(FieldInfo? field) + { + if (field is null) + return null; + + if (field == UnderlyingMember) + return (IIkvmReflectionFieldSymbol)this; + + if (field.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateFieldSymbol(field); + + return base.ResolveFieldSymbol(field); + } + + /// + [return: NotNullIfNotNull(nameof(field))] + public override IIkvmReflectionFieldSymbolBuilder ResolveFieldSymbol(FieldBuilder field) + { + if (field is null) + throw new ArgumentNullException(nameof(field)); + + if (field.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateFieldSymbol(field); + + return base.ResolveFieldSymbol(field); + } + + /// + [return: NotNullIfNotNull(nameof(property))] + public override IIkvmReflectionPropertySymbol? ResolvePropertySymbol(PropertyInfo? property) + { + if (property is null) + return null; + + if (property == UnderlyingMember) + return (IIkvmReflectionPropertySymbol)this; + + if (property.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreatePropertySymbol(property); + + return base.ResolvePropertySymbol(property); + } + + /// + [return: NotNullIfNotNull(nameof(property))] + public override IIkvmReflectionPropertySymbolBuilder ResolvePropertySymbol(PropertyBuilder property) + { + if (property is null) + throw new ArgumentNullException(nameof(property)); + + if (property.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreatePropertySymbol(property); + + return base.ResolvePropertySymbol(property); + } + + /// + [return: NotNullIfNotNull(nameof(@event))] + public override IIkvmReflectionEventSymbol? ResolveEventSymbol(EventInfo? @event) + { + if (@event is null) + return null; + + if (@event == UnderlyingMember) + return (IIkvmReflectionEventSymbol)this; + + if (@event.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateEventSymbol(@event); + + return base.ResolveEventSymbol(@event); + } + + /// + [return: NotNullIfNotNull(nameof(@event))] + public override IIkvmReflectionEventSymbolBuilder ResolveEventSymbol(EventBuilder @event) + { + if (@event is null) + throw new ArgumentNullException(nameof(@event)); + + if (@event.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateEventSymbol(@event); + + return base.ResolveEventSymbol(@event); + } + + /// + [return: NotNullIfNotNull(nameof(parameter))] + public override IIkvmReflectionParameterSymbol? ResolveParameterSymbol(ParameterInfo? parameter) + { + if (parameter is null) + throw new ArgumentNullException(nameof(parameter)); + + if (parameter.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateParameterSymbol(parameter); + + return base.ResolveParameterSymbol(parameter); + } + + /// + [return: NotNullIfNotNull(nameof(parameter))] + public override IIkvmReflectionParameterSymbolBuilder ResolveParameterSymbol(ParameterBuilder parameter) + { + if (parameter is null) + throw new ArgumentNullException(nameof(parameter)); + + if (parameter.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateParameterSymbol(parameter); + + return base.ResolveParameterSymbol(parameter); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodBaseSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodBaseSymbol.cs new file mode 100644 index 000000000..3e5a0a836 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodBaseSymbol.cs @@ -0,0 +1,108 @@ +using IKVM.Reflection; + +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + abstract class IkvmReflectionMethodBaseSymbol : IkvmReflectionMemberSymbol, IIkvmReflectionMethodBaseSymbol + { + + /// + /// Initializes a new instance. + /// + /// + /// + /// + public IkvmReflectionMethodBaseSymbol(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol resolvingModule, IIkvmReflectionTypeSymbol? resolvingType) : + base(context, resolvingModule, resolvingType) + { + + } + + #region IMethodBaseSymbol + + /// + public abstract MethodBase UnderlyingMethodBase { get; } + + /// + public override MemberInfo UnderlyingMember => UnderlyingMethodBase; + + /// + public System.Reflection.MethodAttributes Attributes => (System.Reflection.MethodAttributes)UnderlyingMethodBase.Attributes; + + /// + public System.Reflection.CallingConventions CallingConvention => (System.Reflection.CallingConventions)UnderlyingMethodBase.CallingConvention; + + /// + public bool ContainsGenericParameters => UnderlyingMethodBase.ContainsGenericParameters; + + /// + public bool IsAbstract => UnderlyingMethodBase.IsAbstract; + + /// + public bool IsAssembly => UnderlyingMethodBase.IsAssembly; + + /// + public bool IsConstructor => UnderlyingMethodBase.IsConstructor; + + /// + public bool IsFamily => UnderlyingMethodBase.IsFamily; + + /// + public bool IsFamilyAndAssembly => UnderlyingMethodBase.IsFamilyAndAssembly; + + /// + public bool IsFamilyOrAssembly => UnderlyingMethodBase.IsFamilyOrAssembly; + + /// + public bool IsFinal => UnderlyingMethodBase.IsFinal; + + /// + public bool IsGenericMethod => UnderlyingMethodBase.IsGenericMethod; + + /// + public bool IsGenericMethodDefinition => UnderlyingMethodBase.IsGenericMethodDefinition; + + /// + public bool IsHideBySig => UnderlyingMethodBase.IsHideBySig; + + /// + public bool IsPrivate => UnderlyingMethodBase.IsPrivate; + + /// + public bool IsPublic => UnderlyingMethodBase.IsPublic; + + /// + public bool IsStatic => UnderlyingMethodBase.IsStatic; + + /// + public bool IsVirtual => UnderlyingMethodBase.IsVirtual; + + /// + public bool IsSpecialName => UnderlyingMethodBase.IsSpecialName; + + /// + public System.Reflection.MethodImplAttributes MethodImplementationFlags => (System.Reflection.MethodImplAttributes)UnderlyingMethodBase.MethodImplementationFlags; + + /// + public ITypeSymbol[] GetGenericArguments() + { + return ResolveTypeSymbols(UnderlyingMethodBase.GetGenericArguments()); + } + + /// + public System.Reflection.MethodImplAttributes GetMethodImplementationFlags() + { + return (System.Reflection.MethodImplAttributes)UnderlyingMethodBase.GetMethodImplementationFlags(); + } + + /// + public IParameterSymbol[] GetParameters() + { + return ResolveParameterSymbols(UnderlyingMethodBase.GetParameters()); + } + + #endregion + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodSymbol.cs new file mode 100644 index 000000000..54dc46ff7 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodSymbol.cs @@ -0,0 +1,65 @@ +using System; + +using IKVM.Reflection; + +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + class IkvmReflectionMethodSymbol : IkvmReflectionMethodBaseSymbol, IIkvmReflectionMethodSymbol + { + + readonly MethodInfo _method; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + public IkvmReflectionMethodSymbol(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol module, IIkvmReflectionTypeSymbol? type, MethodInfo method) : + base(context, module, type) + { + _method = method ?? throw new ArgumentNullException(nameof(method)); + } + + /// + public MethodInfo UnderlyingMethod => _method; + + /// + public override MethodBase UnderlyingMethodBase => UnderlyingMethod; + + #region IMethodSymbol + + /// + public IParameterSymbol ReturnParameter => ResolveParameterSymbol(UnderlyingMethod.ReturnParameter); + + /// + public ITypeSymbol ReturnType => ResolveTypeSymbol(UnderlyingMethod.ReturnType); + + /// + public ICustomAttributeProvider ReturnTypeCustomAttributes => throw new NotImplementedException(); + + /// + public IMethodSymbol GetBaseDefinition() + { + return ResolveMethodSymbol(UnderlyingMethod.GetBaseDefinition()); + } + + /// + public IMethodSymbol GetGenericMethodDefinition() + { + return ResolveMethodSymbol(UnderlyingMethod.GetGenericMethodDefinition()); + } + + /// + public IMethodSymbol MakeGenericMethod(params ITypeSymbol[] typeArguments) + { + return ResolveMethodSymbol(UnderlyingMethod.MakeGenericMethod(typeArguments.Unpack())); + } + + #endregion + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleMetadata.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleMetadata.cs new file mode 100644 index 000000000..1d9b0a3e2 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleMetadata.cs @@ -0,0 +1,480 @@ +using System; +using System.Reflection.Metadata.Ecma335; +using System.Threading; + +using IKVM.CoreLib.Collections; +using IKVM.CoreLib.Symbols.IkvmReflection.Emit; +using IKVM.CoreLib.Threading; +using IKVM.Reflection; +using IKVM.Reflection.Emit; + +using Type = IKVM.Reflection.Type; + +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + /// + /// Provides the metadata resolution implementation for a module. + /// + struct IkvmReflectionModuleMetadata + { + + /// + /// Returns true if the given is a TypeDef. That is, not a modified or substituted or generic parameter type. + /// + /// + /// + static bool IsTypeDefinition(Type type) + { + return type.HasElementType == false && type.IsConstructedGenericType == false && type.IsGenericParameter == false; + } + + const int MAX_CAPACITY = 65536 * 2; + + readonly IIkvmReflectionModuleSymbol _symbol; + + IndexRangeDictionary _typeSymbols = new(maxCapacity: MAX_CAPACITY); + ReaderWriterLockSlim? _typeLock; + + IndexRangeDictionary _methodSymbols = new(maxCapacity: MAX_CAPACITY); + ReaderWriterLockSlim? _methodLock; + + IndexRangeDictionary _fieldSymbols = new(maxCapacity: MAX_CAPACITY); + ReaderWriterLockSlim? _fieldLock; + + IndexRangeDictionary _propertySymbols = new(maxCapacity: MAX_CAPACITY); + ReaderWriterLockSlim? _propertyLock; + + IndexRangeDictionary _eventSymbols = new(maxCapacity: MAX_CAPACITY); + ReaderWriterLockSlim? _eventLock; + + IndexRangeDictionary _parameterSymbols = new(maxCapacity: MAX_CAPACITY); + ReaderWriterLockSlim? _parameterLock; + + IndexRangeDictionary _genericParameterSymbols = new(maxCapacity: MAX_CAPACITY); + ReaderWriterLockSlim? _genericParameterLock; + + /// + /// Initializes a new instance. + /// + /// + /// + public IkvmReflectionModuleMetadata(IIkvmReflectionModuleSymbol symbol) + { + _symbol = symbol ?? throw new ArgumentNullException(nameof(symbol)); + } + + /// + /// Gets or creates the cached for the module by type. + /// + /// + /// + public IIkvmReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) + { + if (type is null) + throw new ArgumentNullException(nameof(type)); + if (type.Module.MetadataToken != _symbol.MetadataToken) + throw new ArgumentException(nameof(type)); + + // type is a generic parameter (GenericParam) + if (type.IsGenericParameter) + return GetOrCreateGenericTypeParameterSymbol(type); + + // type is not a type definition (TypeDef) + if (IsTypeDefinition(type) == false) + return GetOrCreateTypeSymbolForSpecification(type); + + // create lock on demand + if (_typeLock == null) + Interlocked.CompareExchange(ref _typeLock, new ReaderWriterLockSlim(), null); + + using (_typeLock.CreateUpgradeableReadLock()) + { + var row = MetadataTokens.GetRowNumber(MetadataTokens.TypeDefinitionHandle(type.MetadataToken)); + if (_typeSymbols[row] == null) + using (_typeLock.CreateWriteLock()) + if (type is TypeBuilder builder) + return _typeSymbols[row] ??= new IkvmReflectionTypeSymbolBuilder(_symbol.Context, _symbol, builder); + else + return _typeSymbols[row] ??= new IkvmReflectionTypeSymbol(_symbol.Context, _symbol, type); + else + return _typeSymbols[row] ?? throw new InvalidOperationException(); + } + } + + + /// + /// Gets or creates the cached for the module by type. + /// + /// + /// + public IIkvmReflectionTypeSymbolBuilder GetOrCreateTypeSymbol(TypeBuilder type) + { + return (IIkvmReflectionTypeSymbolBuilder)GetOrCreateTypeSymbol((Type)type); + } + + /// + /// Gets or creates a for the specification type: array, pointer, generic, etc. + /// + /// + /// + /// + /// + IIkvmReflectionTypeSymbol GetOrCreateTypeSymbolForSpecification(Type type) + { + if (type is null) + throw new ArgumentNullException(nameof(type)); + if (type.Module.MetadataToken != _symbol.MetadataToken) + throw new ArgumentException(nameof(type)); + + if (type.GetElementType() is { } elementType) + { + var elementTypeSymbol = _symbol.ResolveTypeSymbol(elementType)!; + + // handles both SZ arrays and normal arrays + if (type.IsArray) + return (IIkvmReflectionTypeSymbol)elementTypeSymbol.MakeArrayType(type.GetArrayRank()); + + if (type.IsPointer) + return (IIkvmReflectionTypeSymbol)elementTypeSymbol.MakePointerType(); + + if (type.IsByRef) + return (IIkvmReflectionTypeSymbol)elementTypeSymbol.MakeByRefType(); + + throw new InvalidOperationException(); + } + + if (type.IsGenericType) + { + var definitionTypeSymbol = _symbol.GetOrCreateTypeSymbol(type.GetGenericTypeDefinition()); + return (IIkvmReflectionTypeSymbol)definitionTypeSymbol.MakeGenericType(definitionTypeSymbol.ResolveTypeSymbols(type.GetGenericArguments())!); + } + + throw new InvalidOperationException(); + } + + /// + /// Gets or creates the cached for the type by method. + /// + /// + /// + public IIkvmReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method) + { + if (method is null) + throw new ArgumentNullException(nameof(method)); + if (method.Module.MetadataToken != _symbol.MetadataToken) + throw new ArgumentException(nameof(method)); + + // create lock on demand + if (_methodLock == null) + Interlocked.CompareExchange(ref _methodLock, new ReaderWriterLockSlim(), null); + + using (_methodLock.CreateUpgradeableReadLock()) + { + var row = MetadataTokens.GetRowNumber(MetadataTokens.MethodDefinitionHandle(method.MetadataToken)); + if (_methodSymbols[row] == null) + { + using (_methodLock.CreateWriteLock()) + { + if (method is ConstructorInfo c) + { + if (method is ConstructorBuilder builder) + return _methodSymbols[row] ??= new IkvmReflectionConstructorSymbolBuilder(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(c.DeclaringType!), builder); + else + return _methodSymbols[row] ??= new IkvmReflectionConstructorSymbol(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(c.DeclaringType!), c); + } + else if (method is MethodInfo m) + { + if (method is MethodBuilder builder) + return _methodSymbols[row] ??= new IkvmReflectionMethodSymbolBuilder(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(method.DeclaringType), builder); + else + return _methodSymbols[row] ??= new IkvmReflectionMethodSymbol(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(method.DeclaringType), m); + } + else + { + throw new InvalidOperationException(); + } + } + } + else + { + return _methodSymbols[row] ?? throw new InvalidOperationException(); + } + } + } + + /// + /// Gets or creates the cached for the type by ctor. + /// + /// + /// + public IIkvmReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) + { + return (IIkvmReflectionConstructorSymbol)GetOrCreateMethodBaseSymbol(ctor); + } + + /// + /// Gets or creates the cached for the type by ctor. + /// + /// + /// + public IIkvmReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor) + { + return (IIkvmReflectionConstructorSymbolBuilder)GetOrCreateConstructorSymbol((ConstructorInfo)ctor); + } + + /// + /// Gets or creates the cached for the type by method. + /// + /// + /// + public IIkvmReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) + { + return (IIkvmReflectionMethodSymbol)GetOrCreateMethodBaseSymbol(method); + } + + /// + /// Gets or creates the cached for the type by method. + /// + /// + /// + public IIkvmReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method) + { + return (IIkvmReflectionMethodSymbolBuilder)GetOrCreateMethodBaseSymbol((MethodInfo)method); + } + + /// + /// Gets or creates the cached for the type by field. + /// + /// + /// + public IIkvmReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) + { + if (field is null) + throw new ArgumentNullException(nameof(field)); + if (field.Module.MetadataToken != _symbol.MetadataToken) + throw new ArgumentException(nameof(field)); + + // create lock on demand + if (_fieldLock == null) + Interlocked.CompareExchange(ref _fieldLock, new ReaderWriterLockSlim(), null); + + using (_fieldLock.CreateUpgradeableReadLock()) + { + var row = MetadataTokens.GetRowNumber(MetadataTokens.FieldDefinitionHandle(field.MetadataToken)); + if (_fieldSymbols[row] == null) + using (_fieldLock.CreateWriteLock()) + if (field is FieldBuilder builder) + return _fieldSymbols[row] ??= new IkvmReflectionFieldSymbolBuilder(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(field.DeclaringType), builder); + else + return _fieldSymbols[row] ??= new IkvmReflectionFieldSymbol(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(field.DeclaringType), field); + else + return _fieldSymbols[row] ?? throw new InvalidOperationException(); + } + } + + /// + /// Gets or creates the cached for the type by method. + /// + /// + /// + public IIkvmReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field) + { + return (IIkvmReflectionFieldSymbolBuilder)GetOrCreateFieldSymbol((FieldInfo)field); + } + + /// + /// Gets or creates the cached for the type by property. + /// + /// + /// + public IIkvmReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) + { + if (property is null) + throw new ArgumentNullException(nameof(property)); + if (property.Module.MetadataToken != _symbol.MetadataToken) + throw new ArgumentException(nameof(property)); + + // create lock on demand + if (_propertyLock == null) + Interlocked.CompareExchange(ref _propertyLock, new ReaderWriterLockSlim(), null); + + using (_propertyLock.CreateUpgradeableReadLock()) + { + var row = MetadataTokens.GetRowNumber(MetadataTokens.PropertyDefinitionHandle(property.MetadataToken)); + if (_propertySymbols[row] == null) + using (_propertyLock.CreateWriteLock()) + if (property is PropertyBuilder builder) + return _propertySymbols[row] ??= new IkvmReflectionPropertySymbolBuilder(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(property.DeclaringType!), builder); + else + return _propertySymbols[row] ??= new IkvmReflectionPropertySymbol(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(property.DeclaringType!), property); + else + return _propertySymbols[row] ?? throw new InvalidOperationException(); + } + } + + + /// + /// Gets or creates the cached for the type by property. + /// + /// + /// + public IIkvmReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property) + { + return (IIkvmReflectionPropertySymbolBuilder)GetOrCreatePropertySymbol((PropertyInfo)property); + } + + /// + /// Gets or creates the cached for the type by event. + /// + /// + /// + public IIkvmReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) + { + if (@event is null) + throw new ArgumentNullException(nameof(@event)); + if (@event.Module.MetadataToken != _symbol.MetadataToken) + throw new ArgumentException(nameof(@event)); + + // create lock on demand + if (_eventLock == null) + Interlocked.CompareExchange(ref _eventLock, new ReaderWriterLockSlim(), null); + + using (_eventLock.CreateUpgradeableReadLock()) + { + var row = MetadataTokens.GetRowNumber(MetadataTokens.EventDefinitionHandle(@event.MetadataToken)); + if (_eventSymbols[row] == null) + using (_eventLock.CreateWriteLock()) + return _eventSymbols[row] ??= new IkvmReflectionEventSymbol(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(@event.DeclaringType!), @event); + else + return _eventSymbols[row] ?? throw new InvalidOperationException(); + } + } + + /// + /// Gets or creates the cached for the type by event. + /// + /// + /// + public IIkvmReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event) + { + if (@event is null) + throw new ArgumentNullException(nameof(@event)); + if (@event.Module.MetadataToken != _symbol.MetadataToken) + throw new ArgumentException(nameof(@event)); + + // create lock on demand + if (_eventLock == null) + Interlocked.CompareExchange(ref _eventLock, new ReaderWriterLockSlim(), null); + + using (_eventLock.CreateUpgradeableReadLock()) + { + var row = MetadataTokens.GetRowNumber(MetadataTokens.EventDefinitionHandle(@event.GetEventToken().Token)); + if (_eventSymbols[row] == null) + using (_eventLock.CreateWriteLock()) + return (IIkvmReflectionEventSymbolBuilder)(_eventSymbols[row] ??= new IkvmReflectionEventSymbolBuilder(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(@event.DeclaringType), @event)); + else + return (IIkvmReflectionEventSymbolBuilder?)_eventSymbols[row] ?? throw new InvalidOperationException(); + } + } + + /// + /// Gets or creates the cached for the type by method. + /// + /// + /// + public IIkvmReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) + { + if (parameter is null) + throw new ArgumentNullException(nameof(parameter)); + if (parameter.Member.Module.MetadataToken != _symbol.MetadataToken) + throw new ArgumentException(nameof(parameter)); + + // create lock on demand + if (_parameterLock == null) + Interlocked.CompareExchange(ref _parameterLock, new ReaderWriterLockSlim(), null); + + using (_parameterLock.CreateUpgradeableReadLock()) + { + var position = parameter.Position; + if (_parameterSymbols[position] == null) + using (_parameterLock.CreateWriteLock()) + return _parameterSymbols[position] ??= new IkvmReflectionParameterSymbol(_symbol.Context, _symbol, _symbol.ResolveMethodBaseSymbol((MethodBase)parameter.Member), parameter); + else + return _parameterSymbols[position] ?? throw new InvalidOperationException(); + } + } + + /// + /// Gets or creates the cached for the type by method. + /// + /// + /// + public IIkvmReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter) + { + if (parameter is null) + throw new ArgumentNullException(nameof(parameter)); + if (parameter.Module.MetadataToken != _symbol.MetadataToken) + throw new ArgumentException(nameof(parameter)); + + // create lock on demand + if (_parameterLock == null) + Interlocked.CompareExchange(ref _parameterLock, new ReaderWriterLockSlim(), null); + + using (_parameterLock.CreateUpgradeableReadLock()) + { + var position = parameter.Position; + if (_parameterSymbols[position] == null) + using (_parameterLock.CreateWriteLock()) + return (IIkvmReflectionParameterSymbolBuilder)(_parameterSymbols[position] ??= new IkvmReflectionParameterSymbolBuilder(_symbol.Context, _symbol, _symbol.ResolveMethodSymbol(parameter.Method), parameter)); + else + return (IIkvmReflectionParameterSymbolBuilder?)_parameterSymbols[position] ?? throw new InvalidOperationException(); + } + } + + /// + /// Gets or creates the cached for the module by type. + /// + /// + /// + IIkvmReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type genericParameterType) + { + if (genericParameterType is null) + throw new ArgumentNullException(nameof(genericParameterType)); + if (genericParameterType.Module.MetadataToken != _symbol.MetadataToken) + throw new ArgumentException(nameof(genericParameterType)); + + // create lock on demand + if (_genericParameterLock == null) + Interlocked.CompareExchange(ref _genericParameterLock, new ReaderWriterLockSlim(), null); + + using (_genericParameterLock.CreateUpgradeableReadLock()) + { + var hnd = MetadataTokens.GenericParameterHandle(genericParameterType.MetadataToken); + var row = MetadataTokens.GetRowNumber(hnd); + if (_genericParameterSymbols[row] == null) + using (_genericParameterLock.CreateWriteLock()) + if (genericParameterType is GenericTypeParameterBuilder builder) + return _genericParameterSymbols[row] ??= new IkvmReflectionGenericTypeParameterSymbolBuilder(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(genericParameterType.DeclaringType), _symbol.ResolveMethodSymbol((MethodInfo?)genericParameterType.DeclaringMethod), builder); + else + return _genericParameterSymbols[row] ??= new IkvmReflectionGenericTypeParameterSymbol(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(genericParameterType.DeclaringType), _symbol.ResolveMethodSymbol((MethodInfo?)genericParameterType.DeclaringMethod), genericParameterType); + else + { + return _genericParameterSymbols[row] ?? throw new InvalidOperationException(); + } + } + } + + /// + /// Gets or creates the cached for the module. + /// + /// + /// + IIkvmReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeParameterSymbol(GenericTypeParameterBuilder genericParameterType) + { + return (IIkvmReflectionGenericTypeParameterSymbolBuilder)GetOrCreateGenericTypeParameterSymbol((Type)genericParameterType); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs new file mode 100644 index 000000000..94913c88f --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs @@ -0,0 +1,320 @@ +using System; +using System.Linq; + +using IKVM.CoreLib.Symbols.IkvmReflection.Emit; +using IKVM.Reflection; +using IKVM.Reflection.Emit; + +using Type = IKVM.Reflection.Type; + +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + /// + /// Implementation of derived from System.Reflection. + /// + class IkvmReflectionModuleSymbol : IkvmReflectionSymbol, IIkvmReflectionModuleSymbol + { + + readonly IIkvmReflectionAssemblySymbol _resolvingAssembly; + readonly Module _module; + IkvmReflectionModuleMetadata _impl; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + public IkvmReflectionModuleSymbol(IkvmReflectionSymbolContext context, IIkvmReflectionAssemblySymbol resolvingAssembly, Module module) : + base(context) + { + _resolvingAssembly = resolvingAssembly ?? throw new ArgumentNullException(nameof(resolvingAssembly)); + _module = module ?? throw new ArgumentNullException(nameof(module)); + _impl = new IkvmReflectionModuleMetadata(this); + } + + /// + public Module UnderlyingModule => _module; + + /// + public IIkvmReflectionAssemblySymbol ResolvingAssembly => _resolvingAssembly; + + #region IModuleSymbol + + /// + public IAssemblySymbol Assembly => ResolveAssemblySymbol(UnderlyingModule.Assembly); + + /// + public string FullyQualifiedName => UnderlyingModule.FullyQualifiedName; + + /// + public int MetadataToken => UnderlyingModule.MetadataToken; + + /// + public Guid ModuleVersionId => UnderlyingModule.ModuleVersionId; + + /// + public string Name => UnderlyingModule.Name; + + /// + public string ScopeName => UnderlyingModule.ScopeName; + + /// + public IFieldSymbol? GetField(string name) + { + return ResolveFieldSymbol(UnderlyingModule.GetField(name)); + } + + /// + public IFieldSymbol? GetField(string name, System.Reflection.BindingFlags bindingAttr) + { + return ResolveFieldSymbol(UnderlyingModule.GetField(name, (BindingFlags)bindingAttr)); + } + + /// + public IFieldSymbol[] GetFields(System.Reflection.BindingFlags bindingFlags) + { + return ResolveFieldSymbols(UnderlyingModule.GetFields((BindingFlags)bindingFlags))!; + } + + /// + public IFieldSymbol[] GetFields() + { + return ResolveFieldSymbols(UnderlyingModule.GetFields())!; + } + + /// + public IMethodSymbol? GetMethod(string name) + { + return ResolveMethodSymbol(UnderlyingModule.GetMethod(name)); + } + + /// + public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) + { + return ResolveMethodSymbol(UnderlyingModule.GetMethod(name, types.Unpack())); + } + + /// + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + { + return ResolveMethodSymbol(UnderlyingModule.GetMethod(name, (BindingFlags)bindingAttr, null, (CallingConventions)callConvention, types.Unpack(), modifiers?.Unpack())); + } + + /// + public IMethodSymbol[] GetMethods() + { + return ResolveMethodSymbols(UnderlyingModule.GetMethods())!; + } + + /// + public IMethodSymbol[] GetMethods(System.Reflection.BindingFlags bindingFlags) + { + return ResolveMethodSymbols(UnderlyingModule.GetMethods((BindingFlags)bindingFlags))!; + } + + /// + public ITypeSymbol? GetType(string className) + { + return ResolveTypeSymbol(UnderlyingModule.GetType(className)); + } + + /// + public ITypeSymbol? GetType(string className, bool ignoreCase) + { + return ResolveTypeSymbol(UnderlyingModule.GetType(className, ignoreCase)); + } + + /// + public ITypeSymbol? GetType(string className, bool throwOnError, bool ignoreCase) + { + return ResolveTypeSymbol(UnderlyingModule.GetType(className, throwOnError, ignoreCase)); + } + + /// + public ITypeSymbol[] GetTypes() + { + return ResolveTypeSymbols(UnderlyingModule.GetTypes())!; + } + + /// + public bool IsResource() + { + return UnderlyingModule.IsResource(); + } + + /// + public IFieldSymbol? ResolveField(int metadataToken) + { + return ResolveFieldSymbol(UnderlyingModule.ResolveField(metadataToken)); + } + + /// + public IFieldSymbol? ResolveField(int metadataToken, ITypeSymbol[]? genericTypeArguments, ITypeSymbol[]? genericMethodArguments) + { + return ResolveFieldSymbol(UnderlyingModule.ResolveField(metadataToken, genericTypeArguments?.Unpack(), genericMethodArguments?.Unpack())); + } + + /// + public IMemberSymbol? ResolveMember(int metadataToken) + { + return ResolveMemberSymbol(UnderlyingModule.ResolveMember(metadataToken)); + } + + /// + public IMemberSymbol? ResolveMember(int metadataToken, ITypeSymbol[]? genericTypeArguments, ITypeSymbol[]? genericMethodArguments) + { + return ResolveMemberSymbol(UnderlyingModule.ResolveMember(metadataToken, genericTypeArguments?.Unpack(), genericMethodArguments?.Unpack())); + } + + /// + public IMethodBaseSymbol? ResolveMethod(int metadataToken, ITypeSymbol[]? genericTypeArguments, ITypeSymbol[]? genericMethodArguments) + { + return ResolveMethodBaseSymbol(UnderlyingModule.ResolveMethod(metadataToken, genericTypeArguments?.Unpack(), genericMethodArguments?.Unpack())); + } + + /// + public IMethodBaseSymbol? ResolveMethod(int metadataToken) + { + return ResolveMethodBaseSymbol(UnderlyingModule.ResolveMethod(metadataToken)); + } + + /// + public byte[] ResolveSignature(int metadataToken) + { + return UnderlyingModule.ResolveSignature(metadataToken); + } + + /// + public string ResolveString(int metadataToken) + { + return UnderlyingModule.ResolveString(metadataToken); + } + + /// + public ITypeSymbol ResolveType(int metadataToken) + { + return ResolveTypeSymbol(UnderlyingModule.ResolveType(metadataToken)); + } + + /// + public ITypeSymbol ResolveType(int metadataToken, ITypeSymbol[]? genericTypeArguments, ITypeSymbol[]? genericMethodArguments) + { + return ResolveTypeSymbol(UnderlyingModule.ResolveType(metadataToken, genericTypeArguments?.Unpack(), genericMethodArguments?.Unpack())); + } + + /// + public CustomAttribute[] GetCustomAttributes(bool inherit = false) + { + return ResolveCustomAttributes(UnderlyingModule.GetCustomAttributesData()); + } + + /// + public virtual CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) + { + return ResolveCustomAttributes(UnderlyingModule.__GetCustomAttributes(attributeType.Unpack(), inherit)); + } + + /// + public virtual CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) + { + return ResolveCustomAttribute(UnderlyingModule.__GetCustomAttributes(attributeType.Unpack(), inherit).FirstOrDefault()); + } + + /// + public bool IsDefined(ITypeSymbol attributeType, bool inherit = false) + { + return UnderlyingModule.IsDefined(attributeType.Unpack(), false); + } + + #endregion + + /// + public IIkvmReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) + { + return _impl.GetOrCreateTypeSymbol(type); + } + + /// + public IIkvmReflectionTypeSymbolBuilder GetOrCreateTypeSymbol(TypeBuilder type) + { + return _impl.GetOrCreateTypeSymbol(type); + } + + /// + public IIkvmReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) + { + return _impl.GetOrCreateConstructorSymbol(ctor); + } + + /// + public IIkvmReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor) + { + return _impl.GetOrCreateConstructorSymbol(ctor); + } + + /// + public IIkvmReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) + { + return _impl.GetOrCreateMethodSymbol(method); + } + + /// + public IIkvmReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method) + { + return _impl.GetOrCreateMethodSymbol(method); + } + + /// + public IIkvmReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) + { + return _impl.GetOrCreateFieldSymbol(field); + } + + /// + public IIkvmReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field) + { + return _impl.GetOrCreateFieldSymbol(field); + } + + /// + public IIkvmReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) + { + return _impl.GetOrCreatePropertySymbol(property); + } + + /// + public IIkvmReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property) + { + return _impl.GetOrCreatePropertySymbol(property); + } + + /// + public IIkvmReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) + { + return _impl.GetOrCreateEventSymbol(@event); + } + + /// + public IIkvmReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event) + { + return _impl.GetOrCreateEventSymbol(@event); + } + + /// + public IIkvmReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) + { + return _impl.GetOrCreateParameterSymbol(parameter); + } + + /// + public IIkvmReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter) + { + return _impl.GetOrCreateParameterSymbol(parameter); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterSymbol.cs new file mode 100644 index 000000000..58440f6c3 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterSymbol.cs @@ -0,0 +1,121 @@ +using System; +using System.Linq; + +using IKVM.Reflection; + +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + class IkvmReflectionParameterSymbol : IkvmReflectionSymbol, IIkvmReflectionParameterSymbol + { + + readonly IIkvmReflectionModuleSymbol _resolvingModule; + readonly IIkvmReflectionMethodBaseSymbol _resolvingMethod; + readonly ParameterInfo _parameter; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + public IkvmReflectionParameterSymbol(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol resolvingModule, IIkvmReflectionMethodBaseSymbol resolvingMethod, ParameterInfo parameter) : + base(context) + { + _resolvingModule = resolvingModule ?? throw new ArgumentNullException(nameof(resolvingModule)); + _resolvingMethod = resolvingMethod ?? throw new ArgumentNullException(nameof(resolvingMethod)); + _parameter = parameter ?? throw new ArgumentNullException(nameof(parameter)); + } + + /// + public IIkvmReflectionModuleSymbol ResolvingModule => _resolvingModule; + + /// + public IIkvmReflectionMethodBaseSymbol ResolvingMethod => _resolvingMethod; + + /// + public ParameterInfo UnderlyingParameter => _parameter; + + #region IParameterSymbol + + /// + public System.Reflection.ParameterAttributes Attributes => (System.Reflection.ParameterAttributes)UnderlyingParameter.Attributes; + + /// + public object? DefaultValue => UnderlyingParameter.RawDefaultValue; + + /// + public bool HasDefaultValue => UnderlyingParameter.HasDefaultValue; + + /// + public bool IsIn => UnderlyingParameter.IsIn; + + /// + public bool IsLcid => UnderlyingParameter.IsLcid; + + /// + public bool IsOptional => UnderlyingParameter.IsOptional; + + /// + public bool IsOut => UnderlyingParameter.IsOut; + + /// + public bool IsRetval => UnderlyingParameter.IsRetval; + + /// + public IMemberSymbol Member => ResolveMemberSymbol(UnderlyingParameter.Member); + + /// + public int MetadataToken => UnderlyingParameter.MetadataToken; + + /// + public string? Name => UnderlyingParameter.Name; + + /// + public ITypeSymbol ParameterType => ResolveTypeSymbol(UnderlyingParameter.ParameterType); + + /// + public int Position => UnderlyingParameter.Position; + + /// + public CustomAttribute[] GetCustomAttributes(bool inherit = false) + { + return ResolveCustomAttributes(UnderlyingParameter.GetCustomAttributesData()); + } + + /// + public virtual CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) + { + return ResolveCustomAttributes(UnderlyingParameter.__GetCustomAttributes(attributeType.Unpack(), inherit)); + } + + /// + public virtual CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) + { + return ResolveCustomAttribute(UnderlyingParameter.__GetCustomAttributes(attributeType.Unpack(), inherit).FirstOrDefault()); + } + + /// + public virtual bool IsDefined(ITypeSymbol attributeType, bool inherit = false) + { + return UnderlyingParameter.IsDefined(attributeType.Unpack(), inherit); + } + + /// + public ITypeSymbol[] GetOptionalCustomModifiers() + { + return ResolveTypeSymbols(UnderlyingParameter.GetOptionalCustomModifiers()); + } + + /// + public ITypeSymbol[] GetRequiredCustomModifiers() + { + return ResolveTypeSymbols(UnderlyingParameter.GetRequiredCustomModifiers()); + } + + #endregion + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionPropertySymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionPropertySymbol.cs new file mode 100644 index 000000000..96b8eb358 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionPropertySymbol.cs @@ -0,0 +1,121 @@ +using System; + +using IKVM.Reflection; + +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + class IkvmReflectionPropertySymbol : IkvmReflectionMemberSymbol, IIkvmReflectionPropertySymbol + { + + readonly PropertyInfo _property; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + public IkvmReflectionPropertySymbol(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol module, IIkvmReflectionTypeSymbol type, PropertyInfo property) : + base(context, module, type) + { + _property = property ?? throw new ArgumentNullException(nameof(property)); + } + + /// + public PropertyInfo UnderlyingProperty => _property; + + /// + public override MemberInfo UnderlyingMember => UnderlyingProperty; + + /// + public System.Reflection.PropertyAttributes Attributes => (System.Reflection.PropertyAttributes)UnderlyingProperty.Attributes; + + /// + public bool CanRead => UnderlyingProperty.CanRead; + + /// + public bool CanWrite => UnderlyingProperty.CanWrite; + + /// + public bool IsSpecialName => UnderlyingProperty.IsSpecialName; + + /// + public ITypeSymbol PropertyType => ResolveTypeSymbol(UnderlyingProperty.PropertyType); + + /// + public IMethodSymbol? GetMethod => ResolveMethodSymbol(UnderlyingProperty.GetMethod); + + /// + public IMethodSymbol? SetMethod => ResolveMethodSymbol(UnderlyingProperty.SetMethod); + + /// + public object? GetRawConstantValue() + { + return UnderlyingProperty.GetRawConstantValue(); + } + + /// + public IMethodSymbol[] GetAccessors() + { + return ResolveMethodSymbols(UnderlyingProperty.GetAccessors()); + } + + /// + public IMethodSymbol[] GetAccessors(bool nonPublic) + { + return ResolveMethodSymbols(UnderlyingProperty.GetAccessors(nonPublic)); + } + + /// + public IParameterSymbol[] GetIndexParameters() + { + return ResolveParameterSymbols(UnderlyingProperty.GetIndexParameters()); + } + + /// + public IMethodSymbol? GetGetMethod() + { + return ResolveMethodSymbol(UnderlyingProperty.GetGetMethod()); + } + + /// + public IMethodSymbol? GetGetMethod(bool nonPublic) + { + return ResolveMethodSymbol(UnderlyingProperty.GetGetMethod(nonPublic)); + } + + /// + public IMethodSymbol? GetSetMethod() + { + return ResolveMethodSymbol(UnderlyingProperty.GetSetMethod()); + } + + /// + public IMethodSymbol? GetSetMethod(bool nonPublic) + { + return ResolveMethodSymbol(UnderlyingProperty.GetSetMethod(nonPublic)); + } + + /// + public ITypeSymbol GetModifiedPropertyType() + { + throw new NotImplementedException(); + } + + /// + public ITypeSymbol[] GetOptionalCustomModifiers() + { + return ResolveTypeSymbols(UnderlyingProperty.GetOptionalCustomModifiers()); + } + + /// + public ITypeSymbol[] GetRequiredCustomModifiers() + { + return ResolveTypeSymbols(UnderlyingProperty.GetRequiredCustomModifiers()); + } + + } + +} \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs new file mode 100644 index 000000000..393b98db4 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs @@ -0,0 +1,549 @@ +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Diagnostics.CodeAnalysis; + +using IKVM.CoreLib.Symbols.IkvmReflection.Emit; +using IKVM.Reflection; +using IKVM.Reflection.Emit; + +using Type = IKVM.Reflection.Type; + +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + /// + /// Base class for managed symbols. + /// + abstract class IkvmReflectionSymbol : IIkvmReflectionSymbol + { + + readonly IkvmReflectionSymbolContext _context; + + /// + /// Initializes a new instance. + /// + /// + public IkvmReflectionSymbol(IkvmReflectionSymbolContext context) + { + _context = context ?? throw new ArgumentNullException(nameof(context)); + } + + /// + /// Gets the associated . + /// + public IkvmReflectionSymbolContext Context => _context; + + /// + public virtual bool IsMissing => false; + + /// + public virtual bool ContainsMissing => false; + + /// + public virtual bool IsComplete => true; + + /// + [return: NotNullIfNotNull(nameof(assembly))] + public virtual IIkvmReflectionAssemblySymbol? ResolveAssemblySymbol(Assembly? assembly) + { + return assembly == null ? null : _context.GetOrCreateAssemblySymbol(assembly); + } + + /// + [return: NotNullIfNotNull(nameof(assembly))] + public virtual IIkvmReflectionAssemblySymbolBuilder ResolveAssemblySymbol(AssemblyBuilder assembly) + { + if (assembly is null) + throw new ArgumentNullException(nameof(assembly)); + + return _context.GetOrCreateAssemblySymbol(assembly); + } + + /// + [return: NotNullIfNotNull(nameof(assemblies))] + public virtual IIkvmReflectionAssemblySymbol[]? ResolveAssemblySymbols(Assembly[]? assemblies) + { + if (assemblies == null) + return null; + if (assemblies.Length == 0) + return []; + + var a = new IIkvmReflectionAssemblySymbol[assemblies.Length]; + for (int i = 0; i < assemblies.Length; i++) + if (ResolveAssemblySymbol(assemblies[i]) is { } symbol) + a[i] = symbol; + + return a; + } + + /// + [return: NotNullIfNotNull(nameof(module))] + public virtual IIkvmReflectionModuleSymbol? ResolveModuleSymbol(Module? module) + { + return module == null ? null : _context.GetOrCreateModuleSymbol(module); + } + + /// + [return: NotNullIfNotNull(nameof(module))] + public virtual IIkvmReflectionModuleSymbolBuilder ResolveModuleSymbol(ModuleBuilder module) + { + if (module is null) + throw new ArgumentNullException(nameof(module)); + + return _context.GetOrCreateModuleSymbol(module); + } + + /// + [return: NotNullIfNotNull(nameof(modules))] + public virtual IIkvmReflectionModuleSymbol[]? ResolveModuleSymbols(Module[]? modules) + { + if (modules == null) + return null; + if (modules.Length == 0) + return []; + + var a = new IIkvmReflectionModuleSymbol[modules.Length]; + for (int i = 0; i < modules.Length; i++) + if (ResolveModuleSymbol(modules[i]) is { } symbol) + a[i] = symbol; + + return a; + } + + /// + public virtual IEnumerable ResolveModuleSymbols(IEnumerable modules) + { + foreach (var module in modules) + if (ResolveModuleSymbol(module) is { } symbol) + yield return symbol; + } + + /// + [return: NotNullIfNotNull(nameof(member))] + public virtual IIkvmReflectionMemberSymbol? ResolveMemberSymbol(MemberInfo? member) + { + if (member == null) + return null; + + return member switch + { + ConstructorInfo ctor => ResolveConstructorSymbol(ctor), + EventInfo @event => ResolveEventSymbol(@event), + FieldInfo field => ResolveFieldSymbol(field), + MethodInfo method => ResolveMethodSymbol(method), + PropertyInfo property => ResolvePropertySymbol(property), + Type type => ResolveTypeSymbol(type), + _ => throw new InvalidOperationException(), + }; + } + + /// + [return: NotNullIfNotNull(nameof(members))] + public virtual IIkvmReflectionMemberSymbol[]? ResolveMemberSymbols(MemberInfo[]? members) + { + if (members == null) + return null; + if (members.Length == 0) + return []; + + var a = new IIkvmReflectionMemberSymbol[members.Length]; + for (int i = 0; i < members.Length; i++) + if (ResolveMemberSymbol(members[i]) is { } symbol) + a[i] = symbol; + + return a; + } + + /// + [return: NotNullIfNotNull(nameof(type))] + public virtual IIkvmReflectionTypeSymbol? ResolveTypeSymbol(Type? type) + { + return type == null ? null : _context.GetOrCreateTypeSymbol(type); + } + + /// + [return: NotNullIfNotNull(nameof(type))] + public virtual IIkvmReflectionTypeSymbolBuilder ResolveTypeSymbol(TypeBuilder type) + { + if (type is null) + throw new ArgumentNullException(nameof(type)); + + return _context.GetOrCreateTypeSymbol(type); + } + + /// + [return: NotNullIfNotNull(nameof(types))] + public virtual IIkvmReflectionTypeSymbol[]? ResolveTypeSymbols(Type[]? types) + { + if (types == null) + return null; + if (types.Length == 0) + return []; + + var a = new IIkvmReflectionTypeSymbol[types.Length]; + for (int i = 0; i < types.Length; i++) + if (ResolveTypeSymbol(types[i]) is { } symbol) + a[i] = symbol; + + return a; + } + + /// + public virtual IEnumerable ResolveTypeSymbols(IEnumerable types) + { + foreach (var type in types) + if (ResolveTypeSymbol(type) is { } symbol) + yield return symbol; + } + + /// + [return: NotNullIfNotNull(nameof(method))] + public virtual IIkvmReflectionMethodBaseSymbol? ResolveMethodBaseSymbol(MethodBase? method) + { + return method switch + { + ConstructorInfo ctor => ResolveConstructorSymbol(ctor), + MethodInfo method_ => ResolveMethodSymbol(method_), + _ => null, + }; + } + + /// + [return: NotNullIfNotNull(nameof(ctor))] + public virtual IIkvmReflectionConstructorSymbol? ResolveConstructorSymbol(ConstructorInfo? ctor) + { + return ctor == null ? null : _context.GetOrCreateConstructorSymbol(ctor); + } + + /// + [return: NotNullIfNotNull(nameof(ctor))] + public virtual IIkvmReflectionConstructorSymbolBuilder ResolveConstructorSymbol(ConstructorBuilder ctor) + { + if (ctor is null) + throw new ArgumentNullException(nameof(ctor)); + + return _context.GetOrCreateConstructorSymbol(ctor); + } + + /// + [return: NotNullIfNotNull(nameof(ctors))] + public virtual IIkvmReflectionConstructorSymbol[]? ResolveConstructorSymbols(ConstructorInfo[]? ctors) + { + if (ctors == null) + return null; + if (ctors.Length == 0) + return []; + + var a = new IIkvmReflectionConstructorSymbol[ctors.Length]; + for (int i = 0; i < ctors.Length; i++) + if (ResolveConstructorSymbol(ctors[i]) is { } symbol) + a[i] = symbol; + + return a; + } + + /// + [return: NotNullIfNotNull(nameof(method))] + public virtual IIkvmReflectionMethodSymbol? ResolveMethodSymbol(MethodInfo? method) + { + return method == null ? null : _context.GetOrCreateMethodSymbol(method); + } + + /// + [return: NotNullIfNotNull(nameof(method))] + public virtual IIkvmReflectionMethodSymbolBuilder ResolveMethodSymbol(MethodBuilder method) + { + if (method is null) + throw new ArgumentNullException(nameof(method)); + + return _context.GetOrCreateMethodSymbol(method); + } + + /// + [return: NotNullIfNotNull(nameof(methods))] + public virtual IIkvmReflectionMethodSymbol[]? ResolveMethodSymbols(MethodInfo[]? methods) + { + if (methods == null) + return null; + if (methods.Length == 0) + return []; + + var a = new IIkvmReflectionMethodSymbol[methods.Length]; + for (int i = 0; i < methods.Length; i++) + if (ResolveMethodSymbol(methods[i]) is { } symbol) + a[i] = symbol; + + return a; + } + + /// + [return: NotNullIfNotNull(nameof(field))] + public virtual IIkvmReflectionFieldSymbol? ResolveFieldSymbol(FieldInfo? field) + { + return field == null ? null : _context.GetOrCreateFieldSymbol(field); + } + + /// + [return: NotNullIfNotNull(nameof(field))] + public virtual IIkvmReflectionFieldSymbolBuilder ResolveFieldSymbol(FieldBuilder field) + { + if (field is null) + throw new ArgumentNullException(nameof(field)); + + return _context.GetOrCreateFieldSymbol(field); + } + + /// + [return: NotNullIfNotNull(nameof(fields))] + public virtual IIkvmReflectionFieldSymbol[]? ResolveFieldSymbols(FieldInfo[]? fields) + { + if (fields == null) + return null; + if (fields.Length == 0) + return []; + + var a = new IIkvmReflectionFieldSymbol[fields.Length]; + for (int i = 0; i < fields.Length; i++) + if (ResolveFieldSymbol(fields[i]) is { } symbol) + a[i] = symbol; + + return a; + } + + /// + [return: NotNullIfNotNull(nameof(property))] + public virtual IIkvmReflectionPropertySymbol? ResolvePropertySymbol(PropertyInfo? property) + { + return property == null ? null : _context.GetOrCreatePropertySymbol(property); + } + + /// + [return: NotNullIfNotNull(nameof(property))] + public virtual IIkvmReflectionPropertySymbolBuilder ResolvePropertySymbol(PropertyBuilder property) + { + if (property is null) + throw new ArgumentNullException(nameof(property)); + + return _context.GetOrCreatePropertySymbol(property); + } + + /// + [return: NotNullIfNotNull(nameof(properties))] + public virtual IIkvmReflectionPropertySymbol[]? ResolvePropertySymbols(PropertyInfo[]? properties) + { + if (properties == null) + return null; + if (properties.Length == 0) + return []; + + var a = new IIkvmReflectionPropertySymbol[properties.Length]; + for (int i = 0; i < properties.Length; i++) + if (ResolvePropertySymbol(properties[i]) is { } symbol) + a[i] = symbol; + + return a; + } + + /// + [return: NotNullIfNotNull(nameof(@event))] + public virtual IIkvmReflectionEventSymbol? ResolveEventSymbol(EventInfo? @event) + { + return @event == null ? null : _context.GetOrCreateEventSymbol(@event); + } + + /// + [return: NotNullIfNotNull(nameof(@event))] + public virtual IIkvmReflectionEventSymbolBuilder ResolveEventSymbol(EventBuilder @event) + { + if (@event is null) + throw new ArgumentNullException(nameof(@event)); + + return _context.GetOrCreateEventSymbol(@event); + } + + /// + [return: NotNullIfNotNull(nameof(events))] + public virtual IIkvmReflectionEventSymbol[]? ResolveEventSymbols(EventInfo[]? events) + { + if (@events == null) + return null; + if (@events.Length == 0) + return []; + + var a = new IIkvmReflectionEventSymbol[events.Length]; + for (int i = 0; i < events.Length; i++) + if (ResolveEventSymbol(events[i]) is { } symbol) + a[i] = symbol; + + return a; + } + + /// + [return: NotNullIfNotNull(nameof(parameter))] + public virtual IIkvmReflectionParameterSymbol? ResolveParameterSymbol(ParameterInfo? parameter) + { + return parameter == null ? null : _context.GetOrCreateParameterSymbol(parameter); + } + + /// + [return: NotNullIfNotNull(nameof(parameter))] + public virtual IIkvmReflectionParameterSymbolBuilder ResolveParameterSymbol(ParameterBuilder parameter) + { + if (parameter is null) + throw new ArgumentNullException(nameof(parameter)); + + return _context.GetOrCreateParameterSymbol(parameter); + } + + /// + [return: NotNullIfNotNull(nameof(parameters))] + public virtual IIkvmReflectionParameterSymbol[]? ResolveParameterSymbols(ParameterInfo[]? parameters) + { + if (parameters == null) + return null; + if (parameters.Length == 0) + return []; + + var a = new IIkvmReflectionParameterSymbol[parameters.Length]; + for (int i = 0; i < parameters.Length; i++) + if (ResolveParameterSymbol(parameters[i]) is { } symbol) + a[i] = symbol; + + return a; + } + + /// + [return: NotNullIfNotNull(nameof(attributes))] + public virtual CustomAttribute[]? ResolveCustomAttributes(IList? attributes) + { + if (attributes == null) + return null; + if (attributes.Count == 0) + return []; + + var a = new CustomAttribute[attributes.Count]; + for (int i = 0; i < attributes.Count; i++) + if (ResolveCustomAttribute(attributes[i]) is { } v) + a[i] = v; + + return a; + } + + /// + /// Transforms a custom set of custom attribute data records to a symbol record. + /// + /// + /// + public virtual IEnumerable ResolveCustomAttributes(IEnumerable attributes) + { + if (attributes is null) + throw new ArgumentNullException(nameof(attributes)); + + var a = new List(); + foreach (var i in attributes) + if (ResolveCustomAttribute(i) is { } v) + a.Add(v); + + return a.ToArray(); + } + + /// + /// Transforms a custom attribute data record to a symbol record. + /// + /// + /// + [return: NotNullIfNotNull(nameof(customAttributeData))] + public virtual CustomAttribute? ResolveCustomAttribute(CustomAttributeData? customAttributeData) + { + if (customAttributeData == null) + return null; + + return new CustomAttribute( + ResolveTypeSymbol(customAttributeData.AttributeType)!, + ResolveConstructorSymbol(customAttributeData.Constructor)!, + ResolveCustomAttributeTypedArguments(customAttributeData.ConstructorArguments), + ResolveCustomAttributeNamedArguments(customAttributeData.NamedArguments)); + } + + /// + /// Transforms a list of values into symbols. + /// + /// + /// + public ImmutableArray ResolveCustomAttributeTypedArguments(IList args) + { + if (args is null) + throw new ArgumentNullException(nameof(args)); + if (args.Count == 0) + return []; + + var a = new CustomAttributeTypedArgument[args.Count]; + for (int i = 0; i < args.Count; i++) + a[i] = ResolveCustomAttributeTypedArgument(args[i]); + + return a.ToImmutableArray(); + } + + /// + /// Transforms a values into a symbol. + /// + /// + /// + public CustomAttributeTypedArgument ResolveCustomAttributeTypedArgument(IKVM.Reflection.CustomAttributeTypedArgument arg) + { + return new CustomAttributeTypedArgument( + ResolveTypeSymbol(arg.ArgumentType)!, + ResolveCustomAttributeTypedValue(arg.Value)); + } + + /// + /// Transforms the type as appropriate. + /// + /// + /// + public object? ResolveCustomAttributeTypedValue(object? value) + { + return value switch + { + Type v => ResolveTypeSymbol(v), + _ => value + }; + } + + /// + /// Transforms a list of values into symbols. + /// + /// + /// + public ImmutableArray ResolveCustomAttributeNamedArguments(IList args) + { + if (args is null) + throw new ArgumentNullException(nameof(args)); + if (args.Count == 0) + return []; + + var a = new CustomAttributeNamedArgument[args.Count]; + for (int i = 0; i < args.Count; i++) + a[i] = ResolveCustomAttributeNamedArgument(args[i]); + + return ImmutableArray.Create(a); + } + + /// + /// Transforms a values into a symbol. + /// + /// + /// + public CustomAttributeNamedArgument ResolveCustomAttributeNamedArgument(IKVM.Reflection.CustomAttributeNamedArgument arg) + { + return new CustomAttributeNamedArgument( + arg.IsField, + ResolveMemberSymbol(arg.MemberInfo)!, + arg.MemberName, + ResolveCustomAttributeTypedArgument(arg.TypedValue)); + } + + } + +} \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolContext.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolContext.cs new file mode 100644 index 000000000..8268ab17b --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolContext.cs @@ -0,0 +1,297 @@ +using System; +using System.Collections.Concurrent; +using System.Runtime.CompilerServices; + +using IKVM.CoreLib.Symbols.Emit; +using IKVM.CoreLib.Symbols.IkvmReflection.Emit; +using IKVM.Reflection; +using IKVM.Reflection.Emit; + +using Type = IKVM.Reflection.Type; + +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + /// + /// Holds references to symbols derived from System.Reflection. + /// + class IkvmReflectionSymbolContext : ISymbolContext + { + + readonly ConcurrentDictionary> _symbolByName = new(); + readonly ConditionalWeakTable _symbolByAssembly = new(); + + /// + /// Initializes a new instance. + /// + public IkvmReflectionSymbolContext() + { + + } + + /// + /// Gets or creates a indexed based on the assembly's name. + /// + /// + /// + IIkvmReflectionAssemblySymbol GetOrCreateAssemblySymbolByName(Assembly assembly) + { + var r = _symbolByName.GetOrAdd(assembly.FullName, _ => new(null)); + + lock (r) + { + // reference has no target, reset + if (r.TryGetTarget(out var s) == false) + { + if (assembly is AssemblyBuilder builder) + { + // we were passed in a builder, so generate a symbol builder and set it as the builder and symbol. + r.SetTarget(s = new IkvmReflectionAssemblySymbolBuilder(this, builder)); + } + else + { + // we were passed a non builder, so generate a symbol and set it to the symbol + // TODO the weakness here is if we pass it the RuntimeAssembly from a non-associated builder + r.SetTarget(s = new IkvmReflectionAssemblySymbol(this, assembly)); + } + } + + return s ?? throw new InvalidOperationException(); + } + } + + /// + /// Gets or creates a indexed based on the assembly's name. + /// + /// + /// + IIkvmReflectionAssemblySymbolBuilder GetOrCreateAssemblySymbolByName(AssemblyBuilder assembly) + { + return (IIkvmReflectionAssemblySymbolBuilder)GetOrCreateAssemblySymbolByName((Assembly)assembly); + } + + /// + /// Gets or creates a for the specified . + /// + /// + /// + public IIkvmReflectionAssemblySymbol GetOrCreateAssemblySymbol(Assembly assembly) + { + return _symbolByAssembly.GetValue(assembly, GetOrCreateAssemblySymbolByName); + } + + /// + /// Gets or creates a for the specified . + /// + /// + /// + public IIkvmReflectionAssemblySymbolBuilder GetOrCreateAssemblySymbol(AssemblyBuilder assembly) + { + return (IIkvmReflectionAssemblySymbolBuilder)_symbolByAssembly.GetValue(assembly, GetOrCreateAssemblySymbolByName); + } + + /// + /// Gets or creates a for the specified . + /// + /// + /// + public IIkvmReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) + { + if (module is ModuleBuilder builder) + return GetOrCreateModuleSymbol(builder); + else + return GetOrCreateAssemblySymbol(module.Assembly).GetOrCreateModuleSymbol(module); + } + + /// + /// Gets or creates a for the specified . + /// + /// + /// + public IIkvmReflectionModuleSymbolBuilder GetOrCreateModuleSymbol(ModuleBuilder module) + { + return GetOrCreateAssemblySymbol(module.Assembly).GetOrCreateModuleSymbol(module); + } + + /// + /// Gets or creates a for the specified . + /// + /// + /// + public IIkvmReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) + { + if (type is TypeBuilder builder) + return GetOrCreateTypeSymbol(builder); + else + return GetOrCreateModuleSymbol(type.Module).GetOrCreateTypeSymbol(type); + } + + /// + /// Gets or creates a for the specified . + /// + /// + /// + public IIkvmReflectionTypeSymbolBuilder GetOrCreateTypeSymbol(TypeBuilder type) + { + return GetOrCreateModuleSymbol(type.Module).GetOrCreateTypeSymbol(type); + } + + /// + /// Gets or creates a for the specified . + /// + /// + /// + public IIkvmReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) + { + if (ctor is ConstructorBuilder builder) + return GetOrCreateConstructorSymbol(builder); + else + return GetOrCreateModuleSymbol(ctor.Module).GetOrCreateConstructorSymbol(ctor); + } + + /// + /// Gets or creates a for the specified . + /// + /// + /// + public IIkvmReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor) + { + return GetOrCreateModuleSymbol(ctor.Module).GetOrCreateConstructorSymbol(ctor); + } + + /// + /// Gets or creates a for the specified . + /// + /// + /// + public IIkvmReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) + { + if (method is MethodBuilder builder) + return GetOrCreateMethodSymbol(builder); + else + return GetOrCreateModuleSymbol(method.Module).GetOrCreateMethodSymbol(method); + } + + /// + /// Gets or creates a for the specified . + /// + /// + /// + public IIkvmReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method) + { + return GetOrCreateModuleSymbol(method.Module).GetOrCreateMethodSymbol(method); + } + + /// + /// Gets or creates a for the specified . + /// + /// + /// + public IIkvmReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) + { + return GetOrCreateModuleSymbol(parameter.Module).GetOrCreateParameterSymbol(parameter); + } + + /// + /// Gets or creates a for the specified . + /// + /// + /// + public IIkvmReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter) + { + return GetOrCreateModuleSymbol(parameter.Module).GetOrCreateParameterSymbol(parameter); + } + + /// + /// Gets or creates a for the specified . + /// + /// + /// + public IIkvmReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) + { + if (field is FieldBuilder builder) + return GetOrCreateFieldSymbol(builder); + else + return GetOrCreateModuleSymbol(field.Module).GetOrCreateFieldSymbol(field); + } + + /// + /// Gets or creates a for the specified . + /// + /// + /// + public IIkvmReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field) + { + return GetOrCreateModuleSymbol(field.Module).GetOrCreateFieldSymbol(field); + } + + /// + /// Gets or creates a for the specified . + /// + /// + /// + public IIkvmReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) + { + if (property is PropertyBuilder builder) + return GetOrCreatePropertySymbol(builder); + else + return GetOrCreateModuleSymbol(property.Module).GetOrCreatePropertySymbol(property); + } + + /// + /// Gets or creates a for the specified . + /// + /// + /// + public IIkvmReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property) + { + return GetOrCreateModuleSymbol(property.Module).GetOrCreatePropertySymbol(property); + } + + /// + /// Gets or creates a for the specified . + /// + /// + /// + public IIkvmReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) + { + return GetOrCreateModuleSymbol(@event.Module).GetOrCreateEventSymbol(@event); + } + + /// + /// Gets or creates a for the specified . + /// + /// + /// + public IIkvmReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event) + { + return GetOrCreateModuleSymbol(@event.Module).GetOrCreateEventSymbol(@event); + } + + /// + public ICustomAttributeBuilder CreateCustomAttribute(IConstructorSymbol con, object?[] constructorArgs) + { + return new IkvmReflectionCustomAttributeBuilder(new CustomAttributeBuilder(con.Unpack(), constructorArgs)); + } + + /// + public ICustomAttributeBuilder CreateCustomAttribute(IConstructorSymbol con, object?[] constructorArgs, IFieldSymbol[] namedFields, object?[] fieldValues) + { + return new IkvmReflectionCustomAttributeBuilder(new CustomAttributeBuilder(con.Unpack(), constructorArgs, namedFields.Unpack(), fieldValues)); + } + + /// + public ICustomAttributeBuilder CreateCustomAttribute(IConstructorSymbol con, object?[] constructorArgs, IPropertySymbol[] namedProperties, object?[] propertyValues) + { + return new IkvmReflectionCustomAttributeBuilder(new CustomAttributeBuilder(con.Unpack(), constructorArgs, namedProperties.Unpack(), propertyValues)); + } + + /// + public ICustomAttributeBuilder CreateCustomAttribute(IConstructorSymbol con, object?[] constructorArgs, IPropertySymbol[] namedProperties, object?[] propertyValues, IFieldSymbol[] namedFields, object?[] fieldValues) + { + return new IkvmReflectionCustomAttributeBuilder(new CustomAttributeBuilder(con.Unpack(), constructorArgs, namedProperties.Unpack(), propertyValues, namedFields.Unpack(), fieldValues)); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolExtensions.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolExtensions.cs new file mode 100644 index 000000000..988078c42 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolExtensions.cs @@ -0,0 +1,11 @@ +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + static class IkvmReflectionSymbolExtensions + { + + + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeImpl.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeImpl.cs new file mode 100644 index 000000000..e3b7d7fa9 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeImpl.cs @@ -0,0 +1,587 @@ +using System; +using System.Collections.Concurrent; +using System.Threading; + +using IKVM.Reflection; + +using Type = IKVM.Reflection.Type; + +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + /// + /// Provides common operations against a . + /// + struct IkvmReflectionTypeImpl + { + + readonly IIkvmReflectionTypeSymbol _symbol; + + IkvmReflectionTypeSymbol?[]? _asArray; + IkvmReflectionTypeSymbol? _asSZArray; + IkvmReflectionTypeSymbol? _asPointer; + IkvmReflectionTypeSymbol? _asByRef; + ConcurrentDictionary? _genericTypeSymbols; + + /// + /// Initializes a new instance. + /// + /// + /// + public IkvmReflectionTypeImpl(IIkvmReflectionTypeSymbol symbol) + { + _symbol = symbol ?? throw new ArgumentNullException(nameof(symbol)); + } + + /// + /// Gets or creates the cached for the generic parameter type. + /// + /// + /// + public IIkvmReflectionTypeSymbol GetOrCreateGenericTypeSymbol(ITypeSymbol[] genericTypeArguments) + { + if (genericTypeArguments is null) + throw new ArgumentNullException(nameof(genericTypeArguments)); + + if (_symbol.UnderlyingType.IsGenericTypeDefinition == false) + throw new InvalidOperationException(); + + if (_genericTypeSymbols == null) + Interlocked.CompareExchange(ref _genericTypeSymbols, new ConcurrentDictionary(TypeSymbolListEqualityComparer.Instance), null); + + var __symbol = _symbol; + return _genericTypeSymbols.GetOrAdd(genericTypeArguments, _ => new IkvmReflectionTypeSymbol(__symbol.Context, __symbol.ResolvingModule, __symbol.UnderlyingType.MakeGenericType(genericTypeArguments.Unpack()))); + } + + /// + public readonly IAssemblySymbol Assembly => _symbol.ResolveAssemblySymbol(_symbol.UnderlyingType.Assembly); + + /// + public readonly string? AssemblyQualifiedName => _symbol.UnderlyingType.AssemblyQualifiedName; + + /// + public readonly System.Reflection.TypeAttributes Attributes => (System.Reflection.TypeAttributes)_symbol.UnderlyingType.Attributes; + + /// + public readonly ITypeSymbol? BaseType => _symbol.ResolveTypeSymbol(_symbol.UnderlyingType.BaseType); + + /// + public readonly bool ContainsGenericParameters => _symbol.UnderlyingType.ContainsGenericParameters; + + /// + public readonly IMethodBaseSymbol? DeclaringMethod => _symbol.ResolveMethodBaseSymbol(_symbol.UnderlyingType.DeclaringMethod); + + /// + public readonly string? FullName => _symbol.UnderlyingType.FullName; + + /// + public readonly string? Namespace => _symbol.UnderlyingType.Namespace; + + /// + public readonly System.Reflection.GenericParameterAttributes GenericParameterAttributes => (System.Reflection.GenericParameterAttributes)_symbol.UnderlyingType.GenericParameterAttributes; + + /// + public readonly int GenericParameterPosition => _symbol.UnderlyingType.GenericParameterPosition; + + /// + public readonly ITypeSymbol[] GenericTypeArguments => _symbol.ResolveTypeSymbols(_symbol.UnderlyingType.GenericTypeArguments); + + /// + public readonly bool HasElementType => _symbol.UnderlyingType.HasElementType; + + /// + public readonly TypeCode TypeCode => Type.GetTypeCode(_symbol.UnderlyingType); + + /// + public readonly bool IsAbstract => _symbol.UnderlyingType.IsAbstract; + + /// + public readonly bool IsSZArray => _symbol.UnderlyingType.IsSZArray; + + /// + public readonly bool IsArray => _symbol.UnderlyingType.IsArray; + + /// + public readonly bool IsAutoLayout => _symbol.UnderlyingType.IsAutoLayout; + + /// + public readonly bool IsExplicitLayout => _symbol.UnderlyingType.IsExplicitLayout; + + /// + public readonly bool IsByRef => _symbol.UnderlyingType.IsByRef; + + /// + public readonly bool IsClass => _symbol.UnderlyingType.IsClass; + + /// + public readonly bool IsEnum => _symbol.UnderlyingType.IsEnum; + + /// + public readonly bool IsInterface => _symbol.UnderlyingType.IsInterface; + + /// + public readonly bool IsConstructedGenericType => _symbol.UnderlyingType.IsConstructedGenericType; + + /// + public readonly bool IsGenericParameter => _symbol.UnderlyingType.IsGenericParameter; + + /// + public readonly bool IsGenericType => _symbol.UnderlyingType.IsGenericType; + + /// + public readonly bool IsGenericTypeDefinition => _symbol.UnderlyingType.IsGenericTypeDefinition; + + /// + public readonly bool IsLayoutSequential => _symbol.UnderlyingType.IsLayoutSequential; + + /// + public readonly bool IsNested => _symbol.UnderlyingType.IsNested; + + /// + public readonly bool IsNestedAssembly => _symbol.UnderlyingType.IsNestedAssembly; + + /// + public readonly bool IsNestedFamANDAssem => _symbol.UnderlyingType.IsNestedFamANDAssem; + + /// + public readonly bool IsNestedFamORAssem => _symbol.UnderlyingType.IsNestedFamORAssem; + + /// + public readonly bool IsNestedFamily => _symbol.UnderlyingType.IsNestedFamily; + + /// + public readonly bool IsNestedPrivate => _symbol.UnderlyingType.IsNestedPrivate; + + /// + public readonly bool IsNestedPublic => _symbol.UnderlyingType.IsNestedPublic; + + /// + public readonly bool IsNotPublic => _symbol.UnderlyingType.IsNotPublic; + + /// + public readonly bool IsPointer => _symbol.UnderlyingType.IsPointer; + + /// + public readonly bool IsFunctionPointer => _symbol.UnderlyingType.IsFunctionPointer; + + /// + public readonly bool IsUnmanagedFunctionPointer => _symbol.UnderlyingType.IsUnmanagedFunctionPointer; + + /// + public readonly bool IsPrimitive => _symbol.UnderlyingType.IsPrimitive; + + /// + public readonly bool IsPublic => _symbol.UnderlyingType.IsPublic; + + /// + public readonly bool IsSealed => _symbol.UnderlyingType.IsSealed; + + /// + public readonly bool IsSerializable => _symbol.UnderlyingType.IsSerializable; + + /// + public readonly bool IsValueType => _symbol.UnderlyingType.IsValueType; + + /// + public readonly bool IsVisible => _symbol.UnderlyingType.IsVisible; + + /// + public readonly bool IsSignatureType => throw new NotImplementedException(); + + /// + public readonly bool IsSpecialName => _symbol.UnderlyingType.IsSpecialName; + + /// + public readonly IConstructorSymbol? TypeInitializer => _symbol.ResolveConstructorSymbol(_symbol.UnderlyingType.TypeInitializer); + + /// + public readonly int GetArrayRank() + { + return _symbol.UnderlyingType.GetArrayRank(); + } + + /// + public readonly IConstructorSymbol? GetConstructor(System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) + { + return _symbol.ResolveConstructorSymbol(_symbol.UnderlyingType.GetConstructor((BindingFlags)bindingAttr, binder: null, types.Unpack(), modifiers: null)); + } + + /// + public readonly IConstructorSymbol? GetConstructor(ITypeSymbol[] types) + { + return _symbol.ResolveConstructorSymbol(_symbol.UnderlyingType.GetConstructor(types.Unpack())); + } + + /// + public readonly IConstructorSymbol[] GetConstructors() + { + return _symbol.ResolveConstructorSymbols(_symbol.UnderlyingType.GetConstructors()); + } + + /// + public readonly IConstructorSymbol[] GetConstructors(System.Reflection.BindingFlags bindingAttr) + { + return _symbol.ResolveConstructorSymbols(_symbol.UnderlyingType.GetConstructors((BindingFlags)bindingAttr)); + } + + /// + public readonly IMemberSymbol[] GetDefaultMembers() + { + return _symbol.ResolveMemberSymbols(_symbol.UnderlyingType.GetDefaultMembers()); + } + + /// + public readonly ITypeSymbol? GetElementType() + { + return _symbol.ResolveTypeSymbol(_symbol.UnderlyingType.GetElementType()); + } + + /// + public readonly string? GetEnumName(object value) + { + return _symbol.UnderlyingType.GetEnumName(value); + } + + /// + public readonly string[] GetEnumNames() + { + return _symbol.UnderlyingType.GetEnumNames(); + } + + /// + public readonly ITypeSymbol GetEnumUnderlyingType() + { + return _symbol.ResolveTypeSymbol(_symbol.UnderlyingType.GetEnumUnderlyingType()); + } + + /// + public readonly Array GetEnumValues() + { + return _symbol.UnderlyingType.GetEnumValues(); + } + + /// + public readonly IEventSymbol? GetEvent(string name) + { + return _symbol.ResolveEventSymbol(_symbol.UnderlyingType.GetEvent(name)); + } + + /// + public readonly IEventSymbol? GetEvent(string name, System.Reflection.BindingFlags bindingAttr) + { + return _symbol.ResolveEventSymbol(_symbol.UnderlyingType.GetEvent(name, (BindingFlags)bindingAttr)); + } + + /// + public readonly IEventSymbol[] GetEvents() + { + return _symbol.ResolveEventSymbols(_symbol.UnderlyingType.GetEvents()); + } + + /// + public readonly IEventSymbol[] GetEvents(System.Reflection.BindingFlags bindingAttr) + { + return _symbol.ResolveEventSymbols(_symbol.UnderlyingType.GetEvents((BindingFlags)bindingAttr)); + } + + /// + public readonly IFieldSymbol? GetField(string name) + { + return _symbol.ResolveFieldSymbol(_symbol.UnderlyingType.GetField(name)); + } + + /// + public readonly IFieldSymbol? GetField(string name, System.Reflection.BindingFlags bindingAttr) + { + return _symbol.ResolveFieldSymbol(_symbol.UnderlyingType.GetField(name, (BindingFlags)bindingAttr)); + } + + /// + public readonly IFieldSymbol[] GetFields() + { + return _symbol.ResolveFieldSymbols(_symbol.UnderlyingType.GetFields()); + } + + /// + public readonly IFieldSymbol[] GetFields(System.Reflection.BindingFlags bindingAttr) + { + return _symbol.ResolveFieldSymbols(_symbol.UnderlyingType.GetFields((BindingFlags)bindingAttr)); + } + + /// + public readonly ITypeSymbol[] GetGenericArguments() + { + return _symbol.ResolveTypeSymbols(_symbol.UnderlyingType.GetGenericArguments()); + } + + /// + public readonly ITypeSymbol[] GetGenericParameterConstraints() + { + return _symbol.ResolveTypeSymbols(_symbol.UnderlyingType.GetGenericParameterConstraints()); + } + + /// + public readonly ITypeSymbol GetGenericTypeDefinition() + { + return _symbol.ResolveTypeSymbol(_symbol.UnderlyingType.GetGenericTypeDefinition()); + } + + /// + public readonly ITypeSymbol? GetInterface(string name) + { + return _symbol.ResolveTypeSymbol(_symbol.UnderlyingType.GetInterface(name)); + } + + /// + public readonly ITypeSymbol? GetInterface(string name, bool ignoreCase) + { + return _symbol.ResolveTypeSymbol(_symbol.UnderlyingType.GetInterface(name, ignoreCase)); + } + + /// + public readonly InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) + { + throw new NotImplementedException(); + } + + /// + public readonly ITypeSymbol[] GetInterfaces(bool inherit = true) + { + if (inherit) + return _symbol.ResolveTypeSymbols(_symbol.UnderlyingType.GetInterfaces()); + else + throw new NotImplementedException(); + } + + /// + public readonly IMemberSymbol[] GetMember(string name) + { + return _symbol.ResolveMemberSymbols(_symbol.UnderlyingType.GetMember(name)); + } + + /// + public readonly IMemberSymbol[] GetMember(string name, System.Reflection.BindingFlags bindingAttr) + { + return _symbol.ResolveMemberSymbols(_symbol.UnderlyingType.GetMember(name, (BindingFlags)bindingAttr)); + } + + /// + public readonly IMemberSymbol[] GetMember(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) + { + return _symbol.ResolveMemberSymbols(_symbol.UnderlyingType.GetMember(name, (MemberTypes)type, (BindingFlags)bindingAttr)); + } + + /// + public readonly IMemberSymbol[] GetMembers(System.Reflection.BindingFlags bindingAttr) + { + return _symbol.ResolveMemberSymbols(_symbol.UnderlyingType.GetMembers((BindingFlags)bindingAttr)); + } + + /// + public readonly IMemberSymbol[] GetMembers() + { + return _symbol.ResolveMemberSymbols(_symbol.UnderlyingType.GetMembers()); + } + + /// + public readonly IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr) + { + return _symbol.ResolveMethodSymbol(_symbol.UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr)); + } + + /// + public readonly IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) + { + return _symbol.ResolveMethodSymbol(_symbol.UnderlyingType.GetMethod(name, types.Unpack())); + } + + /// + public readonly IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) + { + return _symbol.ResolveMethodSymbol(_symbol.UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), null)); + } + + /// + public readonly IMethodSymbol? GetMethod(string name) + { + return _symbol.ResolveMethodSymbol(_symbol.UnderlyingType.GetMethod(name)); + } + + /// + public readonly IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + { + return _symbol.ResolveMethodSymbol(_symbol.UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, (CallingConventions)callConvention, types.Unpack(), modifiers?.Unpack())); + } + + /// + public readonly IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + { + throw new NotImplementedException(); + } + + /// + public readonly IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + { + throw new NotImplementedException(); + } + + /// + public readonly IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + { + return _symbol.ResolveMethodSymbol(_symbol.UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), modifiers?.Unpack())); + } + + /// + public readonly IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + { + throw new NotImplementedException(); + } + + /// + public readonly IMethodSymbol[] GetMethods(System.Reflection.BindingFlags bindingAttr) + { + return _symbol.ResolveMethodSymbols(_symbol.UnderlyingType.GetMethods((BindingFlags)bindingAttr)); + } + + /// + public readonly IMethodSymbol[] GetMethods() + { + return _symbol.ResolveMethodSymbols(_symbol.UnderlyingType.GetMethods()); + } + + /// + public readonly ITypeSymbol? GetNestedType(string name) + { + return _symbol.ResolveTypeSymbol(_symbol.UnderlyingType.GetNestedType(name)); + } + + /// + public readonly ITypeSymbol? GetNestedType(string name, System.Reflection.BindingFlags bindingAttr) + { + return _symbol.ResolveTypeSymbol(_symbol.UnderlyingType.GetNestedType(name, (BindingFlags)bindingAttr)); + } + + /// + public readonly ITypeSymbol[] GetNestedTypes() + { + return _symbol.ResolveTypeSymbols(_symbol.UnderlyingType.GetNestedTypes()); + } + + /// + public readonly ITypeSymbol[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr) + { + return _symbol.ResolveTypeSymbols(_symbol.UnderlyingType.GetNestedTypes((BindingFlags)bindingAttr)); + } + + /// + public readonly IPropertySymbol[] GetProperties() + { + return _symbol.ResolvePropertySymbols(_symbol.UnderlyingType.GetProperties()); + } + + /// + public readonly IPropertySymbol[] GetProperties(System.Reflection.BindingFlags bindingAttr) + { + return _symbol.ResolvePropertySymbols(_symbol.UnderlyingType.GetProperties((BindingFlags)bindingAttr)); + } + + /// + public readonly IPropertySymbol? GetProperty(string name, ITypeSymbol[] types) + { + return _symbol.ResolvePropertySymbol(_symbol.UnderlyingType.GetProperty(name, types.Unpack())); + } + + /// + public readonly IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types) + { + return _symbol.ResolvePropertySymbol(_symbol.UnderlyingType.GetProperty(name, returnType?.Unpack(), types.Unpack())); + } + + /// + public readonly IPropertySymbol? GetProperty(string name, System.Reflection.BindingFlags bindingAttr) + { + return _symbol.ResolvePropertySymbol(_symbol.UnderlyingType.GetProperty(name, (BindingFlags)bindingAttr)); + } + + /// + public readonly IPropertySymbol? GetProperty(string name) + { + return _symbol.ResolvePropertySymbol(_symbol.UnderlyingType.GetProperty(name)); + } + + /// + public readonly IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) + { + return _symbol.ResolvePropertySymbol(_symbol.UnderlyingType.GetProperty(name, returnType?.Unpack())); + } + + /// + public readonly bool IsAssignableFrom(ITypeSymbol? c) + { + return _symbol.UnderlyingType.IsAssignableFrom(c?.Unpack()); + } + + /// + public readonly bool IsEnumDefined(object value) + { + return _symbol.UnderlyingType.IsEnumDefined(value); + } + + /// + public readonly bool IsSubclassOf(ITypeSymbol c) + { + return _symbol.UnderlyingType.IsSubclassOf(c.Unpack()); + } + + /// + public IIkvmReflectionTypeSymbol MakeArrayType() + { + if (_asSZArray == null) + Interlocked.CompareExchange(ref _asSZArray, new IkvmReflectionTypeSymbol(_symbol.Context, _symbol.ResolvingModule, _symbol.UnderlyingType.MakeArrayType()), null); + + return _asSZArray; + } + + /// + public IIkvmReflectionTypeSymbol MakeArrayType(int rank) + { + if (rank == 1) + return MakeArrayType(); + + if (_asArray == null) + Interlocked.CompareExchange(ref _asArray, new IkvmReflectionTypeSymbol?[32], null); + + ref var asArray = ref _asArray[rank]; + if (asArray == null) + Interlocked.CompareExchange(ref asArray, new IkvmReflectionTypeSymbol(_symbol.Context, _symbol.ResolvingModule, _symbol.UnderlyingType.MakeArrayType(rank)), null); + + return asArray; + } + + /// + public IIkvmReflectionTypeSymbol MakeByRefType() + { + if (_asByRef == null) + Interlocked.CompareExchange(ref _asByRef, new IkvmReflectionTypeSymbol(_symbol.Context, _symbol.ResolvingModule, _symbol.UnderlyingType.MakeByRefType()), null); + + return _asByRef; + } + + /// + public IIkvmReflectionTypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments) + { + return GetOrCreateGenericTypeSymbol(typeArguments); + } + + /// + public IIkvmReflectionTypeSymbol MakePointerType() + { + if (_asPointer == null) + Interlocked.CompareExchange(ref _asPointer, new IkvmReflectionTypeSymbol(_symbol.Context, _symbol.ResolvingModule, _symbol.UnderlyingType.MakePointerType()), null); + + return _asPointer; + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs new file mode 100644 index 000000000..99ef2c73c --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs @@ -0,0 +1,554 @@ +using System; +using System.Diagnostics.CodeAnalysis; + +using Type = IKVM.Reflection.Type; + +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + class IkvmReflectionTypeSymbol : IkvmReflectionMemberSymbol, IIkvmReflectionTypeSymbol + { + + readonly Type _type; + IkvmReflectionTypeImpl _impl; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + public IkvmReflectionTypeSymbol(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol resolvingModule, Type type) : + base(context, resolvingModule, null) + { + _type = type ?? throw new ArgumentNullException(nameof(type)); + _impl = new IkvmReflectionTypeImpl(this); + } + + /// + public Type UnderlyingType => _type; + + /// + public override IKVM.Reflection.MemberInfo UnderlyingMember => UnderlyingType; + + /// + /// Resolves the symbol for the specified type. + /// + /// + /// + [return: NotNullIfNotNull(nameof(type))] + public override IIkvmReflectionTypeSymbol? ResolveTypeSymbol(Type? type) + { + if (type == _type) + return this; + else + return base.ResolveTypeSymbol(type); + } + + #region ITypeSymbol + + /// + public System.Reflection.TypeAttributes Attributes => _impl.Attributes; + + /// + public IAssemblySymbol Assembly => _impl.Assembly; + + /// + public IMethodBaseSymbol? DeclaringMethod => _impl.DeclaringMethod; + + /// + public string? AssemblyQualifiedName => _impl.AssemblyQualifiedName; + + /// + public string? FullName => _impl.FullName; + + /// + public string? Namespace => _impl.Namespace; + + /// + public TypeCode TypeCode => _impl.TypeCode; + + /// + public ITypeSymbol? BaseType => _impl.BaseType; + + /// + public bool ContainsGenericParameters => _impl.ContainsGenericParameters; + + /// + public System.Reflection.GenericParameterAttributes GenericParameterAttributes => _impl.GenericParameterAttributes; + + /// + public int GenericParameterPosition => _impl.GenericParameterPosition; + + /// + public ITypeSymbol[] GenericTypeArguments => _impl.GenericTypeArguments; + + /// + public bool IsConstructedGenericType => _impl.IsConstructedGenericType; + + /// + public bool IsGenericType => _impl.IsGenericType; + + /// + public bool IsGenericTypeDefinition => _impl.IsGenericTypeDefinition; + + /// + public bool IsGenericParameter => _impl.IsGenericParameter; + + /// + public bool IsAutoLayout => _impl.IsAutoLayout; + + /// + public bool IsExplicitLayout => _impl.IsExplicitLayout; + + /// + public bool IsLayoutSequential => _impl.IsLayoutSequential; + + /// + public bool HasElementType => _impl.HasElementType; + + /// + public bool IsClass => _impl.IsClass; + + /// + public bool IsValueType => _impl.IsValueType; + + /// + public bool IsInterface => _impl.IsInterface; + + /// + public bool IsPrimitive => _impl.IsPrimitive; + + /// + public bool IsSZArray => _impl.IsSZArray; + + /// + public bool IsArray => _impl.IsArray; + + /// + public bool IsEnum => _impl.IsEnum; + + /// + public bool IsPointer => _impl.IsPointer; + + /// + public bool IsFunctionPointer => _impl.IsFunctionPointer; + + /// + public bool IsUnmanagedFunctionPointer => _impl.IsUnmanagedFunctionPointer; + + /// + public bool IsByRef => _impl.IsByRef; + + /// + public bool IsAbstract => _impl.IsAbstract; + + /// + public bool IsSealed => _impl.IsSealed; + + /// + public bool IsVisible => _impl.IsVisible; + + /// + public bool IsPublic => _impl.IsPublic; + + /// + public bool IsNotPublic => _impl.IsNotPublic; + + /// + public bool IsNested => _impl.IsNested; + + /// + public bool IsNestedAssembly => _impl.IsNestedAssembly; + + /// + public bool IsNestedFamANDAssem => _impl.IsNestedFamANDAssem; + + /// + public bool IsNestedFamily => _impl.IsNestedFamily; + + /// + public bool IsNestedFamORAssem => _impl.IsNestedFamORAssem; + + /// + public bool IsNestedPrivate => _impl.IsNestedPrivate; + + /// + public bool IsNestedPublic => _impl.IsNestedPublic; + + /// + public bool IsSerializable => _impl.IsSerializable; + + /// + public bool IsSignatureType => _impl.IsSignatureType; + + /// + public bool IsSpecialName => _impl.IsSpecialName; + + /// + public IConstructorSymbol? TypeInitializer => throw new NotImplementedException(); + + /// + public int GetArrayRank() + { + return _impl.GetArrayRank(); + } + + /// + public IMemberSymbol[] GetDefaultMembers() + { + return _impl.GetDefaultMembers(); + } + + /// + public ITypeSymbol? GetElementType() + { + return _impl.GetElementType(); + } + + /// + public string? GetEnumName(object value) + { + return _impl.GetEnumName(value); + } + + /// + public string[] GetEnumNames() + { + return _impl.GetEnumNames(); + } + + /// + public ITypeSymbol GetEnumUnderlyingType() + { + return _impl.GetEnumUnderlyingType(); + } + + /// + public ITypeSymbol[] GetGenericArguments() + { + return _impl.GetGenericArguments(); + } + + /// + public ITypeSymbol[] GetGenericParameterConstraints() + { + return _impl.GetGenericParameterConstraints(); + } + + /// + public ITypeSymbol GetGenericTypeDefinition() + { + return _impl.GetGenericTypeDefinition(); + } + + /// + public ITypeSymbol? GetInterface(string name) + { + return _impl.GetInterface(name); + } + + /// + public ITypeSymbol? GetInterface(string name, bool ignoreCase) + { + return _impl.GetInterface(name, ignoreCase); + } + + /// + public ITypeSymbol[] GetInterfaces(bool inherit = true) + { + return _impl.GetInterfaces(inherit); + } + + /// + public InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) + { + return _impl.GetInterfaceMap(interfaceType); + } + + /// + public IMemberSymbol[] GetMember(string name) + { + return _impl.GetMember(name); + } + + /// + public IMemberSymbol[] GetMember(string name, System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetMember(name, bindingAttr); + } + + /// + public IMemberSymbol[] GetMember(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetMember(name, type, bindingAttr); + } + + /// + public IMemberSymbol[] GetMembers() + { + return _impl.GetMembers(); + } + + /// + public IMemberSymbol[] GetMembers(System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetMembers(bindingAttr); + } + + public IConstructorSymbol? GetConstructor(ITypeSymbol[] types) + { + return _impl.GetConstructor(types); + } + + /// + public IConstructorSymbol? GetConstructor(System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) + { + return _impl.GetConstructor(bindingAttr, types); + } + + /// + public IConstructorSymbol[] GetConstructors() + { + return _impl.GetConstructors(); + } + + /// + public IConstructorSymbol[] GetConstructors(System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetConstructors(bindingAttr); + } + + /// + public IFieldSymbol? GetField(string name) + { + return _impl.GetField(name); + } + + /// + public IFieldSymbol? GetField(string name, System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetField(name, bindingAttr); + } + + /// + public IFieldSymbol[] GetFields() + { + return _impl.GetFields(); + } + + /// + public IFieldSymbol[] GetFields(System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetFields(bindingAttr); + } + + /// + public IMethodSymbol? GetMethod(string name) + { + return _impl.GetMethod(name); + } + + /// + public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) + { + return _impl.GetMethod(name, types); + } + + /// + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetMethod(name, bindingAttr); + } + + /// + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) + { + return _impl.GetMethod(name, bindingAttr, types); + } + + /// + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + { + return _impl.GetMethod(name, bindingAttr, callConvention, types, modifiers); + } + + /// + public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + { + return _impl.GetMethod(name, genericParameterCount, bindingAttr, callConvention, types, modifiers); + } + + /// + public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + { + return _impl.GetMethod(name, genericParameterCount, bindingAttr, types, modifiers); + } + + /// + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + { + return _impl.GetMethod(name, bindingAttr, types, modifiers); + } + + /// + public IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + { + return _impl.GetMethod(name, genericParameterCount, types, modifiers); + } + + /// + public IMethodSymbol[] GetMethods() + { + return _impl.GetMethods(); + } + + /// + public IMethodSymbol[] GetMethods(System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetMethods(bindingAttr); + } + + /// + public IPropertySymbol? GetProperty(string name) + { + return _impl.GetProperty(name); + } + + /// + public IPropertySymbol? GetProperty(string name, System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetProperty(name, bindingAttr); + } + + /// + public IPropertySymbol? GetProperty(string name, ITypeSymbol[] types) + { + return _impl.GetProperty(name, types); + } + + /// + public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types) + { + return _impl.GetProperty(name, returnType, types); + } + + /// + public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) + { + return _impl.GetProperty(name, returnType); + } + + /// + public IPropertySymbol[] GetProperties() + { + return _impl.GetProperties(); + } + + /// + public IPropertySymbol[] GetProperties(System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetProperties(bindingAttr); + } + + /// + public IEventSymbol? GetEvent(string name) + { + return _impl.GetEvent(name); + } + + /// + public IEventSymbol? GetEvent(string name, System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetEvent(name, bindingAttr); + } + + /// + public IEventSymbol[] GetEvents() + { + return _impl.GetEvents(); + } + + /// + public IEventSymbol[] GetEvents(System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetEvents(bindingAttr); + } + + /// + public ITypeSymbol? GetNestedType(string name) + { + return _impl.GetNestedType(name); + } + + /// + public ITypeSymbol? GetNestedType(string name, System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetNestedType(name, bindingAttr); + } + + /// + public ITypeSymbol[] GetNestedTypes() + { + return _impl.GetNestedTypes(); + } + + /// + public ITypeSymbol[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr) + { + return _impl.GetNestedTypes(); + } + + /// + public bool IsAssignableFrom(ITypeSymbol? c) + { + return _impl.IsAssignableFrom(c); + } + + /// + public bool IsSubclassOf(ITypeSymbol c) + { + return _impl.IsSubclassOf(c); + } + + /// + public bool IsEnumDefined(object value) + { + return _impl.IsEnumDefined(value); + } + + /// + public ITypeSymbol MakeArrayType() + { + return _impl.MakeArrayType(); + } + + /// + public ITypeSymbol MakeArrayType(int rank) + { + return _impl.MakeArrayType(rank); + } + + /// + public ITypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments) + { + return _impl.MakeGenericType(typeArguments); + } + + /// + public ITypeSymbol MakePointerType() + { + return _impl.MakePointerType(); + } + + /// + public ITypeSymbol MakeByRefType() + { + return _impl.MakeByRefType(); + } + + #endregion + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionUtil.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionUtil.cs new file mode 100644 index 000000000..0aa5322ab --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionUtil.cs @@ -0,0 +1,315 @@ +using System; + +using IKVM.Reflection; + +using Type = IKVM.Reflection.Type; + +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + static class IkvmReflectionUtil + { + +#pragma warning disable SYSLIB0017 // Type or member is obsolete +#pragma warning disable SYSLIB0037 // Type or member is obsolete + + /// + /// Converts a to a . + /// + /// + /// + public static System.Reflection.AssemblyName ToAssemblyName(this AssemblyName n) + { + return new System.Reflection.AssemblyName() + { + Name = n.Name, + Version = n.Version, + CultureInfo = n.CultureInfo, + CultureName = n.CultureName, + ProcessorArchitecture = (System.Reflection.ProcessorArchitecture)n.ProcessorArchitecture, + Flags = (System.Reflection.AssemblyNameFlags)n.Flags, + HashAlgorithm = (System.Configuration.Assemblies.AssemblyHashAlgorithm)n.HashAlgorithm, + ContentType = (System.Reflection.AssemblyContentType)n.ContentType, + VersionCompatibility = (System.Configuration.Assemblies.AssemblyVersionCompatibility)n.VersionCompatibility, + }; + } + +#pragma warning restore SYSLIB0037 // Type or member is obsolete +#pragma warning restore SYSLIB0017 // Type or member is obsolete + + /// + /// Converts a set of to a set of . + /// + /// + /// + public static System.Reflection.AssemblyName[] ToAssemblyNames(this AssemblyName[] n) + { + if (n.Length == 0) + return []; + + var a = new System.Reflection.AssemblyName[n.Length]; + for (int i = 0; i < n.Length; i++) + a[i] = n[i].ToAssemblyName(); + + return a; + } + + /// + /// Unpacks the symbol into their original type. + /// + /// + /// + public static Module Unpack(this IModuleSymbol module) + { + if (module is IIkvmReflectionModuleSymbol symbol) + return symbol.UnderlyingModule; + + throw new InvalidOperationException(); + } + + /// + /// Unpacks the symbols into their original type. + /// + /// + /// + public static Module[] Unpack(this IModuleSymbol[] modules) + { + if (modules.Length == 0) + return []; + + var a = new Module[modules.Length]; + for (int i = 0; i < modules.Length; i++) + a[i] = modules[i].Unpack(); + + return a; + } + + /// + /// Unpacks the symbol into their original type. + /// + /// + /// + public static Type Unpack(this ITypeSymbol type) + { + if (type is IIkvmReflectionTypeSymbol symbol) + return symbol.UnderlyingType; + + throw new InvalidOperationException(); + } + + /// + /// Unpacks the symbols into their original type. + /// + /// + /// + public static Type[] Unpack(this ITypeSymbol[] types) + { + if (types.Length == 0) + return []; + + var a = new Type[types.Length]; + for (int i = 0; i < types.Length; i++) + a[i] = types[i].Unpack(); + + return a; + } + + /// + /// Unpacks the symbols into their original type. + /// + /// + /// + public static Type[][] Unpack(this ITypeSymbol[][] types) + { + if (types.Length == 0) + return []; + + var a = new Type[types.Length][]; + for (int i = 0; i < types.Length; i++) + a[i] = types[i].Unpack(); + + return a; + } + + /// + /// Unpacks the symbol into their original type. + /// + /// + /// + public static MemberInfo Unpack(this IMemberSymbol member) + { + if (member is IIkvmReflectionMemberSymbol symbol) + return symbol.UnderlyingMember; + + throw new InvalidOperationException(); + } + + /// + /// Unpacks the symbols into their original type. + /// + /// + /// + public static MemberInfo[] Unpack(this IMemberSymbol[] members) + { + if (members.Length == 0) + return []; + + var a = new MemberInfo[members.Length]; + for (int i = 0; i < members.Length; i++) + a[i] = members[i].Unpack(); + + return a; + } + + /// + /// Unpacks the symbol into their original type. + /// + /// + /// + public static ConstructorInfo Unpack(this IConstructorSymbol ctor) + { + if (ctor is IIkvmReflectionConstructorSymbol symbol) + return symbol.UnderlyingConstructor; + + throw new InvalidOperationException(); + } + + /// + /// Unpacks the symbols into their original type. + /// + /// + /// + public static ConstructorInfo[] Unpack(this IConstructorSymbol[] ctor) + { + if (ctor.Length == 0) + return []; + + var a = new ConstructorInfo[ctor.Length]; + for (int i = 0; i < ctor.Length; i++) + a[i] = ctor[i].Unpack(); + + return a; + } + + /// + /// Unpacks the symbol into their original type. + /// + /// + /// + public static MethodInfo Unpack(this IMethodSymbol ctor) + { + if (ctor is IIkvmReflectionMethodSymbol symbol) + return symbol.UnderlyingMethod; + + throw new InvalidOperationException(); + } + + /// + /// Unpacks the symbols into their original type. + /// + /// + /// + public static MethodInfo[] Unpack(this IMethodSymbol[] ctor) + { + if (ctor.Length == 0) + return []; + + var a = new MethodInfo[ctor.Length]; + for (int i = 0; i < ctor.Length; i++) + a[i] = ctor[i].Unpack(); + + return a; + } + + /// + /// Unpacks the symbol into their original type. + /// + /// + /// + public static FieldInfo Unpack(this IFieldSymbol field) + { + if (field is IIkvmReflectionFieldSymbol symbol) + return symbol.UnderlyingField; + + throw new InvalidOperationException(); + } + + /// + /// Unpacks the symbols into their original type. + /// + /// + /// + public static FieldInfo[] Unpack(this IFieldSymbol[] fields) + { + if (fields.Length == 0) + return []; + + var a = new FieldInfo[fields.Length]; + for (int i = 0; i < fields.Length; i++) + a[i] = fields[i].Unpack(); + + return a; + } + + /// + /// Unpacks the symbol into their original type. + /// + /// + /// + public static PropertyInfo Unpack(this IPropertySymbol property) + { + if (property is IIkvmReflectionPropertySymbol symbol) + return symbol.UnderlyingProperty; + + throw new InvalidOperationException(); + } + + /// + /// Unpacks the symbols into their original type. + /// + /// + /// + public static PropertyInfo[] Unpack(this IPropertySymbol[] properties) + { + if (properties.Length == 0) + return []; + + var a = new PropertyInfo[properties.Length]; + for (int i = 0; i < properties.Length; i++) + a[i] = properties[i].Unpack(); + + return a; + } + + /// + /// Unpacks the parameter modifier. + /// + /// + /// + /// + public static ParameterModifier Unpack(this System.Reflection.ParameterModifier modifier) + { + throw new NotSupportedException(); + } + + /// + /// Unpacks the parameter modifier. + /// + /// + /// + /// + public static ParameterModifier[] Unpack(this System.Reflection.ParameterModifier[] modifiers) + { + if (modifiers.Length == 0) + return []; + + var a = new ParameterModifier[modifiers.Length]; + for (int i = 0; i < modifiers.Length; i++) + a[i] = modifiers[i].Unpack(); + + return a; + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionParameterSymbolBuilder.cs index 5495e484b..879a74a62 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionParameterSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionParameterSymbolBuilder.cs @@ -122,13 +122,13 @@ public CustomAttribute[] GetCustomAttributes(bool inherit = false) /// public virtual CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) { - return GetCustomAttributes(inherit).Where(i => i.AttributeType == attributeType).ToArray(); + return ResolveCustomAttributes(UnderlyingParameter.GetCustomAttributesData().Where(i => attributeType.IsAssignableFrom(attributeType)).ToArray()); } /// public virtual CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) { - return GetCustomAttributes(attributeType, inherit).FirstOrDefault(); + return ResolveCustomAttribute(UnderlyingParameter.GetCustomAttributesData().Where(i => attributeType.IsAssignableFrom(attributeType)).FirstOrDefault()); } /// diff --git a/src/IKVM.Reflection/Emit/PropertyBuilder.cs b/src/IKVM.Reflection/Emit/PropertyBuilder.cs index 0a906ce60..a114f26c2 100644 --- a/src/IKVM.Reflection/Emit/PropertyBuilder.cs +++ b/src/IKVM.Reflection/Emit/PropertyBuilder.cs @@ -269,6 +269,17 @@ internal override int GetCurrentToken() return lazyPseudoToken; } + public override int MetadataToken + { + get + { + if (lazyPseudoToken == 0) + lazyPseudoToken = typeBuilder.ModuleBuilder.AllocPseudoToken(); + + return GetCurrentToken(); + } + } + } } diff --git a/src/IKVM.Runtime/AttributeHelper.cs b/src/IKVM.Runtime/AttributeHelper.cs index cea132a71..cf883ce9a 100644 --- a/src/IKVM.Runtime/AttributeHelper.cs +++ b/src/IKVM.Runtime/AttributeHelper.cs @@ -38,7 +38,9 @@ Jeroen Frijters #if IMPORTER || EXPORTER +using IKVM.Reflection; #else +using System.Reflection; #endif #if IMPORTER @@ -902,7 +904,7 @@ internal NameSigAttribute GetNameSig(IMemberSymbol member) internal T[] DecodeArray(IKVM.CoreLib.Symbols.CustomAttributeTypedArgument arg) { - var elems = (CustomAttributeTypedArgument[])arg.Value; + var elems = (IKVM.CoreLib.Symbols.CustomAttributeTypedArgument[])arg.Value; var arr = new T[elems.Length]; for (int i = 0; i < arr.Length; i++) arr[i] = (T)elems[i].Value; @@ -932,7 +934,7 @@ internal ThrowsAttribute GetThrows(IMethodBaseSymbol mb) } else if (args[0].ArgumentType == context.Types.Type.MakeArrayType()) { - return new ThrowsAttribute(DecodeArray(args[0]).Unpack()); + return new ThrowsAttribute(DecodeArray(args[0]).AsReflection()); } else { diff --git a/src/IKVM.Runtime/ByteCodeHelper.cs b/src/IKVM.Runtime/ByteCodeHelper.cs index df39527fa..43f3be833 100644 --- a/src/IKVM.Runtime/ByteCodeHelper.cs +++ b/src/IKVM.Runtime/ByteCodeHelper.cs @@ -105,7 +105,7 @@ public static object multianewarray_ghost(RuntimeTypeHandle typeHandle, int[] le type = type.GetElementType(); } - var obj = multianewarray(RuntimeArrayJavaType.MakeArrayType(typeof(object), rank).TypeHandle, lengths); + var obj = multianewarray(typeof(object).MakeArrayType(rank).TypeHandle, lengths); GhostTag.SetTag(obj, typeHandle); return obj; } diff --git a/src/IKVM.Runtime/CodeEmitter.cs b/src/IKVM.Runtime/CodeEmitter.cs index ec6406b17..cf4cb20cb 100644 --- a/src/IKVM.Runtime/CodeEmitter.cs +++ b/src/IKVM.Runtime/CodeEmitter.cs @@ -80,7 +80,7 @@ public CodeEmitterFactory(RuntimeContext context) /// public CodeEmitter Create(IMethodSymbolBuilder mb) { - return new CodeEmitter(context, mb.GetILGenerator(), context.Resolver.ResolveType(mb.Symbol.DeclaringType)); + return new CodeEmitter(context, mb.GetILGenerator(), context.Resolver.ResolveType(mb.DeclaringType)); } #if IMPORTER == false diff --git a/src/IKVM.Runtime/Java/Externs/sun/misc/Unsafe.cs b/src/IKVM.Runtime/Java/Externs/sun/misc/Unsafe.cs index 20a8de6f9..229822b1d 100644 --- a/src/IKVM.Runtime/Java/Externs/sun/misc/Unsafe.cs +++ b/src/IKVM.Runtime/Java/Externs/sun/misc/Unsafe.cs @@ -1734,9 +1734,9 @@ public static object allocateInstance(object self, global::java.lang.Class cls) } #if NETFRAMEWORK - return FormatterServices.GetUninitializedObject(wrapper.TypeAsBaseType); + return FormatterServices.GetUninitializedObject(wrapper.TypeAsBaseType.AsReflection()); #else - return RuntimeHelpers.GetUninitializedObject(wrapper.TypeAsBaseType); + return RuntimeHelpers.GetUninitializedObject(wrapper.TypeAsBaseType.AsReflection()); #endif } @@ -1854,8 +1854,8 @@ static void PutFieldVolatile(object o, long offset, T value) /// static Delegate CreateGetArrayVolatileDelegate(RuntimeJavaType tw) { - var et = tw.IsPrimitive ? tw.TypeAsTBD : typeof(object); - var dm = DynamicMethodUtil.Create($"____{tw.Name.Replace(".", "_")}", tw.TypeAsTBD, true, et, new[] { typeof(object[]), typeof(long) }); + var et = tw.IsPrimitive ? tw.TypeAsTBD.AsReflection() : typeof(object); + var dm = DynamicMethodUtil.Create($"____{tw.Name.Replace(".", "_")}", tw.TypeAsTBD.AsReflection(), true, et, new[] { typeof(object[]), typeof(long) }); var il = dm.GetILGenerator(); // load reference to element @@ -1865,17 +1865,17 @@ static Delegate CreateGetArrayVolatileDelegate(RuntimeJavaType tw) il.Emit(OpCodes.Ldc_I4, ArrayIndexScale(tw.MakeArrayType(1))); il.Emit(OpCodes.Div); il.Emit(OpCodes.Conv_Ovf_I); - il.Emit(OpCodes.Ldelema, tw.TypeAsLocalOrStackType); + il.Emit(OpCodes.Ldelema, tw.TypeAsLocalOrStackType.AsReflection()); if (tw.IsWidePrimitive == false) { il.Emit(OpCodes.Volatile); - EmitLdind(il, tw.TypeAsLocalOrStackType); + EmitLdind(il, tw.TypeAsLocalOrStackType.AsReflection()); } else { // Java volatile semantics require atomicity, CLR volatile semantics do not - var mi = typeof(Unsafe).GetMethod(nameof(InterlockedRead), BindingFlags.NonPublic | BindingFlags.Static, null, new[] { tw.TypeAsTBD.MakeByRefType() }, null); + var mi = typeof(Unsafe).GetMethod(nameof(InterlockedRead), BindingFlags.NonPublic | BindingFlags.Static, null, new[] { tw.TypeAsTBD.MakeByRefType().AsReflection() }, null); il.Emit(OpCodes.Call, mi); } @@ -1912,8 +1912,8 @@ static object GetArrayObjectVolatile(object[] array, long offset) /// static Delegate CreatePutArrayVolatileDelegate(RuntimeJavaType tw) { - var et = tw.IsPrimitive ? tw.TypeAsTBD : typeof(object); - var dm = DynamicMethodUtil.Create($"____{tw.Name.Replace(".", "_")}", tw.TypeAsTBD, true, typeof(void), new[] { typeof(object[]), typeof(long), et }); + var et = tw.IsPrimitive ? tw.TypeAsTBD.AsReflection() : typeof(object); + var dm = DynamicMethodUtil.Create($"____{tw.Name.Replace(".", "_")}", tw.TypeAsTBD.AsReflection(), true, typeof(void), new[] { typeof(object[]), typeof(long), et }); var il = dm.GetILGenerator(); // load reference to element @@ -1923,19 +1923,19 @@ static Delegate CreatePutArrayVolatileDelegate(RuntimeJavaType tw) il.Emit(OpCodes.Ldc_I4, ArrayIndexScale(tw.MakeArrayType(1))); il.Emit(OpCodes.Div); il.Emit(OpCodes.Conv_Ovf_I); - il.Emit(OpCodes.Ldelema, tw.TypeAsLocalOrStackType); + il.Emit(OpCodes.Ldelema, tw.TypeAsLocalOrStackType.AsReflection()); il.Emit(OpCodes.Ldarg_2); if (tw.IsWidePrimitive == false) { il.Emit(OpCodes.Volatile); - EmitStind(il, tw.TypeAsLocalOrStackType); + EmitStind(il, tw.TypeAsLocalOrStackType.AsReflection()); } else { // Java volatile semantics require atomicity, CLR volatile semantics do not - var mi = typeof(Interlocked).GetMethod(nameof(Interlocked.Exchange), new[] { tw.TypeAsTBD.MakeByRefType() }); + var mi = typeof(Interlocked).GetMethod(nameof(Interlocked.Exchange), new[] { tw.TypeAsTBD.MakeByRefType().AsReflection() }); il.Emit(OpCodes.Call, mi); } diff --git a/src/IKVM.Runtime/LambdaMetafactory.cs b/src/IKVM.Runtime/LambdaMetafactory.cs index ea553973b..50877f45b 100644 --- a/src/IKVM.Runtime/LambdaMetafactory.cs +++ b/src/IKVM.Runtime/LambdaMetafactory.cs @@ -27,17 +27,16 @@ Jeroen Frijters using IKVM.ByteCode; using IKVM.CoreLib.Diagnostics; +using IKVM.CoreLib.Symbols.Emit; +using IKVM.CoreLib.Symbols; #if IMPORTER -using IKVM.Reflection; -using IKVM.Reflection.Emit; using IKVM.Tools.Importer; using Type = IKVM.Reflection.Type; #else using System.Reflection; using System.Reflection.Emit; - #endif namespace IKVM.Runtime @@ -46,16 +45,17 @@ namespace IKVM.Runtime sealed class LambdaMetafactory { - private MethodBuilder getInstance; + private IMethodSymbolBuilder getInstance; internal static bool Emit(RuntimeByteCodeJavaType.FinishContext context, ClassFile classFile, int constantPoolIndex, ClassFile.ConstantPoolItemInvokeDynamic cpi, CodeEmitter ilgen) { - ClassFile.BootstrapMethod bsm = classFile.GetBootstrapMethod(cpi.BootstrapMethod); + var bsm = classFile.GetBootstrapMethod(cpi.BootstrapMethod); if (!IsLambdaMetafactory(classFile, bsm) && !IsLambdaAltMetafactory(classFile, bsm)) { return false; } - LambdaMetafactory lmf = context.GetValue(constantPoolIndex); + + var lmf = context.GetValue(constantPoolIndex); if (lmf.getInstance == null && !lmf.EmitImpl(context, classFile, cpi, bsm, ilgen)) { #if IMPORTER @@ -64,6 +64,7 @@ internal static bool Emit(RuntimeByteCodeJavaType.FinishContext context, ClassFi #endif return false; } + ilgen.Emit(OpCodes.Call, lmf.getInstance); return true; } @@ -166,6 +167,7 @@ private bool EmitImpl(RuntimeByteCodeJavaType.FinishContext context, ClassFile c return false; } } + RuntimeJavaMethod interfaceMethod = null; List methods = new List(); foreach (RuntimeJavaMethod mw in methodList) @@ -186,7 +188,7 @@ private bool EmitImpl(RuntimeByteCodeJavaType.FinishContext context, ClassFile c return false; } - TypeBuilder tb = context.DefineAnonymousClass(); + var tb = context.DefineAnonymousClass(); // we're not implementing the interfaces recursively (because we don't care about .NET Compact anymore), // but should we decide to do that, we'd need to somehow communicate to AnonymousTypeWrapper what the 'real' interface is tb.AddInterfaceImplementation(interfaceType.TypeAsBaseType); @@ -194,10 +196,10 @@ private bool EmitImpl(RuntimeByteCodeJavaType.FinishContext context, ClassFile c { tb.AddInterfaceImplementation(context.Context.JavaBase.TypeOfJavaIoSerializable.TypeAsBaseType); } - foreach (RuntimeJavaType marker in markers) - { + + foreach (var marker in markers) tb.AddInterfaceImplementation(marker.TypeAsBaseType); - } + getInstance = CreateConstructorAndDispatch(context, cpi, tb, methods, implParameters, samMethodType, implMethod, instantiatedMethodType, serializable); AddDefaultInterfaceMethods(context, methodList, tb); return true; @@ -216,11 +218,13 @@ private static bool CheckConstraints(ClassFile.ConstantPoolItemMethodType instan Fail("instantiatedMethodType <= methodType"); return false; } + if (args.Length + methodType.GetArgTypes().Length != implParameters.Length) { Fail("K + N = M"); return false; } + for (int i = 0, K = args.Length; i < K; i++) { if (args[i] == implParameters[i]) @@ -233,6 +237,7 @@ private static bool CheckConstraints(ClassFile.ConstantPoolItemMethodType instan return false; } } + for (int i = 0, N = methodType.GetArgTypes().Length, k = args.Length; i < N; i++) { if (!IsAdaptable(instantiatedMethodType.GetArgTypes()[i], implParameters[i + k], false)) @@ -241,17 +246,17 @@ private static bool CheckConstraints(ClassFile.ConstantPoolItemMethodType instan return false; } } + return true; } private static RuntimeJavaType[] GetImplParameters(ClassFile.ConstantPoolItemMethodHandle implMethod) { - RuntimeJavaMethod mw = (RuntimeJavaMethod)implMethod.Member; - RuntimeJavaType[] parameters = mw.GetParameters(); + var mw = (RuntimeJavaMethod)implMethod.Member; + var parameters = mw.GetParameters(); if (mw.IsStatic || mw.IsConstructor) - { return parameters; - } + return ArrayUtil.Concat(mw.DeclaringType, parameters); } @@ -313,7 +318,7 @@ private static bool IsAdaptable(RuntimeJavaType Q, RuntimeJavaType S, bool isRet if (S.IsPrimitive) { // If Q is a primitive wrapper, check that Primitive(Q) can be widened to S - RuntimeJavaType primitive = GetPrimitiveFromWrapper(Q); + var primitive = GetPrimitiveFromWrapper(Q); return primitive != null && IsAdaptable(primitive, S, isReturn); } else @@ -377,8 +382,9 @@ private static RuntimeJavaType GetPrimitiveFromWrapper(RuntimeJavaType wrapper) private static bool IsSubTypeOf(ClassFile.ConstantPoolItemMethodType instantiatedMethodType, ClassFile.ConstantPoolItemMethodType samMethodType) { - RuntimeJavaType[] T = instantiatedMethodType.GetArgTypes(); - RuntimeJavaType[] U = samMethodType.GetArgTypes(); + var T = instantiatedMethodType.GetArgTypes(); + var U = samMethodType.GetArgTypes(); + if (T.Length != U.Length) { return false; @@ -390,34 +396,34 @@ private static bool IsSubTypeOf(ClassFile.ConstantPoolItemMethodType instantiate return false; } } - RuntimeJavaType Rt = instantiatedMethodType.GetRetType(); - RuntimeJavaType Ru = samMethodType.GetRetType(); + + var Rt = instantiatedMethodType.GetRetType(); + var Ru = samMethodType.GetRetType(); return Rt.IsAssignableTo(Ru); } - private static MethodBuilder CreateConstructorAndDispatch(RuntimeByteCodeJavaType.FinishContext context, ClassFile.ConstantPoolItemInvokeDynamic cpi, TypeBuilder tb, + private static IMethodSymbolBuilder CreateConstructorAndDispatch(RuntimeByteCodeJavaType.FinishContext context, ClassFile.ConstantPoolItemInvokeDynamic cpi, ITypeSymbolBuilder tb, List methods, RuntimeJavaType[] implParameters, ClassFile.ConstantPoolItemMethodType samMethodType, ClassFile.ConstantPoolItemMethodHandle implMethod, ClassFile.ConstantPoolItemMethodType instantiatedMethodType, bool serializable) { - RuntimeJavaType[] args = cpi.GetArgTypes(); + var args = cpi.GetArgTypes(); // captured values - Type[] capturedTypes = new Type[args.Length]; - FieldBuilder[] capturedFields = new FieldBuilder[capturedTypes.Length]; + var capturedTypes = new ITypeSymbol[args.Length]; + var capturedFields = new IFieldSymbolBuilder[capturedTypes.Length]; for (int i = 0; i < capturedTypes.Length; i++) { capturedTypes[i] = args[i].TypeAsSignatureType; - FieldAttributes attr = FieldAttributes.Private; + var attr = FieldAttributes.Private; if (i > 0 || !args[0].IsGhost) - { attr |= FieldAttributes.InitOnly; - } + capturedFields[i] = tb.DefineField("arg$" + (i + 1), capturedTypes[i], attr); } // constructor - MethodBuilder ctor = ReflectUtil.DefineConstructor(tb, MethodAttributes.Assembly, capturedTypes); - CodeEmitter ilgen = context.Context.CodeEmitterFactory.Create(ctor); + var ctor = ReflectUtil.DefineConstructor(tb, MethodAttributes.Assembly, capturedTypes); + var ilgen = context.Context.CodeEmitterFactory.Create(ctor); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Call, context.Context.Types.Object.GetConstructor([])); for (int i = 0; i < capturedTypes.Length; i++) @@ -430,17 +436,17 @@ private static MethodBuilder CreateConstructorAndDispatch(RuntimeByteCodeJavaTyp ilgen.DoEmit(); // instance getter - MethodBuilder getInstance = tb.DefineMethod("__", MethodAttributes.Assembly | MethodAttributes.Static, cpi.GetRetType().TypeAsBaseType, capturedTypes); - CodeEmitter ilgenGet = context.Context.CodeEmitterFactory.Create(getInstance); + var getInstance = tb.DefineMethod("__", MethodAttributes.Assembly | MethodAttributes.Static, cpi.GetRetType().TypeAsBaseType, capturedTypes); + var ilgenGet = context.Context.CodeEmitterFactory.Create(getInstance); if (capturedTypes.Length == 0) { // use singleton for lambdas with no captures - FieldBuilder instField = tb.DefineField("inst", tb, FieldAttributes.Private | FieldAttributes.Static); + var instField = tb.DefineField("inst", tb, FieldAttributes.Private | FieldAttributes.Static); // static constructor - MethodBuilder cctor = ReflectUtil.DefineTypeInitializer(tb, context.TypeWrapper.ClassLoader); - CodeEmitter ilgenCCtor = context.Context.CodeEmitterFactory.Create(cctor); + var cctor = ReflectUtil.DefineTypeInitializer(tb, context.TypeWrapper.ClassLoader); + var ilgenCCtor = context.Context.CodeEmitterFactory.Create(cctor); ilgenCCtor.Emit(OpCodes.Newobj, ctor); ilgenCCtor.Emit(OpCodes.Stsfld, instField); ilgenCCtor.Emit(OpCodes.Ret); @@ -471,7 +477,7 @@ private static MethodBuilder CreateConstructorAndDispatch(RuntimeByteCodeJavaTyp // writeReplace method if (serializable) { - MethodBuilder writeReplace = tb.DefineMethod("writeReplace", MethodAttributes.Private, context.Context.Types.Object, []); + var writeReplace = tb.DefineMethod("writeReplace", MethodAttributes.Private, context.Context.Types.Object, []); ilgen = context.Context.CodeEmitterFactory.Create(writeReplace); context.TypeWrapper.EmitClassLiteral(ilgen); ilgen.Emit(OpCodes.Ldstr, cpi.GetRetType().Name.Replace('.', '/')); @@ -500,8 +506,7 @@ private static MethodBuilder CreateConstructorAndDispatch(RuntimeByteCodeJavaTyp } ilgen.Emit(OpCodes.Stelem, context.Context.Types.Object); } - RuntimeJavaMethod ctorSerializedLambda = context.Context.ClassLoaderFactory.LoadClassCritical("java.lang.invoke.SerializedLambda").GetMethodWrapper(StringConstants.INIT, - "(Ljava.lang.Class;Ljava.lang.String;Ljava.lang.String;Ljava.lang.String;ILjava.lang.String;Ljava.lang.String;Ljava.lang.String;Ljava.lang.String;[Ljava.lang.Object;)V", false); + var ctorSerializedLambda = context.Context.ClassLoaderFactory.LoadClassCritical("java.lang.invoke.SerializedLambda").GetMethodWrapper(StringConstants.INIT, "(Ljava.lang.Class;Ljava.lang.String;Ljava.lang.String;Ljava.lang.String;ILjava.lang.String;Ljava.lang.String;Ljava.lang.String;Ljava.lang.String;[Ljava.lang.Object;)V", false); ctorSerializedLambda.Link(); ctorSerializedLambda.EmitNewobj(ilgen); ilgen.Emit(OpCodes.Ret); @@ -518,10 +523,10 @@ private static MethodBuilder CreateConstructorAndDispatch(RuntimeByteCodeJavaTyp return getInstance; } - private static void EmitDispatch(RuntimeByteCodeJavaType.FinishContext context, RuntimeJavaType[] args, TypeBuilder tb, RuntimeJavaMethod interfaceMethod, RuntimeJavaType[] implParameters, - ClassFile.ConstantPoolItemMethodHandle implMethod, ClassFile.ConstantPoolItemMethodType instantiatedMethodType, FieldBuilder[] capturedFields) + private static void EmitDispatch(RuntimeByteCodeJavaType.FinishContext context, RuntimeJavaType[] args, ITypeSymbolBuilder tb, RuntimeJavaMethod interfaceMethod, RuntimeJavaType[] implParameters, + ClassFile.ConstantPoolItemMethodHandle implMethod, ClassFile.ConstantPoolItemMethodType instantiatedMethodType, IFieldSymbolBuilder[] capturedFields) { - MethodBuilder mb = interfaceMethod.GetDefineMethodHelper().DefineMethod(context.TypeWrapper, tb, interfaceMethod.Name, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final); + var mb = interfaceMethod.GetDefineMethodHelper().DefineMethod(context.TypeWrapper, tb, interfaceMethod.Name, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final); if (interfaceMethod.Name != interfaceMethod.RealName) { tb.DefineMethodOverride(mb, (MethodInfo)interfaceMethod.GetMethod()); @@ -529,7 +534,7 @@ private static void EmitDispatch(RuntimeByteCodeJavaType.FinishContext context, context.Context.AttributeHelper.HideFromJava(mb); - CodeEmitter ilgen = context.Context.CodeEmitterFactory.Create(mb); + var ilgen = context.Context.CodeEmitterFactory.Create(mb); for (int i = 0; i < capturedFields.Length; i++) { ilgen.EmitLdarg(0); @@ -732,34 +737,34 @@ private static void EmitUnboxNumber(RuntimeContext context, CodeEmitter ilgen, s mw.EmitCallvirt(ilgen); } - private static void AddDefaultInterfaceMethods(RuntimeByteCodeJavaType.FinishContext context, RuntimeJavaMethod[] methodList, TypeBuilder tb) + private static void AddDefaultInterfaceMethods(RuntimeByteCodeJavaType.FinishContext context, RuntimeJavaMethod[] methodList, ITypeSymbolBuilder tb) { // we use special name to hide these from Java reflection const MethodAttributes attr = MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final | MethodAttributes.SpecialName; - RuntimeJavaTypeFactory factory = context.TypeWrapper.ClassLoader.GetTypeWrapperFactory(); - foreach (RuntimeJavaMethod mw in methodList) + + var factory = context.TypeWrapper.ClassLoader.GetTypeWrapperFactory(); + foreach (var mw in methodList) { if (!mw.IsAbstract) { - MethodBuilder mb = mw.GetDefineMethodHelper().DefineMethod(factory, tb, mw.Name, attr); + var mb = mw.GetDefineMethodHelper().DefineMethod(factory, tb, mw.Name, attr); if (mw.Name != mw.RealName) - { - tb.DefineMethodOverride(mb, (MethodInfo)mw.GetMethod()); - } + tb.DefineMethodOverride(mb, (IMethodSymbol)mw.GetMethod()); + context.EmitCallDefaultInterfaceMethod(mb, mw); } else if (IsObjectMethod(mw)) { - MethodBuilder mb = mw.GetDefineMethodHelper().DefineMethod(factory, tb, mw.Name, attr); + var mb = mw.GetDefineMethodHelper().DefineMethod(factory, tb, mw.Name, attr); if (mw.Name != mw.RealName) - { - tb.DefineMethodOverride(mb, (MethodInfo)mw.GetMethod()); - } - CodeEmitter ilgen = context.Context.CodeEmitterFactory.Create(mb); + tb.DefineMethodOverride(mb, (IMethodSymbol)mw.GetMethod()); + + var ilgen = context.Context.CodeEmitterFactory.Create(mb); for (int i = 0, count = mw.GetParameters().Length; i <= count; i++) { ilgen.EmitLdarg(i); } + context.Context.JavaBase.TypeOfJavaLangObject.GetMethodWrapper(mw.Name, mw.Signature, false).EmitCallvirt(ilgen); ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); @@ -780,11 +785,11 @@ static bool IsSupportedImplMethod(ClassFile.ConstantPoolItemMethodHandle implMet default: return false; } - RuntimeJavaMethod mw = (RuntimeJavaMethod)implMethod.Member; + + var mw = (RuntimeJavaMethod)implMethod.Member; if (mw == null || mw.HasCallerID || RuntimeByteCodeJavaType.RequiresDynamicReflectionCallerClass(mw.DeclaringType.Name, mw.Name, mw.Signature)) - { return false; - } + RuntimeJavaType instance; if (mw.IsConstructor) { @@ -803,10 +808,12 @@ static bool IsSupportedImplMethod(ClassFile.ConstantPoolItemMethodHandle implMet return false; } } + if (!mw.IsAccessibleFrom(mw.DeclaringType, caller, instance)) { return false; } + mw.Link(); return true; } @@ -827,7 +834,7 @@ private static bool CheckSupportedInterfaces(RuntimeJavaType caller, RuntimeJava methodList = null; return false; } - Dictionary methods = new Dictionary(); + var methods = new Dictionary(); int abstractMethodCount = 0; int bridgeMethodCount = 0; if (GatherAllInterfaceMethods(tw, bridges, methods, ref abstractMethodCount, ref bridgeMethodCount) && abstractMethodCount == 1) @@ -860,11 +867,11 @@ private static bool CheckSupportedInterfaces(RuntimeJavaType caller, RuntimeJava private static bool GatherAllInterfaceMethods(RuntimeJavaType tw, ClassFile.ConstantPoolItemMethodType[] bridges, Dictionary methods, ref int abstractMethodCount, ref int bridgeMethodCount) { - foreach (RuntimeJavaMethod mw in tw.GetMethods()) + foreach (var mw in tw.GetMethods()) { if (mw.IsVirtual) { - RuntimeMirandaJavaMethod mmw = mw as RuntimeMirandaJavaMethod; + var mmw = mw as RuntimeMirandaJavaMethod; if (mmw != null) { if (mmw.Error != null) @@ -873,7 +880,8 @@ private static bool GatherAllInterfaceMethods(RuntimeJavaType tw, ClassFile.Cons } continue; } - MethodKey key = new MethodKey("", mw.Name, mw.Signature); + + var key = new MethodKey("", mw.Name, mw.Signature); RuntimeJavaMethod current; if (methods.TryGetValue(key, out current)) { @@ -898,6 +906,7 @@ private static bool GatherAllInterfaceMethods(RuntimeJavaType tw, ClassFile.Cons } } } + mw.Link(); if (mw.GetMethod() == null) { @@ -909,13 +918,15 @@ private static bool GatherAllInterfaceMethods(RuntimeJavaType tw, ClassFile.Cons } } } - foreach (RuntimeJavaType tw1 in tw.Interfaces) + + foreach (var tw1 in tw.Interfaces) { if (!GatherAllInterfaceMethods(tw1, bridges, methods, ref abstractMethodCount, ref bridgeMethodCount)) { return false; } } + return true; } @@ -928,6 +939,7 @@ private static bool IsBridge(RuntimeJavaMethod mw, ClassFile.ConstantPoolItemMet return true; } } + return false; } diff --git a/src/IKVM.Runtime/ReflectUtil.cs b/src/IKVM.Runtime/ReflectUtil.cs index 44c812677..f684f71ef 100644 --- a/src/IKVM.Runtime/ReflectUtil.cs +++ b/src/IKVM.Runtime/ReflectUtil.cs @@ -156,7 +156,7 @@ internal static IMethodSymbolBuilder DefineConstructor(ITypeSymbolBuilder tb, Sy /// /// /// - internal static bool CanOwnDynamicMethod(ITypeSymbol type) + internal static bool CanOwnDynamicMethod(Type type) { return type != null && !type.IsInterface && !type.HasElementType && !type.IsGenericTypeDefinition && !type.IsGenericParameter; } @@ -192,6 +192,15 @@ private static bool MatchTypes(ITypeSymbol[] t1, ITypeSymbol[] t2) return false; } + internal static bool IsVector(Type type) + { +#if NET + return type.IsSZArray; +#else + return type.IsArray && type.Name.EndsWith("[]"); +#endif + } + #if IMPORTER internal static ITypeSymbol GetMissingType(ITypeSymbol type) diff --git a/src/IKVM.Runtime/RuntimeArrayJavaType.cs b/src/IKVM.Runtime/RuntimeArrayJavaType.cs index 95cd1a6c5..5295a96b6 100644 --- a/src/IKVM.Runtime/RuntimeArrayJavaType.cs +++ b/src/IKVM.Runtime/RuntimeArrayJavaType.cs @@ -180,18 +180,6 @@ internal override RuntimeJavaType GetUltimateElementTypeWrapper() return ultimateElementTypeWrapper; } - internal static ITypeSymbol MakeArrayType(ITypeSymbol type, int dims) - { - // NOTE this is not just an optimization, but it is also required to - // make sure that ReflectionOnly types stay ReflectionOnly types - // (in particular instantiations of generic types from mscorlib that - // have ReflectionOnly type parameters). - for (int i = 0; i < dims; i++) - type = type.MakeArrayType(); - - return type; - } - } } diff --git a/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishContext.cs b/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishContext.cs index 9443a3efa..1001ff45a 100644 --- a/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishContext.cs +++ b/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishContext.cs @@ -28,15 +28,12 @@ Jeroen Frijters using IKVM.Attributes; using IKVM.ByteCode; using IKVM.ByteCode.Decoding; -using IKVM.CoreLib.Diagnostics; - +using IKVM.CoreLib.Symbols.Emit; +using IKVM.CoreLib.Symbols; #if IMPORTER -using IKVM.Reflection; -using IKVM.Reflection.Emit; using IKVM.Tools.Importer; -using Type = IKVM.Reflection.Type; using DynamicOrAotTypeWrapper = IKVM.Tools.Importer.RuntimeImportByteCodeJavaType; #else using System.Reflection; @@ -58,15 +55,15 @@ internal sealed class FinishContext readonly RuntimeJavaType host; readonly ClassFile classFile; readonly DynamicOrAotTypeWrapper wrapper; - readonly TypeBuilder typeBuilder; - List nestedTypeBuilders; - MethodInfo callerIDMethod; + readonly ITypeSymbolBuilder typeBuilder; + List nestedTypeBuilders; + IMethodSymbol callerIDMethod; List items; - Dictionary arfuMap; - Dictionary invokespecialstubcache; - Dictionary dynamicClassLiteral; + Dictionary arfuMap; + Dictionary invokespecialstubcache; + Dictionary dynamicClassLiteral; #if IMPORTER - TypeBuilder interfaceHelperMethodsTypeBuilder; + ITypeSymbolBuilder interfaceHelperMethodsTypeBuilder; #else List liveObjects; #endif @@ -85,7 +82,7 @@ private struct Item /// /// /// - internal FinishContext(RuntimeContext context, RuntimeJavaType host, ClassFile classFile, DynamicOrAotTypeWrapper wrapper, TypeBuilder typeBuilder) + internal FinishContext(RuntimeContext context, RuntimeJavaType host, ClassFile classFile, DynamicOrAotTypeWrapper wrapper, ITypeSymbolBuilder typeBuilder) { this.context = context; this.host = host; @@ -124,7 +121,7 @@ internal void EmitDynamicClassLiteral(CodeEmitter ilgen, RuntimeJavaType tw, boo { Debug.Assert(tw.IsUnloadable); - dynamicClassLiteral ??= new Dictionary(); + dynamicClassLiteral ??= new Dictionary(); var cacheKey = tw.Name; if (dynamicCallerID) @@ -183,13 +180,13 @@ internal void EmitCallerID(CodeEmitter ilgen, bool dynamic) private void CreateGetCallerID() { - RuntimeJavaType tw = context.JavaBase.TypeOfIkvmInternalCallerID; - FieldBuilder callerIDField = typeBuilder.DefineField("__", tw.TypeAsSignatureType, FieldAttributes.Private | FieldAttributes.Static | FieldAttributes.SpecialName); - MethodBuilder mb = DefineHelperMethod("__", tw.TypeAsSignatureType, []); + var tw = context.JavaBase.TypeOfIkvmInternalCallerID; + var callerIDField = typeBuilder.DefineField("__", tw.TypeAsSignatureType, FieldAttributes.Private | FieldAttributes.Static | FieldAttributes.SpecialName); + var mb = DefineHelperMethod("__", tw.TypeAsSignatureType, []); callerIDMethod = mb; - CodeEmitter ilgen = context.CodeEmitterFactory.Create(mb); + var ilgen = context.CodeEmitterFactory.Create(mb); ilgen.Emit(OpCodes.Ldsfld, callerIDField); - CodeEmitterLabel done = ilgen.DefineLabel(); + var done = ilgen.DefineLabel(); ilgen.EmitBrtrue(done); EmitCallerIDInitialization(ilgen, callerIDField); ilgen.MarkLabel(done); @@ -232,7 +229,7 @@ internal Type FinishImpl() { foreach (RuntimeJavaMethod mw in parent.GetMethods()) { - var mi = mw.GetMethod() as MethodInfo; + var mi = mw.GetMethod() as IMethodSymbol; if (mi != null && mi.IsAbstract && !mi.DeclaringType.IsInterface) { bool needStub = false; @@ -268,13 +265,13 @@ internal Type FinishImpl() // NOTE in Sun's JRE 1.4.1 this method cannot be overridden by subclasses, // but I think this is a bug, so we'll support it anyway. string name = mi.Name; - MethodAttributes attr = mi.Attributes & ~(MethodAttributes.Abstract | MethodAttributes.NewSlot); + var attr = mi.Attributes & ~(MethodAttributes.Abstract | MethodAttributes.NewSlot); if (needRename) { name = "__<>" + name + "/" + mi.DeclaringType.FullName; attr = MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.NewSlot; } - MethodBuilder mb = mw.GetDefineMethodHelper().DefineMethod(wrapper, typeBuilder, name, attr); + var mb = mw.GetDefineMethodHelper().DefineMethod(wrapper, typeBuilder, name, attr); if (needRename) { typeBuilder.DefineMethodOverride(mb, mi); @@ -300,7 +297,7 @@ internal Type FinishImpl() for (int i = 0; i < classFile.Methods.Length; i++) { var m = classFile.Methods[i]; - var mb = (MethodBuilder)methods[i].GetMethod(); + var mb = (IMethodSymbolBuilder)methods[i].GetMethod(); if (mb == null) { // method doesn't really exist (e.g. delegate constructor or that is optimized away) @@ -386,7 +383,7 @@ internal Type FinishImpl() } #endif - MethodInfo nativeMethod = null; + IMethodSymbol nativeMethod = null; var args = methods[i].GetParameters(); var nargs = args; @@ -512,7 +509,7 @@ internal Type FinishImpl() { if (m.IsVirtual && classFile.IsInterface) { - mb = (MethodBuilder)RuntimeDefaultInterfaceJavaMethod.GetImpl(methods[i]); + mb = (IMethodSymbolBuilder)RuntimeDefaultInterfaceJavaMethod.GetImpl(methods[i]); #if IMPORTER CreateDefaultMethodInterop(ref tbDefaultMethods, mb, methods[i]); #endif @@ -561,10 +558,10 @@ internal Type FinishImpl() if (clinitIndex != -1 || (basehasclinit && !classFile.IsInterface) || classFile.HasInitializedFields) { - MethodBuilder cb; + IMethodSymbolBuilder cb; if (clinitIndex != -1) { - cb = (MethodBuilder)methods[clinitIndex].GetMethod(); + cb = (IMethodSymbolBuilder)methods[clinitIndex].GetMethod(); } else { @@ -662,7 +659,7 @@ internal Type FinishImpl() for (int i = 0; i < classFile.Methods.Length; i++) { var m = classFile.Methods[i]; - var mb = (MethodBuilder)methods[i].GetMethod(); + var mb = (IMethodSymbolBuilder)methods[i].GetMethod(); if (mb == null) continue; @@ -708,7 +705,7 @@ internal Type FinishImpl() } else { - annotation.Apply(wrapper.ClassLoader, (FieldBuilder)fields[i].GetField(), def); + annotation.Apply(wrapper.ClassLoader, (IFieldSymbolBuilder)fields[i].GetField(), def); } } } @@ -730,22 +727,21 @@ internal Type FinishImpl() AddImplementsAttribute(); #endif - Type type; Profiler.Enter("TypeBuilder.CreateType"); try { - type = typeBuilder.CreateType(); + typeBuilder.Complete(); if (nestedTypeBuilders != null) { context.ClassLoaderFactory.LoadClassCritical("ikvm.internal.IntrinsicAtomicReferenceFieldUpdater").Finish(); context.ClassLoaderFactory.LoadClassCritical("ikvm.internal.IntrinsicThreadLocal").Finish(); - foreach (TypeBuilder tb in nestedTypeBuilders) - tb.CreateType(); + foreach (var tb in nestedTypeBuilders) + tb.Complete(); } #if !IMPORTER if (liveObjects != null) - typeof(IKVM.Runtime.LiveObjectHolder<>).MakeGenericType(type).GetField("values", BindingFlags.Static | BindingFlags.Public).SetValue(null, liveObjects.ToArray()); + context.Resolver.ResolveRuntimeType("IKVM.Runtime.LiveObjectHolder`1").GetField("values", BindingFlags.Static | BindingFlags.Public).AsReflection().SetValue(liveObjects.ToArray()); #endif } finally @@ -754,14 +750,14 @@ internal Type FinishImpl() } #if !IMPORTER // When we're statically compiling we don't need to set the wrapper here, because we've already done so for the typeBuilder earlier. - context.ClassLoaderFactory.SetWrapperForType(type, wrapper); + context.ClassLoaderFactory.SetWrapperForType(typeBuilder, wrapper); #endif #if IMPORTER wrapper.FinishGhostStep2(); #endif - return type; + return typeBuilder; } #if IMPORTER @@ -1006,7 +1002,7 @@ private bool EmitInterlockedCompareAndSet(RuntimeJavaMethod method, string field } #endif - private void AddMethodParameterInfo(ClassFile.Method m, RuntimeJavaMethod mw, MethodBuilder mb, out string[] parameterNames) + private void AddMethodParameterInfo(ClassFile.Method m, RuntimeJavaMethod mw, IMethodSymbolBuilder mb, out string[] parameterNames) { parameterNames = null; ParameterBuilder[] parameterBuilders = null; @@ -1116,7 +1112,7 @@ void AddInterfaceMethodsInterop(RuntimeJavaMethod[] methods) } - private void CreateDefaultMethodInterop(ref TypeBuilder tbDefaultMethods, MethodBuilder defaultMethod, RuntimeJavaMethod mw) + private void CreateDefaultMethodInterop(ref TypeBuilder tbDefaultMethods, IMethodSymbolBuilder defaultMethod, RuntimeJavaMethod mw) { if (!ParametersAreAccessible(mw)) { @@ -1169,7 +1165,7 @@ private void AddInheritedDefaultInterfaceMethods(RuntimeJavaMethod[] methods) if (mmw.Error == null && !mmw.BaseMethod.IsAbstract) { // we inherited a default interface method, so we need to forward the miranda method to the default method - MethodBuilder mb = (MethodBuilder)mmw.GetMethod(); + var mb = (IMethodSymbolBuilder)mmw.GetMethod(); if (classFile.IsInterface) { // if we're an interface with a default miranda method, we need to create a new default method that forwards to the original @@ -1182,7 +1178,7 @@ private void AddInheritedDefaultInterfaceMethods(RuntimeJavaMethod[] methods) } } - internal void EmitCallDefaultInterfaceMethod(MethodBuilder mb, RuntimeJavaMethod defaultMethod) + internal void EmitCallDefaultInterfaceMethod(IMethodSymbolBuilder mb, RuntimeJavaMethod defaultMethod) { CodeEmitter ilgen = context.CodeEmitterFactory.Create(mb); if (defaultMethod.DeclaringType.IsGhost) @@ -1287,7 +1283,7 @@ void GenerateAccessStub(RuntimeJavaField fw, bool type1) // we attach the AccessStub custom modifier because the C# compiler prefers fields without custom modifiers // so if this class defines a field with the same name, that will be preferred over this one by the C# compiler - var fb = typeBuilder.DefineField(fw.Name, fw.FieldTypeWrapper.TypeAsSignatureType, null, new Type[] { context.Resolver.ResolveRuntimeType(typeof(IKVM.Attributes.AccessStub).FullName).AsReflection() }, attribs); + var fb = typeBuilder.DefineField(fw.Name, fw.FieldTypeWrapper.TypeAsSignatureType, null, new ITypeSymbol[] { context.Resolver.ResolveRuntimeType(typeof(IKVM.Attributes.AccessStub).FullName) }, attribs); context.AttributeHelper.HideFromReflection(fb); fb.SetConstant(cjf.GetConstantValue()); } @@ -1327,7 +1323,7 @@ void GenerateAccessStub(RuntimeJavaField fw, bool type1) attribs |= MethodAttributes.Private; } - var setter = typeBuilder.DefineMethod("set_" + fw.Name, attribs, CallingConventions.Standard, null, null, null, new Type[] { propType }, null, new Type[][] { modopt2 }); + var setter = typeBuilder.DefineMethod("set_" + fw.Name, attribs, CallingConventions.Standard, null, null, null, new ITypeSymbol[] { propType }, null, new ITypeSymbol[][] { modopt2 }); context.AttributeHelper.HideFromJava(setter); pb.SetSetMethod(setter); ilgen = context.CodeEmitterFactory.Create(setter); @@ -1393,9 +1389,9 @@ void GenerateAccessStub(int id, RuntimeJavaMethod mw, bool virt, bool type1) stubattribs |= MethodAttributes.Static; var parameters = mw.GetParameters(); - var realParameterTypes = new Type[parameters.Length]; - var parameterTypes = new Type[parameters.Length]; - var modopt = new Type[parameters.Length][]; + var realParameterTypes = new ITypeSymbol[parameters.Length]; + var parameterTypes = new ITypeSymbol[parameters.Length]; + var modopt = new ITypeSymbol[parameters.Length][]; for (int i = 0; i < parameters.Length; i++) { realParameterTypes[i] = parameters[i].TypeAsSignatureType; @@ -1538,7 +1534,7 @@ void ImplementInterfaceMethodStubImpl(RuntimeJavaMethod ifmethod, bool baseClass var ilgen = context.CodeEmitterFactory.Create(mb); ilgen.EmitThrow("java.lang.LinkageError", wrapper.Name + "." + ifmethod.Name + ifmethod.Signature); ilgen.DoEmit(); - typeBuilder.DefineMethodOverride(mb, (MethodInfo)ifmethod.GetMethod()); + typeBuilder.DefineMethodOverride(mb, (IMethodSymbol)ifmethod.GetMethod()); return; } } @@ -1555,7 +1551,7 @@ void ImplementInterfaceMethodStubImpl(RuntimeJavaMethod ifmethod, bool baseClass var ilgen = context.CodeEmitterFactory.Create(mb); ilgen.EmitThrow("java.lang.IllegalAccessError", wrapper.Name + "." + ifmethod.Name + ifmethod.Signature); ilgen.DoEmit(); - typeBuilder.DefineMethodOverride(mb, (MethodInfo)ifmethod.GetMethod()); + typeBuilder.DefineMethodOverride(mb, (IMethodSymbol)ifmethod.GetMethod()); wrapper.SetHasIncompleteInterfaceImplementation(); } else if (mce.GetMethod() == null || mce.RealName != ifmethod.RealName || mce.IsInternal || !ReflectUtil.IsSameAssembly(mce.DeclaringType.TypeAsTBD, typeBuilder) || CheckRequireOverrideStub(mce, ifmethod)) @@ -1567,7 +1563,7 @@ void ImplementInterfaceMethodStubImpl(RuntimeJavaMethod ifmethod, bool baseClass } else if (baseClassInterface && mce.DeclaringType == wrapper) { - typeBuilder.DefineMethodOverride((MethodInfo)mce.GetMethod(), (MethodInfo)ifmethod.GetMethod()); + typeBuilder.DefineMethodOverride((IMethodSymbol)mce.GetMethod(), (IMethodSymbol)ifmethod.GetMethod()); } } else @@ -1581,14 +1577,14 @@ void ImplementInterfaceMethodStubImpl(RuntimeJavaMethod ifmethod, bool baseClass var ilgen = context.CodeEmitterFactory.Create(mb); ilgen.EmitThrow("java.lang.AbstractMethodError", wrapper.Name + "." + ifmethod.Name + ifmethod.Signature); ilgen.DoEmit(); - typeBuilder.DefineMethodOverride(mb, (MethodInfo)ifmethod.GetMethod()); + typeBuilder.DefineMethodOverride(mb, (IMethodSymbol)ifmethod.GetMethod()); wrapper.SetHasIncompleteInterfaceImplementation(); wrapper.EmitLevel4Warning(HardError.AbstractMethodError, wrapper.Name + "." + ifmethod.Name + ifmethod.Signature); } } } - MethodBuilder DefineInterfaceStubMethod(string name, RuntimeJavaMethod mw) + IMethodSymbolBuilder DefineInterfaceStubMethod(string name, RuntimeJavaMethod mw) { return mw.GetDefineMethodHelper().DefineMethod(wrapper, typeBuilder, name, MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.Final); } @@ -1613,9 +1609,9 @@ static JniProxyBuilder() internal static void Generate(RuntimeByteCodeJavaType.FinishContext context, CodeEmitter ilGenerator, RuntimeByteCodeJavaType wrapper, RuntimeJavaMethod mw, TypeBuilder typeBuilder, ClassFile classFile, ClassFile.Method m, RuntimeJavaType[] args) { - TypeBuilder tb = mod.DefineType("__" + System.Threading.Interlocked.Increment(ref count), TypeAttributes.Public | TypeAttributes.Class); + var tb = mod.DefineType("__" + System.Threading.Interlocked.Increment(ref count), TypeAttributes.Public | TypeAttributes.Class); int instance = m.IsStatic ? 0 : 1; - Type[] argTypes = new Type[args.Length + instance + 1]; + var argTypes = new ITypeSymbolvvvvvvvvvvvvvvvv[args.Length + instance + 1]; if (instance != 0) { argTypes[0] = typeof(object); @@ -1626,9 +1622,10 @@ internal static void Generate(RuntimeByteCodeJavaType.FinishContext context, Cod // are public and so we can get away with replacing all other types with object. argTypes[i + instance] = !args[i].IsUnloadable && (args[i].IsPrimitive || args[i].IsGhost || args[i].IsNonPrimitiveValueType) ? args[i].TypeAsSignatureType : typeof(object); } + argTypes[argTypes.Length - 1] = context.context.JavaBase.TypeOfIkvmInternalCallerID.TypeAsSignatureType; - Type retType = !mw.ReturnType.IsUnloadable && (mw.ReturnType.IsPrimitive || mw.ReturnType.IsGhost || mw.ReturnType.IsNonPrimitiveValueType) ? mw.ReturnType.TypeAsSignatureType : typeof(object); - MethodBuilder mb = tb.DefineMethod("method", MethodAttributes.Public | MethodAttributes.Static, retType, argTypes); + var retType = !mw.ReturnType.IsUnloadable && (mw.ReturnType.IsPrimitive || mw.ReturnType.IsGhost || mw.ReturnType.IsNonPrimitiveValueType) ? mw.ReturnType.TypeAsSignatureType : typeof(object); + var mb = tb.DefineMethod("method", MethodAttributes.Public | MethodAttributes.Static, retType, argTypes); context.context.AttributeHelper.HideFromJava(mb); CodeEmitter ilgen = context.context.CodeEmitterFactory.Create(mb); new JniBuilder(context.context).Generate(context, ilgen, wrapper, mw, tb, classFile, m, args, true); @@ -1665,23 +1662,23 @@ public JniBuilder(RuntimeContext context) Type LocalRefStructType => context.Resolver.ResolveRuntimeType("IKVM.Runtime.JNI.JNIFrame").AsReflection(); - MethodInfo JniFuncPtrMethod => LocalRefStructType.GetMethod("GetFuncPtr"); + IMethodSymbol JniFuncPtrMethod => LocalRefStructType.GetMethod("GetFuncPtr"); - MethodInfo EnterLocalRefStructMethod => LocalRefStructType.GetMethod("Enter"); + IMethodSymbol EnterLocalRefStructMethod => LocalRefStructType.GetMethod("Enter"); - MethodInfo LeaveLocalRefStructMethod => LocalRefStructType.GetMethod("Leave"); + IMethodSymbol LeaveLocalRefStructMethod => LocalRefStructType.GetMethod("Leave"); - MethodInfo MakeLocalRefMethod => LocalRefStructType.GetMethod("MakeLocalRef"); + IMethodSymbol MakeLocalRefMethod => LocalRefStructType.GetMethod("MakeLocalRef"); - MethodInfo UnwrapLocalRefMethod => LocalRefStructType.GetMethod("UnwrapLocalRef"); + IMethodSymbol UnwrapLocalRefMethod => LocalRefStructType.GetMethod("UnwrapLocalRef"); - MethodInfo WriteLineMethod => context.Resolver.ResolveCoreType(typeof(Console).FullName).AsReflection().GetMethod("WriteLine", [context.Types.Object]); + IMethodSymbol WriteLineMethod => context.Resolver.ResolveCoreType(typeof(Console).FullName).GetMethod("WriteLine", [context.Types.Object]); - MethodInfo MonitorEnterMethod => context.Resolver.ResolveCoreType(typeof(System.Threading.Monitor).FullName).AsReflection().GetMethod("Enter", [context.Types.Object]); + IMethodSymbol MonitorEnterMethod => context.Resolver.ResolveCoreType(typeof(System.Threading.Monitor).FullName).GetMethod("Enter", [context.Types.Object]); - MethodInfo MonitorExitMethod => context.Resolver.ResolveCoreType(typeof(System.Threading.Monitor).FullName).AsReflection().GetMethod("Exit", [context.Types.Object]); + IMethodSymbol MonitorExitMethod => context.Resolver.ResolveCoreType(typeof(System.Threading.Monitor).FullName).GetMethod("Exit", [context.Types.Object]); - internal void Generate(RuntimeByteCodeJavaType.FinishContext context, CodeEmitter ilGenerator, RuntimeByteCodeJavaType wrapper, RuntimeJavaMethod mw, TypeBuilder typeBuilder, ClassFile classFile, ClassFile.Method m, RuntimeJavaType[] args, bool thruProxy) + internal void Generate(RuntimeByteCodeJavaType.FinishContext context, CodeEmitter ilGenerator, RuntimeByteCodeJavaType wrapper, RuntimeJavaMethod mw, ITypeSymbolBuilder typeBuilder, ClassFile classFile, ClassFile.Method m, RuntimeJavaType[] args, bool thruProxy) { CodeEmitterLocal syncObject = null; if (m.IsSynchronized && m.IsStatic) @@ -1734,7 +1731,7 @@ internal void Generate(RuntimeByteCodeJavaType.FinishContext context, CodeEmitte ilGenerator.Emit(OpCodes.Ldloc, jnienv); - var modargs = new Type[args.Length + 2]; + var modargs = new ITypeSymbol[args.Length + 2]; modargs[0] = context.context.Types.IntPtr; modargs[1] = context.context.Types.IntPtr; for (int i = 0; i < args.Length; i++) @@ -1861,7 +1858,7 @@ void EmitCallerIDStub(RuntimeJavaMethod mw, string[] parameterNames) { // we don't need to support custom modifiers, because there aren't any callerid methods that have parameter types that require a custom modifier var parameters = mw.GetParameters(); - var parameterTypes = new Type[parameters.Length]; + var parameterTypes = new ITypeSymbol[parameters.Length]; for (int i = 0; i < parameterTypes.Length; i++) parameterTypes[i] = parameters[i].TypeAsSignatureType; @@ -1910,7 +1907,7 @@ void EmitCallerIDStub(RuntimeJavaMethod mw, string[] parameterNames) } ilgen.Emit(OpCodes.Ldc_I4_1); ilgen.Emit(OpCodes.Ldc_I4_0); - ilgen.Emit(OpCodes.Newobj, context.Resolver.ResolveCoreType(typeof(StackFrame).FullName).AsReflection().GetConstructor(new Type[] { context.Types.Int32, context.Types.Boolean })); + ilgen.Emit(OpCodes.Newobj, context.Resolver.ResolveCoreType(typeof(StackFrame).FullName).AsReflection().GetConstructor(new ITypeSymbol[] { context.Types.Int32, context.Types.Boolean })); var callerID = context.JavaBase.TypeOfIkvmInternalCallerID.GetMethodWrapper("create", "(Lcli.System.Diagnostics.StackFrame;)Likvm.internal.CallerID;", false); callerID.Link(); callerID.EmitCall(ilgen); @@ -1966,7 +1963,7 @@ void ImplementInterfaces(RuntimeJavaType[] interfaces, List int // if we implement a ghost interface, add an implicit conversion to the ghost reference value type if (iface.IsGhost && wrapper.IsPublic) { - var mb = typeBuilder.DefineMethod("op_Implicit", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.SpecialName, iface.TypeAsSignatureType, new Type[] { wrapper.TypeAsSignatureType }); + var mb = typeBuilder.DefineMethod("op_Implicit", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.SpecialName, iface.TypeAsSignatureType, new ITypeSymbol[] { wrapper.TypeAsSignatureType }); context.AttributeHelper.HideFromJava(mb); var ilgen = context.CodeEmitterFactory.Create(mb); var local = ilgen.DeclareLocal(iface.TypeAsSignatureType); @@ -2014,25 +2011,25 @@ void AddUnsupportedAbstractMethods() } } - void GenerateUnsupportedAbstractMethodStub(MethodBase mb) + void GenerateUnsupportedAbstractMethodStub(IMethodBaseSymbol mb) { var parameters = mb.GetParameters(); - var parameterTypes = new Type[parameters.Length]; + var parameterTypes = new ITypeSymbol[parameters.Length]; for (int i = 0; i < parameters.Length; i++) parameterTypes[i] = parameters[i].ParameterType; var attr = MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Private; - var m = typeBuilder.DefineMethod("__" + mb.DeclaringType.FullName + "/" + mb.Name, attr, ((MethodInfo)mb).ReturnType, parameterTypes); + var m = typeBuilder.DefineMethod("__" + mb.DeclaringType.FullName + "/" + mb.Name, attr, ((IMethodSymbol)mb).ReturnType, parameterTypes); if (mb.IsGenericMethodDefinition) CopyGenericArguments(mb, m); var ilgen = context.CodeEmitterFactory.Create(m); ilgen.EmitThrow("java.lang.AbstractMethodError", "Method " + mb.DeclaringType.FullName + "." + mb.Name + " is unsupported by IKVM."); ilgen.DoEmit(); - typeBuilder.DefineMethodOverride(m, (MethodInfo)mb); + typeBuilder.DefineMethodOverride(m, (IMethodSymbol)mb); } - void CopyGenericArguments(MethodBase mi, MethodBuilder mb) + void CopyGenericArguments(IMethodBaseSymbol mi, IMethodSymbolBuilder mb) { var genericParameters = mi.GetGenericArguments(); var genParamNames = new string[genericParameters.Length]; @@ -2068,7 +2065,7 @@ void CompileConstructorBody(FinishContext context, CodeEmitter ilGenerator, int Compiler.Compile(context, host, wrapper, methods[methodIndex], classFile, m, ilGenerator, ref nonLeaf); ilGenerator.DoEmit(); #if IMPORTER - ilGenerator.EmitLineNumberTable((MethodBuilder)methods[methodIndex].GetMethod()); + ilGenerator.EmitLineNumberTable((IMethodSymbolBuilder)methods[methodIndex].GetMethod()); #else // IMPORTER var linenumbers = ilGenerator.GetLineNumberTable(); if (linenumbers != null) @@ -2117,7 +2114,7 @@ void EmitCallerIDInitialization(CodeEmitter ilGenerator, FieldInfo callerIDField ilGenerator.Emit(OpCodes.Stsfld, callerIDField); } - internal static TypeBuilder EmitCreateCallerID(RuntimeContext context, TypeBuilder typeBuilder, CodeEmitter ilGenerator) + internal static ITypeSymbolBuilder EmitCreateCallerID(RuntimeContext context, ITypeSymbolBuilder typeBuilder, CodeEmitter ilGenerator) { var tw = context.JavaBase.TypeOfIkvmInternalCallerID; var typeCallerID = typeBuilder.DefineNestedType(NestedTypeName.CallerID, TypeAttributes.Sealed | TypeAttributes.NestedPrivate, tw.TypeAsBaseType); @@ -2190,7 +2187,7 @@ void EmitConstantValueInitialization(RuntimeJavaField[] fields, CodeEmitter ilGe } } - internal MethodBuilder DefineThreadLocalType() + internal IMethodSymbolBuilder DefineThreadLocalType() { var threadLocal = context.ClassLoaderFactory.LoadClassCritical("ikvm.internal.IntrinsicThreadLocal"); int id = nestedTypeBuilders == null ? 0 : nestedTypeBuilders.Count; @@ -2222,14 +2219,14 @@ internal MethodBuilder DefineThreadLocalType() return cb; } - internal MethodBuilder GetAtomicReferenceFieldUpdater(RuntimeJavaField field) + internal IMethodSymbolBuilder GetAtomicReferenceFieldUpdater(RuntimeJavaField field) { - arfuMap ??= new Dictionary(); + arfuMap ??= new Dictionary(); if (!arfuMap.TryGetValue(field, out var cb)) { - RuntimeJavaType arfuTypeWrapper = context.ClassLoaderFactory.LoadClassCritical("ikvm.internal.IntrinsicAtomicReferenceFieldUpdater"); - TypeBuilder tb = typeBuilder.DefineNestedType(NestedTypeName.AtomicReferenceFieldUpdater + arfuMap.Count, TypeAttributes.NestedPrivate | TypeAttributes.Sealed, arfuTypeWrapper.TypeAsBaseType); + var arfuTypeWrapper = context.ClassLoaderFactory.LoadClassCritical("ikvm.internal.IntrinsicAtomicReferenceFieldUpdater"); + var tb = typeBuilder.DefineNestedType(NestedTypeName.AtomicReferenceFieldUpdater + arfuMap.Count, TypeAttributes.NestedPrivate | TypeAttributes.Sealed, arfuTypeWrapper.TypeAsBaseType); AtomicReferenceFieldUpdaterEmitter.EmitImpl(context, tb, field.GetField()); cb = ReflectUtil.DefineConstructor(tb, MethodAttributes.Assembly, []); arfuMap.Add(field, cb); @@ -2245,7 +2242,7 @@ internal MethodBuilder GetAtomicReferenceFieldUpdater(RuntimeJavaField field) return cb; } - internal TypeBuilder DefineIndyCallSiteType() + internal ITypeSymbolBuilder DefineIndyCallSiteType() { int id = nestedTypeBuilders == null ? 0 : nestedTypeBuilders.Count; var tb = typeBuilder.DefineNestedType(NestedTypeName.IndyCallSite + id, TypeAttributes.NestedPrivate | TypeAttributes.Abstract | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit); @@ -2253,14 +2250,14 @@ internal TypeBuilder DefineIndyCallSiteType() return tb; } - internal TypeBuilder DefineMethodHandleConstantType(MethodHandleConstantHandle handle) + internal ITypeSymbolBuilder DefineMethodHandleConstantType(MethodHandleConstantHandle handle) { var tb = typeBuilder.DefineNestedType(NestedTypeName.MethodHandleConstant + handle.Slot, TypeAttributes.NestedPrivate | TypeAttributes.Sealed | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit); ; RegisterNestedTypeBuilder(tb); return tb; } - internal TypeBuilder DefineMethodTypeConstantType(MethodTypeConstantHandle handle) + internal ITypeSymbolBuilder DefineMethodTypeConstantType(MethodTypeConstantHandle handle) { var tb = typeBuilder.DefineNestedType(NestedTypeName.MethodTypeConstant + handle.Slot, TypeAttributes.NestedPrivate | TypeAttributes.Sealed | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit); RegisterNestedTypeBuilder(tb); @@ -2268,7 +2265,7 @@ internal TypeBuilder DefineMethodTypeConstantType(MethodTypeConstantHandle handl } // this is used to define intrinsified anonymous classes (in the Unsafe.defineAnonymousClass() sense) - internal TypeBuilder DefineAnonymousClass() + internal ITypeSymbolBuilder DefineAnonymousClass() { int id = nestedTypeBuilders == null ? 0 : nestedTypeBuilders.Count; var tb = typeBuilder.DefineNestedType(NestedTypeName.IntrinsifiedAnonymousClass + id, TypeAttributes.NestedPrivate | TypeAttributes.Sealed | TypeAttributes.SpecialName | TypeAttributes.BeforeFieldInit); @@ -2276,39 +2273,39 @@ internal TypeBuilder DefineAnonymousClass() return tb; } - MethodBuilder DefineHelperMethod(string name, Type returnType, Type[] parameterTypes) + IMethodSymbolBuilder DefineHelperMethod(string name, ITypeSymbol returnType, ITypeSymbol[] parameterTypes) { return typeBuilder.DefineMethod(name, MethodAttributes.PrivateScope | MethodAttributes.Static, returnType, parameterTypes); } - internal MethodBuilder DefineMethodHandleDispatchStub(Type returnType, Type[] parameterTypes) + internal IMethodSymbolBuilder DefineMethodHandleDispatchStub(ITypeSymbol returnType, ITypeSymbol[] parameterTypes) { return DefineHelperMethod("__<>MHC", returnType, parameterTypes); } - internal FieldBuilder DefineMethodHandleInvokeCacheField(Type fieldType) + internal IFieldSymbolBuilder DefineMethodHandleInvokeCacheField(ITypeSymbol fieldType) { return typeBuilder.DefineField("__<>invokeCache", fieldType, FieldAttributes.Static | FieldAttributes.PrivateScope); } - internal FieldBuilder DefineDynamicMethodHandleCacheField() + internal IFieldSymbolBuilder DefineDynamicMethodHandleCacheField() { return typeBuilder.DefineField("__<>dynamicMethodHandleCache", context.JavaBase.TypeOfJavaLangInvokeMethodHandle.TypeAsSignatureType, FieldAttributes.Static | FieldAttributes.PrivateScope); } - internal FieldBuilder DefineDynamicMethodTypeCacheField() + internal IFieldSymbolBuilder DefineDynamicMethodTypeCacheField() { return typeBuilder.DefineField("__<>dynamicMethodTypeCache", context.JavaBase.TypeOfJavaLangInvokeMethodType.TypeAsSignatureType, FieldAttributes.Static | FieldAttributes.PrivateScope); } - internal MethodBuilder DefineDelegateInvokeErrorStub(Type returnType, Type[] parameterTypes) + internal IMethodSymbolBuilder DefineDelegateInvokeErrorStub(ITypeSymbol returnType, ITypeSymbol[] parameterTypes) { return DefineHelperMethod("__<>", returnType, parameterTypes); } - internal MethodInfo GetInvokeSpecialStub(RuntimeJavaMethod method) + internal IMethodSymbol GetInvokeSpecialStub(RuntimeJavaMethod method) { - invokespecialstubcache ??= new Dictionary(); + invokespecialstubcache ??= new Dictionary(); var key = new MethodKey(method.DeclaringType.Name, method.Name, method.Signature); @@ -2335,8 +2332,7 @@ internal MethodInfo GetInvokeSpecialStub(RuntimeJavaMethod method) internal void EmitLiveObjectLoad(CodeEmitter ilgen, object value) { liveObjects ??= new List(); - var fi = TypeBuilder.GetField(typeof(IKVM.Runtime.LiveObjectHolder<>).MakeGenericType(typeBuilder), typeof(IKVM.Runtime.LiveObjectHolder<>).GetField("values", BindingFlags.Static | BindingFlags.Public)); - ilgen.Emit(OpCodes.Ldsfld, fi); + ilgen.Emit(OpCodes.Ldsfld, context.Resolver.ResolveRuntimeType("IKVM.Runtime.LiveObjectHolder`1").MakeGenericType(typeBuilder).GetField("values", BindingFlags.Static | BindingFlags.Public)); ilgen.EmitLdc_I4(liveObjects.Count); ilgen.Emit(OpCodes.Ldelem_Ref); liveObjects.Add(value); diff --git a/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.cs b/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.cs index ffa19a858..5f5053619 100644 --- a/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.cs +++ b/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.cs @@ -1812,7 +1812,7 @@ internal void Finish(JavaTypeImpl o) getValueMethod.EmitCall(ilgen); o.methods[i].ReturnType.EmitCheckcast(ilgen); } - ilgen.Emit(OpCodes.Ret); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ret); ilgen.DoEmit(); if (o.classFile.Methods[i].AnnotationDefault != null @@ -1822,16 +1822,16 @@ internal void Finish(JavaTypeImpl o) Type argType = TypeWrapperToAnnotationParameterType(o.methods[i].ReturnType); if (argType != null) { - PropertyBuilder pb = attributeTypeBuilder.DefineProperty(o.methods[i].Name, PropertyAttributes.None, argType, []); + var pb = attributeTypeBuilder.DefineProperty(o.methods[i].Name, PropertyAttributes.None, argType, []); context.AttributeHelper.HideFromJava(pb); - MethodBuilder setter = attributeTypeBuilder.DefineMethod("set_" + o.methods[i].Name, MethodAttributes.Public, context.Types.Void, new Type[] { argType }); + var setter = attributeTypeBuilder.DefineMethod("set_" + o.methods[i].Name, MethodAttributes.Public, context.Types.Void, new ITypeSymbol[] { argType }); context.AttributeHelper.HideFromJava(setter); pb.SetSetMethod(setter); ilgen = context.CodeEmitterFactory.Create(setter); EmitSetValueCall(annotationAttributeBaseType, ilgen, o.methods[i].Name, o.methods[i].ReturnType, 1); - ilgen.Emit(OpCodes.Ret); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ret); ilgen.DoEmit(); - MethodBuilder getter = attributeTypeBuilder.DefineMethod("get_" + o.methods[i].Name, MethodAttributes.Public, argType, []); + var getter = attributeTypeBuilder.DefineMethod("get_" + o.methods[i].Name, MethodAttributes.Public, argType, []); context.AttributeHelper.HideFromJava(getter); pb.SetGetMethod(getter); // TODO implement the getter method @@ -2129,7 +2129,7 @@ bool IsAccessibleInternal(RuntimeJavaMethod mw) return mw.IsInternal && mw.DeclaringType.InternalsVisibleTo(wrapper); } - static MethodBase LinkAndGetMethod(RuntimeJavaMethod mw) + static IMethodSymbol LinkAndGetMethod(RuntimeJavaMethod mw) { mw.Link(); return mw.GetMethod(); @@ -2260,7 +2260,7 @@ RuntimeJavaMethod[] FindBaseMethodsLegacy(string name, string sig, out bool expl return null; } - static MethodInfo GetBaseFinalizeMethod(RuntimeJavaType wrapper) + static IMethodSymbol GetBaseFinalizeMethod(RuntimeJavaType wrapper) { for (; ; ) { @@ -2294,7 +2294,7 @@ static MethodInfo GetBaseFinalizeMethod(RuntimeJavaType wrapper) while (type != null) { - foreach (MethodInfo m in type.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)) + foreach (var m in type.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)) { if (m.Name == "Finalize" && m.ReturnType == wrapper.Context.Types.Void @@ -2467,7 +2467,7 @@ internal override IMethodBaseSymbol LinkMethod(RuntimeJavaMethod mw) } var m = classFile.Methods[index]; - MethodBuilder method; + IMethodSymbolBuilder method; bool setModifiers = false; if (methods[index].HasCallerID && (m.Modifiers & Modifiers.VarArgs) != 0) @@ -2573,12 +2573,12 @@ private bool HasSerialVersionUID } } - MethodBuilder GenerateConstructor(RuntimeJavaMethod mw) + IMethodSymbolBuilder GenerateConstructor(RuntimeJavaMethod mw) { return mw.GetDefineMethodHelper().DefineConstructor(wrapper, typeBuilder, GetMethodAccess(mw) | MethodAttributes.HideBySig); } - MethodBuilder GenerateMethod(int index, ClassFile.Method m, ref bool setModifiers) + IMethodSymbolBuilder GenerateMethod(int index, ClassFile.Method m, ref bool setModifiers) { var attribs = MethodAttributes.HideBySig; if (m.IsNative) @@ -2630,6 +2630,7 @@ MethodBuilder GenerateMethod(int index, ClassFile.Method m, ref bool setModifier setModifiers = true; } } + if (m.IsFinal) { if (m.IsVirtual) @@ -2641,6 +2642,7 @@ MethodBuilder GenerateMethod(int index, ClassFile.Method m, ref bool setModifier setModifiers = true; } } + if (m.IsStatic) { attribs |= MethodAttributes.Static; @@ -2653,7 +2655,8 @@ MethodBuilder GenerateMethod(int index, ClassFile.Method m, ref bool setModifier { attribs |= MethodAttributes.Virtual | MethodAttributes.CheckAccessOnOverride; } - string name = UnicodeUtil.EscapeInvalidSurrogates(m.Name); + + var name = UnicodeUtil.EscapeInvalidSurrogates(m.Name); if (!ReferenceEquals(name, m.Name)) { // mark as specialname to remind us to unescape the name @@ -2689,9 +2692,9 @@ MethodBuilder GenerateMethod(int index, ClassFile.Method m, ref bool setModifier // if we have a method overriding a more accessible method (the JVM allows this), we need to make the // method more accessible, because otherwise the CLR will complain that we're reducing access bool hasPublicBaseMethod = false; - foreach (RuntimeJavaMethod baseMethodWrapper in baseMethods[index]) + foreach (var baseMethodWrapper in baseMethods[index]) { - MethodBase baseMethod = baseMethodWrapper.GetMethod(); + var baseMethod = baseMethodWrapper.GetMethod(); if ((baseMethod.IsPublic && !m.IsPublic) || ((baseMethod.IsFamily || baseMethod.IsFamilyOrAssembly) && !m.IsPublic && !m.IsProtected) || (!m.IsPublic && !m.IsProtected && !baseMethodWrapper.DeclaringType.IsPackageAccessibleFrom(wrapper))) @@ -2704,7 +2707,8 @@ MethodBuilder GenerateMethod(int index, ClassFile.Method m, ref bool setModifier } } } - MethodBuilder mb = null; + + IMethodSymbolBuilder mb = null; #if IMPORTER mb = wrapper.DefineGhostMethod(typeBuilder, name, attribs, methods[index]); #endif @@ -2830,15 +2834,15 @@ MethodBuilder GenerateMethod(int index, ClassFile.Method m, ref bool setModifier var ilgen = wrapper.Context.CodeEmitterFactory.Create(finalizeMethod); ilgen.EmitLdarg(0); - ilgen.Emit(OpCodes.Call, wrapper.Context.ByteCodeHelperMethods.SkipFinalizerOf); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, wrapper.Context.ByteCodeHelperMethods.SkipFinalizerOf); var skip = ilgen.DefineLabel(); ilgen.EmitBrtrue(skip); if (needDispatch) { ilgen.BeginExceptionBlock(); - ilgen.Emit(OpCodes.Ldarg_0); - ilgen.Emit(OpCodes.Callvirt, mb); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); + ilgen.Emit(System.Reflection.Emit.OpCodes.Callvirt, mb); ilgen.EmitLeave(skip); ilgen.BeginCatchBlock(wrapper.Context.Types.Object); ilgen.EmitLeave(skip); @@ -2846,12 +2850,12 @@ MethodBuilder GenerateMethod(int index, ClassFile.Method m, ref bool setModifier } else { - ilgen.Emit(OpCodes.Ldarg_0); - ilgen.Emit(OpCodes.Call, baseFinalize); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, baseFinalize); } ilgen.MarkLabel(skip); - ilgen.Emit(OpCodes.Ret); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ret); ilgen.DoEmit(); } #if IMPORTER diff --git a/src/IKVM.Runtime/RuntimeJavaField.cs b/src/IKVM.Runtime/RuntimeJavaField.cs index c4cd21c80..f36a6325c 100644 --- a/src/IKVM.Runtime/RuntimeJavaField.cs +++ b/src/IKVM.Runtime/RuntimeJavaField.cs @@ -27,6 +27,8 @@ Jeroen Frijters using IKVM.Attributes; using IKVM.CoreLib.Symbols; +using IKVM.CoreLib.Symbols.Emit; + #if IMPORTER || EXPORTER using IKVM.Reflection; @@ -438,20 +440,10 @@ internal static RuntimeJavaField Create(RuntimeJavaType declaringType, RuntimeJa } #if !IMPORTER && !EXPORTER + internal virtual void ResolveField() { - var fb = field.AsReflection() as FieldBuilder; - if (fb != null) - { -#if NETFRAMEWORK - field = fb.DeclaringType.Module.ResolveField(fb.GetToken().Token); -#else - BindingFlags flags = BindingFlags.DeclaredOnly; - flags |= fb.IsPublic ? BindingFlags.Public : BindingFlags.NonPublic; - flags |= fb.IsStatic ? BindingFlags.Static : BindingFlags.Instance; - field = DeclaringType.TypeAsTBD.GetField(fb.Name, flags); -#endif - } + } #if !FIRST_PASS diff --git a/src/IKVM.Runtime/RuntimeJavaType.cs b/src/IKVM.Runtime/RuntimeJavaType.cs index ff32a1673..319b7455a 100644 --- a/src/IKVM.Runtime/RuntimeJavaType.cs +++ b/src/IKVM.Runtime/RuntimeJavaType.cs @@ -1231,7 +1231,7 @@ internal void EmitBox(CodeEmitter ilgen) { Debug.Assert(this.IsNonPrimitiveValueType); - ilgen.Emit(OpCodes.Box, this.TypeAsTBD); + ilgen.Emit(System.Reflection.Emit.OpCodes.Box, this.TypeAsTBD); } internal void EmitConvSignatureTypeToStackType(CodeEmitter ilgen) @@ -1242,7 +1242,7 @@ internal void EmitConvSignatureTypeToStackType(CodeEmitter ilgen) } else if (this == context.PrimitiveJavaTypeFactory.BYTE) { - ilgen.Emit(OpCodes.Conv_I1); + ilgen.Emit(System.Reflection.Emit.OpCodes.Conv_I1); } else if (IsNonPrimitiveValueType) { @@ -1251,9 +1251,9 @@ internal void EmitConvSignatureTypeToStackType(CodeEmitter ilgen) else if (IsGhost) { var local = ilgen.DeclareLocal(TypeAsSignatureType); - ilgen.Emit(OpCodes.Stloc, local); - ilgen.Emit(OpCodes.Ldloca, local); - ilgen.Emit(OpCodes.Ldfld, GhostRefField); + ilgen.Emit(System.Reflection.Emit.OpCodes.Stloc, local); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldloca, local); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldfld, GhostRefField); } } @@ -1266,13 +1266,13 @@ internal void EmitConvStackTypeToSignatureType(CodeEmitter ilgen, RuntimeJavaTyp if (IsGhost) { CodeEmitterLocal local1 = ilgen.DeclareLocal(TypeAsLocalOrStackType); - ilgen.Emit(OpCodes.Stloc, local1); + ilgen.Emit(System.Reflection.Emit.OpCodes.Stloc, local1); CodeEmitterLocal local2 = ilgen.DeclareLocal(TypeAsSignatureType); - ilgen.Emit(OpCodes.Ldloca, local2); - ilgen.Emit(OpCodes.Ldloc, local1); - ilgen.Emit(OpCodes.Stfld, GhostRefField); - ilgen.Emit(OpCodes.Ldloca, local2); - ilgen.Emit(OpCodes.Ldobj, TypeAsSignatureType); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldloca, local2); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldloc, local1); + ilgen.Emit(System.Reflection.Emit.OpCodes.Stfld, GhostRefField); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldloca, local2); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldobj, TypeAsSignatureType); } // because of the way interface merging works, any reference is valid // for any interface reference @@ -1287,7 +1287,7 @@ internal void EmitConvStackTypeToSignatureType(CodeEmitter ilgen, RuntimeJavaTyp } else if (sourceType != null && sourceType.IsUnloadable) { - ilgen.Emit(OpCodes.Castclass, TypeAsSignatureType); + ilgen.Emit(System.Reflection.Emit.OpCodes.Castclass, TypeAsSignatureType); } } } @@ -1296,16 +1296,16 @@ internal virtual void EmitCheckcast(CodeEmitter ilgen) { if (IsGhost) { - ilgen.Emit(OpCodes.Dup); + ilgen.Emit(System.Reflection.Emit.OpCodes.Dup); // TODO make sure we get the right "Cast" method and cache it // NOTE for dynamic ghosts we don't end up here because AotTypeWrapper overrides this method, // so we're safe to call GetMethod on TypeAsTBD (because it has to be a compiled type, if we're here) - ilgen.Emit(OpCodes.Call, TypeAsTBD.GetMethod("Cast")); - ilgen.Emit(OpCodes.Pop); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, TypeAsTBD.GetMethod("Cast")); + ilgen.Emit(System.Reflection.Emit.OpCodes.Pop); } else if (IsGhostArray) { - ilgen.Emit(OpCodes.Dup); + ilgen.Emit(System.Reflection.Emit.OpCodes.Dup); // TODO make sure we get the right "CastArray" method and cache it // NOTE for dynamic ghosts we don't end up here because AotTypeWrapper overrides this method, // so we're safe to call GetMethod on TypeAsTBD (because it has to be a compiled type, if we're here) @@ -1317,8 +1317,8 @@ internal virtual void EmitCheckcast(CodeEmitter ilgen) tw = tw.ElementTypeWrapper; } ilgen.EmitLdc_I4(rank); - ilgen.Emit(OpCodes.Call, tw.TypeAsTBD.GetMethod("CastArray")); - ilgen.Emit(OpCodes.Castclass, RuntimeArrayJavaType.MakeArrayType(context.Types.Object, rank)); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, tw.TypeAsTBD.GetMethod("CastArray")); + ilgen.Emit(System.Reflection.Emit.OpCodes.Castclass, RuntimeArrayJavaType.MakeArrayType(context.Types.Object, rank)); } else { @@ -1333,7 +1333,7 @@ internal virtual void EmitInstanceOf(CodeEmitter ilgen) // TODO make sure we get the right "IsInstance" method and cache it // NOTE for dynamic ghosts we don't end up here because DynamicTypeWrapper overrides this method, // so we're safe to call GetMethod on TypeAsTBD (because it has to be a compiled type, if we're here) - ilgen.Emit(OpCodes.Call, TypeAsTBD.GetMethod("IsInstance")); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, TypeAsTBD.GetMethod("IsInstance")); } else if (IsGhostArray) { @@ -1348,7 +1348,7 @@ internal virtual void EmitInstanceOf(CodeEmitter ilgen) tw = tw.ElementTypeWrapper; } ilgen.EmitLdc_I4(rank); - ilgen.Emit(OpCodes.Call, tw.TypeAsTBD.GetMethod("IsInstanceArray")); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, tw.TypeAsTBD.GetMethod("IsInstanceArray")); } else { @@ -1363,23 +1363,23 @@ internal virtual void EmitInstanceOf(CodeEmitter ilgen) internal virtual void EmitLdind(CodeEmitter il) { if (this == context.PrimitiveJavaTypeFactory.BOOLEAN) - il.Emit(OpCodes.Ldind_U1); + il.Emit(System.Reflection.Emit.OpCodes.Ldind_U1); else if (this == context.PrimitiveJavaTypeFactory.BYTE) - il.Emit(OpCodes.Ldind_U1); + il.Emit(System.Reflection.Emit.OpCodes.Ldind_U1); else if (this == context.PrimitiveJavaTypeFactory.CHAR) - il.Emit(OpCodes.Ldind_U2); + il.Emit(System.Reflection.Emit.OpCodes.Ldind_U2); else if (this == context.PrimitiveJavaTypeFactory.SHORT) - il.Emit(OpCodes.Ldind_I2); + il.Emit(System.Reflection.Emit.OpCodes.Ldind_I2); else if (this == context.PrimitiveJavaTypeFactory.INT) - il.Emit(OpCodes.Ldind_I4); + il.Emit(System.Reflection.Emit.OpCodes.Ldind_I4); else if (this == context.PrimitiveJavaTypeFactory.LONG) - il.Emit(OpCodes.Ldind_I8); + il.Emit(System.Reflection.Emit.OpCodes.Ldind_I8); else if (this == context.PrimitiveJavaTypeFactory.FLOAT) - il.Emit(OpCodes.Ldind_R4); + il.Emit(System.Reflection.Emit.OpCodes.Ldind_R4); else if (this == context.PrimitiveJavaTypeFactory.DOUBLE) - il.Emit(OpCodes.Ldind_R8); + il.Emit(System.Reflection.Emit.OpCodes.Ldind_R8); else - il.Emit(OpCodes.Ldind_Ref); + il.Emit(System.Reflection.Emit.OpCodes.Ldind_Ref); } /// @@ -1389,23 +1389,23 @@ internal virtual void EmitLdind(CodeEmitter il) internal virtual void EmitStind(CodeEmitter il) { if (this == context.PrimitiveJavaTypeFactory.BOOLEAN) - il.Emit(OpCodes.Stind_I1); + il.Emit(System.Reflection.Emit.OpCodes.Stind_I1); else if (this == context.PrimitiveJavaTypeFactory.BYTE) - il.Emit(OpCodes.Stind_I1); + il.Emit(System.Reflection.Emit.OpCodes.Stind_I1); else if (this == context.PrimitiveJavaTypeFactory.CHAR) - il.Emit(OpCodes.Stind_I2); + il.Emit(System.Reflection.Emit.OpCodes.Stind_I2); else if (this == context.PrimitiveJavaTypeFactory.SHORT) - il.Emit(OpCodes.Stind_I2); + il.Emit(System.Reflection.Emit.OpCodes.Stind_I2); else if (this == context.PrimitiveJavaTypeFactory.INT) - il.Emit(OpCodes.Stind_I4); + il.Emit(System.Reflection.Emit.OpCodes.Stind_I4); else if (this == context.PrimitiveJavaTypeFactory.LONG) - il.Emit(OpCodes.Stind_I8); + il.Emit(System.Reflection.Emit.OpCodes.Stind_I8); else if (this == context.PrimitiveJavaTypeFactory.FLOAT) - il.Emit(OpCodes.Stind_R4); + il.Emit(System.Reflection.Emit.OpCodes.Stind_R4); else if (this == context.PrimitiveJavaTypeFactory.DOUBLE) - il.Emit(OpCodes.Stind_R8); + il.Emit(System.Reflection.Emit.OpCodes.Stind_R8); else - il.Emit(OpCodes.Stind_Ref); + il.Emit(System.Reflection.Emit.OpCodes.Stind_Ref); } #endif @@ -1479,7 +1479,7 @@ internal virtual string GetSourceFileName() return null; } - internal virtual int GetSourceLineNumber(MethodBase mb, int ilOffset) + internal virtual int GetSourceLineNumber(IMethodBaseSymbol mb, int ilOffset) { return -1; } diff --git a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs index f3cdaf1c5..e05682159 100644 --- a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs @@ -1280,7 +1280,7 @@ internal override string GetSourceFileName() return null; } - internal override int GetSourceLineNumber(MethodBase mb, int ilOffset) + internal override int GetSourceLineNumber(IMethodBaseSymbol mb, int ilOffset) { var attr = type.GetCustomAttribute(Context.Resolver.ResolveType(typeof(LineNumberTableAttribute))); if (attr != null && attr.Value.Constructor != null) diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.cs index 6b2a6272b..51ee91f3b 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.cs @@ -545,14 +545,14 @@ ICustomAttributeBuilder MakeCustomAttributeBuilder(RuntimeClassLoader loader, ob internal override void Apply(RuntimeClassLoader loader, ITypeSymbolBuilder tb, object annotation) { - if (type == loader.Context.Resolver.ResolveCoreType(typeof(System.Runtime.InteropServices.StructLayoutAttribute).FullName) && tb.Symbol.BaseType != loader.Context.Types.Object) + if (type == loader.Context.Resolver.ResolveCoreType(typeof(System.Runtime.InteropServices.StructLayoutAttribute).FullName) && tb.BaseType != loader.Context.Types.Object) { // we have to handle this explicitly, because if we apply an illegal StructLayoutAttribute, // TypeBuilder.CreateType() will later on throw an exception. #if IMPORTER - loader.Diagnostics.IgnoredCustomAttribute(type.FullName, $"Type '{tb.Symbol.FullName}' does not extend cli.System.Object"); + loader.Diagnostics.IgnoredCustomAttribute(type.FullName, $"Type '{tb.FullName}' does not extend cli.System.Object"); #else - loader.Diagnostics.GenericRuntimeError($"StructLayoutAttribute cannot be applied to {tb.Symbol.FullName}, because it does not directly extend cli.System.Object"); + loader.Diagnostics.GenericRuntimeError($"StructLayoutAttribute cannot be applied to {tb.FullName}, because it does not directly extend cli.System.Object"); #endif return; } diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.DelegateJavaMethod.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.DelegateJavaMethod.cs index 678bb8f5e..d04117a4f 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.DelegateJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.DelegateJavaMethod.cs @@ -75,25 +75,25 @@ internal override bool EmitIntrinsic(EmitIntrinsicContext context) var mw = targetType.GetMethodWrapper(GetDelegateInvokeStubName(DeclaringType.TypeAsTBD), iface.GetMethods()[0].Signature, true); if (mw == null || mw.IsStatic || !mw.IsPublic) { - context.Emitter.Emit(OpCodes.Ldftn, CreateErrorStub(context, targetType, mw == null || mw.IsStatic)); - context.Emitter.Emit(OpCodes.Newobj, delegateConstructor); + context.Emitter.Emit(System.Reflection.Emit.OpCodes.Ldftn, CreateErrorStub(context, targetType, mw == null || mw.IsStatic)); + context.Emitter.Emit(System.Reflection.Emit.OpCodes.Newobj, delegateConstructor); return true; } // TODO linking here is not safe mw.Link(); - context.Emitter.Emit(OpCodes.Dup); - context.Emitter.Emit(OpCodes.Ldvirtftn, mw.GetMethod()); - context.Emitter.Emit(OpCodes.Newobj, delegateConstructor); + context.Emitter.Emit(System.Reflection.Emit.OpCodes.Dup); + context.Emitter.Emit(System.Reflection.Emit.OpCodes.Ldvirtftn, mw.GetMethod()); + context.Emitter.Emit(System.Reflection.Emit.OpCodes.Newobj, delegateConstructor); return true; } - MethodInfo CreateErrorStub(EmitIntrinsicContext context, RuntimeJavaType targetType, bool isAbstract) + IMethodSymbol CreateErrorStub(EmitIntrinsicContext context, RuntimeJavaType targetType, bool isAbstract) { var invoke = delegateConstructor.DeclaringType.GetMethod("Invoke"); var parameters = invoke.GetParameters(); - var parameterTypes = new Type[parameters.Length + 1]; + var parameterTypes = new ITypeSymbol[parameters.Length + 1]; parameterTypes[0] = DeclaringType.Context.Types.Object; for (int i = 0; i < parameters.Length; i++) parameterTypes[i + 1] = parameters[i].ParameterType; @@ -107,12 +107,12 @@ MethodInfo CreateErrorStub(EmitIntrinsicContext context, RuntimeJavaType targetT internal override void EmitNewobj(CodeEmitter ilgen) { - ilgen.Emit(OpCodes.Ldtoken, delegateConstructor.DeclaringType); - ilgen.Emit(OpCodes.Call, DeclaringType.Context.CompilerFactory.GetTypeFromHandleMethod); - ilgen.Emit(OpCodes.Ldstr, GetDelegateInvokeStubName(DeclaringType.TypeAsTBD)); - ilgen.Emit(OpCodes.Ldstr, iface.GetMethods()[0].Signature); - ilgen.Emit(OpCodes.Call, DeclaringType.Context.ByteCodeHelperMethods.DynamicCreateDelegate); - ilgen.Emit(OpCodes.Castclass, delegateConstructor.DeclaringType); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldtoken, delegateConstructor.DeclaringType); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, DeclaringType.Context.CompilerFactory.GetTypeFromHandleMethod); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldstr, GetDelegateInvokeStubName(DeclaringType.TypeAsTBD)); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldstr, iface.GetMethods()[0].Signature); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, DeclaringType.Context.ByteCodeHelperMethods.DynamicCreateDelegate); + ilgen.Emit(System.Reflection.Emit.OpCodes.Castclass, delegateConstructor.DeclaringType); } internal override void EmitCall(CodeEmitter ilgen) @@ -124,9 +124,9 @@ internal override void EmitCall(CodeEmitter ilgen) EmitNewobj(ilgen); // invoke the constructor, binding the delegate to the target delegate - ilgen.Emit(OpCodes.Dup); - ilgen.Emit(OpCodes.Ldvirtftn, DeclaringType.Context.MethodHandleUtil.GetDelegateInvokeMethod(delegateConstructor.DeclaringType)); - ilgen.Emit(OpCodes.Call, delegateConstructor); + ilgen.Emit(System.Reflection.Emit.OpCodes.Dup); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldvirtftn, DeclaringType.Context.MethodHandleUtil.GetDelegateInvokeMethod(delegateConstructor.DeclaringType)); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, delegateConstructor); } #endif diff --git a/src/IKVM.Runtime/Serialization.cs b/src/IKVM.Runtime/Serialization.cs index bf4086772..dc7142b5e 100644 --- a/src/IKVM.Runtime/Serialization.cs +++ b/src/IKVM.Runtime/Serialization.cs @@ -24,6 +24,10 @@ Jeroen Frijters using System; using System.Runtime.Serialization; using System.Security; +using IKVM.CoreLib.Symbols; +using IKVM.CoreLib.Symbols.Emit; + + #if IMPORTER using IKVM.Reflection; @@ -90,9 +94,9 @@ bool IsSafeForAutomagicSerialization(RuntimeJavaType wrapper) return true; } - internal MethodBuilder AddAutomagicSerialization(RuntimeByteCodeJavaType wrapper, TypeBuilder typeBuilder) + internal IMethodSymbolBuilder AddAutomagicSerialization(RuntimeByteCodeJavaType wrapper, ITypeSymbolBuilder typeBuilder) { - MethodBuilder serializationCtor = null; + IMethodSymbolBuilder serializationCtor = null; if ((wrapper.Modifiers & IKVM.Attributes.Modifiers.Enum) != 0) { MarkSerializable(typeBuilder); @@ -149,7 +153,7 @@ internal MethodBuilder AddAutomagicSerialization(RuntimeByteCodeJavaType wrapper return serializationCtor; } - internal MethodBuilder AddAutomagicSerializationToWorkaroundBaseClass(TypeBuilder typeBuilderWorkaroundBaseClass, MethodBase baseCtor) + internal IMethodSymbolBuilder AddAutomagicSerializationToWorkaroundBaseClass(ITypeSymbolBuilder typeBuilderWorkaroundBaseClass, MethodBase baseCtor) { if (typeBuilderWorkaroundBaseClass.BaseType.IsSerializable) { @@ -161,36 +165,36 @@ internal MethodBuilder AddAutomagicSerializationToWorkaroundBaseClass(TypeBuilde return null; } - internal void MarkSerializable(TypeBuilder tb) + internal void MarkSerializable(ITypeSymbolBuilder tb) { tb.SetCustomAttribute(SerializableAttribute); } - internal void AddGetObjectData(TypeBuilder tb) + internal void AddGetObjectData(ITypeSymbolBuilder tb) { var name = tb.IsSealed ? "System.Runtime.Serialization.ISerializable.GetObjectData" : "GetObjectData"; var attr = tb.IsSealed ? MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final : MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.CheckAccessOnOverride; - tb.AddInterfaceImplementation(context.Resolver.ResolveCoreType(typeof(ISerializable).FullName).AsReflection()); - var getObjectData = tb.DefineMethod(name, attr, null, new Type[] { context.Resolver.ResolveCoreType(typeof(SerializationInfo).FullName).AsReflection(), context.Resolver.ResolveCoreType(typeof(StreamingContext).FullName).AsReflection() }); + tb.AddInterfaceImplementation(context.Resolver.ResolveCoreType(typeof(ISerializable).FullName)); + var getObjectData = tb.DefineMethod(name, attr, null, new ITypeSymbol[] { context.Resolver.ResolveCoreType(typeof(SerializationInfo).FullName), context.Resolver.ResolveCoreType(typeof(StreamingContext).FullName).AsReflection() }); getObjectData.SetCustomAttribute(SecurityCriticalAttribute); context.AttributeHelper.HideFromJava(getObjectData); tb.DefineMethodOverride(getObjectData, context.Resolver.ResolveCoreType(typeof(ISerializable).FullName).GetMethod("GetObjectData").AsReflection()); - CodeEmitter ilgen = context.CodeEmitterFactory.Create(getObjectData); + var ilgen = context.CodeEmitterFactory.Create(getObjectData); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Ldarg_1); - RuntimeJavaType serializationHelper = context.ClassLoaderFactory.LoadClassCritical("ikvm.internal.Serialization"); - RuntimeJavaMethod mw = serializationHelper.GetMethodWrapper("writeObject", "(Ljava.lang.Object;Lcli.System.Runtime.Serialization.SerializationInfo;)V", false); + var serializationHelper = context.ClassLoaderFactory.LoadClassCritical("ikvm.internal.Serialization"); + var mw = serializationHelper.GetMethodWrapper("writeObject", "(Ljava.lang.Object;Lcli.System.Runtime.Serialization.SerializationInfo;)V", false); mw.Link(); mw.EmitCall(ilgen); ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); } - MethodBuilder AddConstructor(TypeBuilder tb, RuntimeJavaMethod defaultConstructor, MethodBase serializationConstructor, bool callReadObject) + IMethodSymbolBuilder AddConstructor(ITypeSymbolBuilder tb, RuntimeJavaMethod defaultConstructor, IMethodBaseSymbol serializationConstructor, bool callReadObject) { - MethodBuilder ctor = ReflectUtil.DefineConstructor(tb, MethodAttributes.Family, new Type[] { context.Resolver.ResolveCoreType(typeof(SerializationInfo).FullName).AsReflection(), context.Resolver.ResolveCoreType(typeof(StreamingContext).FullName).AsReflection() }); + var ctor = ReflectUtil.DefineConstructor(tb, MethodAttributes.Family, new ITypeSymbol[] { context.Resolver.ResolveCoreType(typeof(SerializationInfo).FullName).AsReflection(), context.Resolver.ResolveCoreType(typeof(StreamingContext).FullName).AsReflection() }); context.AttributeHelper.HideFromJava(ctor); CodeEmitter ilgen = context.CodeEmitterFactory.Create(ctor); ilgen.Emit(OpCodes.Ldarg_0); @@ -218,13 +222,13 @@ MethodBuilder AddConstructor(TypeBuilder tb, RuntimeJavaMethod defaultConstructo return ctor; } - void AddReadResolve(RuntimeByteCodeJavaType wrapper, TypeBuilder tb) + void AddReadResolve(RuntimeByteCodeJavaType wrapper, ITypeSymbolBuilder tb) { var mw = wrapper.GetMethodWrapper("readResolve", "()Ljava.lang.Object;", false); if (mw != null && !wrapper.IsSubTypeOf(TypeOfIObjectReference)) { tb.AddInterfaceImplementation(wrapper.Context.Resolver.ResolveCoreType(typeof(IObjectReference).FullName).AsReflection()); - var getRealObject = tb.DefineMethod("IObjectReference.GetRealObject", MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final, wrapper.Context.Types.Object, new Type[] { wrapper.Context.Resolver.ResolveCoreType(typeof(StreamingContext).FullName).AsReflection() }); + var getRealObject = tb.DefineMethod("IObjectReference.GetRealObject", MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final, wrapper.Context.Types.Object, new ITypeSymbol[] { wrapper.Context.Resolver.ResolveCoreType(typeof(StreamingContext).FullName) }); getRealObject.SetCustomAttribute(SecurityCriticalAttribute); wrapper.Context.AttributeHelper.HideFromJava(getRealObject); tb.DefineMethodOverride(getRealObject, wrapper.Context.Resolver.ResolveCoreType(typeof(IObjectReference).FullName).GetMethod("GetRealObject").AsReflection()); @@ -237,7 +241,7 @@ void AddReadResolve(RuntimeByteCodeJavaType wrapper, TypeBuilder tb) ilgen.Emit(OpCodes.Callvirt, wrapper.Context.CompilerFactory.GetTypeMethod); ilgen.Emit(OpCodes.Ldtoken, wrapper.TypeAsBaseType); ilgen.Emit(OpCodes.Call, wrapper.Context.CompilerFactory.GetTypeFromHandleMethod); - CodeEmitterLabel label = ilgen.DefineLabel(); + var label = ilgen.DefineLabel(); ilgen.EmitBeq(label); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Ret); @@ -250,14 +254,14 @@ void AddReadResolve(RuntimeByteCodeJavaType wrapper, TypeBuilder tb) } } - void RemoveReadResolve(TypeBuilder tb) + void RemoveReadResolve(ITypeSymbolBuilder tb) { tb.AddInterfaceImplementation(context.Resolver.ResolveCoreType(typeof(IObjectReference).FullName).AsReflection()); - MethodBuilder getRealObject = tb.DefineMethod("IObjectReference.GetRealObject", MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final, context.Types.Object, [context.Resolver.ResolveCoreType(typeof(StreamingContext).FullName).AsReflection()]); + var getRealObject = tb.DefineMethod("IObjectReference.GetRealObject", MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final, context.Types.Object, [context.Resolver.ResolveCoreType(typeof(StreamingContext).FullName)]); getRealObject.SetCustomAttribute(SecurityCriticalAttribute); context.AttributeHelper.HideFromJava(getRealObject); tb.DefineMethodOverride(getRealObject, context.Resolver.ResolveCoreType(typeof(IObjectReference).FullName).GetMethod("GetRealObject").AsReflection()); - CodeEmitter ilgen = context.CodeEmitterFactory.Create(getRealObject); + var ilgen = context.CodeEmitterFactory.Create(getRealObject); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); diff --git a/src/IKVM.Runtime/SymbolExtensions.cs b/src/IKVM.Runtime/SymbolExtensions.cs index 14e3948b0..52745475a 100644 --- a/src/IKVM.Runtime/SymbolExtensions.cs +++ b/src/IKVM.Runtime/SymbolExtensions.cs @@ -29,9 +29,9 @@ public static Assembly AsReflection(this IAssemblySymbol symbol) return null; #if IMPORTER || EXPORTER - return ((IkvmReflectionAssemblySymbol)symbol).ReflectionObject; + return ((IIkvmReflectionAssemblySymbol)symbol).UnderlyingAssembly; #else - return ((ReflectionAssemblySymbol)symbol).ReflectionObject; + return ((IReflectionAssemblySymbol)symbol).UnderlyingAssembly; #endif } @@ -41,9 +41,9 @@ public static Module AsReflection(this IModuleSymbol symbol) return null; #if IMPORTER || EXPORTER - return ((IkvmReflectionModuleSymbol)symbol).ReflectionObject; + return ((IIkvmReflectionModuleSymbol)symbol).UnderlyingModule; #else - return ((ReflectionModuleSymbol)symbol).ReflectionObject; + return ((IReflectionModuleSymbol)symbol).UnderlyingModule; #endif } @@ -53,9 +53,9 @@ public static Type AsReflection(this ITypeSymbol symbol) return null; #if IMPORTER || EXPORTER - return ((IkvmReflectionTypeSymbol)symbol).ReflectionObject; + return ((IIkvmReflectionTypeSymbol)symbol).UnderlyingType; #else - return ((ReflectionTypeSymbol)symbol).ReflectionObject; + return ((IReflectionTypeSymbol)symbol).UnderlyingType; #endif } @@ -77,9 +77,9 @@ public static MethodBase AsReflection(this IMethodBaseSymbol symbol) return null; #if IMPORTER || EXPORTER - return ((IkvmReflectionMethodBaseSymbol)symbol).ReflectionObject; + return ((IIkvmReflectionMethodBaseSymbol)symbol).UnderlyingMethodBase; #else - return ((ReflectionMethodBaseSymbol)symbol).ReflectionObject; + return ((IReflectionMethodBaseSymbol)symbol).UnderlyingMethodBase; #endif } @@ -89,9 +89,9 @@ public static ConstructorInfo AsReflection(this IConstructorSymbol symbol) return null; #if IMPORTER || EXPORTER - return ((IkvmReflectionConstructorSymbol)symbol).ReflectionObject; + return ((IIkvmReflectionConstructorSymbol)symbol).UnderlyingConstructor; #else - return ((ReflectionConstructorSymbol)symbol).ReflectionObject; + return ((IReflectionConstructorSymbol)symbol).UnderlyingConstructor; #endif } @@ -101,9 +101,9 @@ public static MethodInfo AsReflection(this IMethodSymbol symbol) return null; #if IMPORTER || EXPORTER - return ((IkvmReflectionMethodSymbol)symbol).ReflectionObject; + return ((IIkvmReflectionMethodSymbol)symbol).UnderlyingMethod; #else - return ((ReflectionMethodSymbol)symbol).ReflectionObject; + return ((IReflectionMethodSymbol)symbol).UnderlyingMethod; #endif } @@ -113,9 +113,9 @@ public static FieldInfo AsReflection(this IFieldSymbol symbol) return null; #if IMPORTER || EXPORTER - return ((IkvmReflectionFieldSymbol)symbol).ReflectionObject; + return ((IIkvmReflectionFieldSymbol)symbol).UnderlyingField; #else - return ((ReflectionFieldSymbol)symbol).ReflectionObject; + return ((IReflectionFieldSymbol)symbol).UnderlyingField; #endif } @@ -137,9 +137,9 @@ public static PropertyInfo AsReflection(this IPropertySymbol symbol) return null; #if IMPORTER || EXPORTER - return ((IkvmReflectionPropertySymbol)symbol).ReflectionObject; + return ((IIkvmReflectionPropertySymbol)symbol).UnderlyingProperty; #else - return ((ReflectionPropertySymbol)symbol).ReflectionObject; + return ((IReflectionPropertySymbol)symbol).UnderlyingProperty; #endif } @@ -161,9 +161,9 @@ public static AssemblyBuilder AsReflection(this IAssemblySymbolBuilder builder) return null; #if IMPORTER || EXPORTER - return ((IkvmReflectionAssemblySymbolBuilder)builder).ReflectionBuilder; + return ((IIkvmReflectionAssemblySymbolBuilder)builder).UnderlyingAssemblyBuilder; #else - return ((ReflectionAssemblySymbolBuilder)builder).ReflectionBuilder; + return ((IReflectionAssemblySymbolBuilder)builder).UnderlyingAssemblyBuilder; #endif } @@ -173,9 +173,9 @@ public static ModuleBuilder AsReflection(this IModuleSymbolBuilder builder) return null; #if IMPORTER || EXPORTER - return ((IkvmReflectionModuleSymbolBuilder)builder).ReflectionBuilder; + return ((IIkvmReflectionModuleSymbolBuilder)builder).UnderlyingModuleBuilder; #else - return ((ReflectionModuleSymbolBuilder)builder).ReflectionBuilder; + return ((IReflectionModuleSymbolBuilder)builder).UnderlyingModuleBuilder; #endif } @@ -185,9 +185,9 @@ public static TypeBuilder AsReflection(this ITypeSymbolBuilder builder) return null; #if IMPORTER || EXPORTER - return ((IkvmReflectionTypeSymbolBuilder)builder).ReflectionBuilder; + return ((IIkvmReflectionTypeSymbolBuilder)builder).UnderlyingTypeBuilder; #else - return ((ReflectionTypeSymbolBuilder)builder).ReflectionBuilder; + return ((IReflectionTypeSymbolBuilder)builder).UnderlyingTypeBuilder; #endif } @@ -197,9 +197,9 @@ public static ConstructorBuilder AsReflection(this IConstructorSymbolBuilder bui return null; #if IMPORTER || EXPORTER - return ((IkvmReflectionConstructorSymbolBuilder)builder).ReflectionBuilder; + return ((IIkvmReflectionConstructorSymbolBuilder)builder).UnderlyingConstructorBuilder; #else - return ((ReflectionConstructorSymbolBuilder)builder).ReflectionBuilder; + return ((IReflectionConstructorSymbolBuilder)builder).UnderlyingConstructorBuilder; #endif } @@ -209,9 +209,9 @@ public static MethodBuilder AsReflection(this IMethodSymbolBuilder builder) return null; #if IMPORTER || EXPORTER - return ((IkvmReflectionMethodSymbolBuilder)builder).ReflectionBuilder; + return ((IIkvmReflectionMethodSymbolBuilder)builder).UnderlyingMethodBuilder; #else - return ((ReflectionMethodSymbolBuilder)builder).ReflectionBuilder; + return ((IReflectionMethodSymbolBuilder)builder).UnderlyingMethodBuilder; #endif } @@ -221,9 +221,9 @@ public static FieldBuilder AsReflection(this IFieldSymbolBuilder builder) return null; #if IMPORTER || EXPORTER - return ((IkvmReflectionFieldSymbolBuilder)builder).ReflectionBuilder; + return ((IIkvmReflectionFieldSymbolBuilder)builder).UnderlyingFieldBuilder; #else - return ((ReflectionFieldSymbolBuilder)builder).ReflectionBuilder; + return ((IReflectionFieldSymbolBuilder)builder).UnderlyingFieldBuilder; #endif } diff --git a/src/IKVM.Runtime/atomic.cs b/src/IKVM.Runtime/atomic.cs index d200ca721..3467e3992 100644 --- a/src/IKVM.Runtime/atomic.cs +++ b/src/IKVM.Runtime/atomic.cs @@ -22,17 +22,10 @@ Jeroen Frijters */ -using System; - -#if IMPORTER -using IKVM.Reflection; -using IKVM.Reflection.Emit; - -using Type = IKVM.Reflection.Type; -#else using System.Reflection; -using System.Reflection.Emit; -#endif + +using IKVM.CoreLib.Symbols; +using IKVM.CoreLib.Symbols.Emit; using InstructionFlags = IKVM.Runtime.ClassFile.Method.InstructionFlags; @@ -63,10 +56,10 @@ internal static bool Emit(RuntimeByteCodeJavaType.FinishContext context, Runtime if (field != null && !field.IsStatic && field.IsVolatile && field.DeclaringType == wrapper && field.FieldTypeWrapper == vclass) { // everything matches up, now call the actual emitter - ilgen.Emit(OpCodes.Pop); - ilgen.Emit(OpCodes.Pop); - ilgen.Emit(OpCodes.Pop); - ilgen.Emit(OpCodes.Newobj, context.GetAtomicReferenceFieldUpdater(field)); + ilgen.Emit(System.Reflection.Emit.OpCodes.Pop); + ilgen.Emit(System.Reflection.Emit.OpCodes.Pop); + ilgen.Emit(System.Reflection.Emit.OpCodes.Pop); + ilgen.Emit(System.Reflection.Emit.OpCodes.Newobj, context.GetAtomicReferenceFieldUpdater(field)); return true; } } @@ -74,58 +67,58 @@ internal static bool Emit(RuntimeByteCodeJavaType.FinishContext context, Runtime return false; } - internal static void EmitImpl(RuntimeContext context, TypeBuilder tb, FieldInfo field) + internal static void EmitImpl(RuntimeContext context, ITypeSymbolBuilder tb, IFieldSymbol field) { EmitCompareAndSet(context, "compareAndSet", tb, field); EmitGet(context, tb, field); EmitSet(context, "set", tb, field); } - private static void EmitCompareAndSet(RuntimeContext context, string name, TypeBuilder tb, FieldInfo field) + private static void EmitCompareAndSet(RuntimeContext context, string name, ITypeSymbolBuilder tb, IFieldSymbol field) { - MethodBuilder compareAndSet = tb.DefineMethod(name, MethodAttributes.Public | MethodAttributes.Virtual, context.Types.Boolean, new Type[] { context.Types.Object, context.Types.Object, context.Types.Object }); - ILGenerator ilgen = compareAndSet.GetILGenerator(); - ilgen.Emit(OpCodes.Ldarg_1); - ilgen.Emit(OpCodes.Castclass, field.DeclaringType); - ilgen.Emit(OpCodes.Ldflda, field); - ilgen.Emit(OpCodes.Ldarg_3); - ilgen.Emit(OpCodes.Castclass, field.FieldType); - ilgen.Emit(OpCodes.Ldarg_2); - ilgen.Emit(OpCodes.Castclass, field.FieldType); - ilgen.Emit(OpCodes.Call, MakeCompareExchange(context, field.FieldType)); - ilgen.Emit(OpCodes.Ldarg_2); - ilgen.Emit(OpCodes.Ceq); - ilgen.Emit(OpCodes.Ret); + var compareAndSet = tb.DefineMethod(name, MethodAttributes.Public | MethodAttributes.Virtual, context.Types.Boolean, [context.Types.Object, context.Types.Object, context.Types.Object]); + var ilgen = compareAndSet.GetILGenerator(); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldarg_1); + ilgen.Emit(System.Reflection.Emit.OpCodes.Castclass, field.DeclaringType); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldflda, field); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldarg_3); + ilgen.Emit(System.Reflection.Emit.OpCodes.Castclass, field.FieldType); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldarg_2); + ilgen.Emit(System.Reflection.Emit.OpCodes.Castclass, field.FieldType); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, MakeCompareExchange(context, field.FieldType)); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldarg_2); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ceq); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ret); } - internal static MethodInfo MakeCompareExchange(RuntimeContext context, Type type) + internal static IMethodSymbol MakeCompareExchange(RuntimeContext context, ITypeSymbol type) { return context.InterlockedMethods.CompareExchangeOfT.MakeGenericMethod(type); } - static void EmitGet(RuntimeContext context, TypeBuilder tb, FieldInfo field) + static void EmitGet(RuntimeContext context, ITypeSymbolBuilder tb, IFieldSymbol field) { - MethodBuilder get = tb.DefineMethod("get", MethodAttributes.Public | MethodAttributes.Virtual, context.Types.Object, new Type[] { context.Types.Object }); - ILGenerator ilgen = get.GetILGenerator(); - ilgen.Emit(OpCodes.Ldarg_1); - ilgen.Emit(OpCodes.Castclass, field.DeclaringType); - ilgen.Emit(OpCodes.Volatile); - ilgen.Emit(OpCodes.Ldfld, field); - ilgen.Emit(OpCodes.Ret); + var get = tb.DefineMethod("get", MethodAttributes.Public | MethodAttributes.Virtual, context.Types.Object, [context.Types.Object]); + var ilgen = get.GetILGenerator(); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldarg_1); + ilgen.Emit(System.Reflection.Emit.OpCodes.Castclass, field.DeclaringType); + ilgen.Emit(System.Reflection.Emit.OpCodes.Volatile); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldfld, field); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ret); } - static void EmitSet(RuntimeContext context, string name, TypeBuilder tb, FieldInfo field) + static void EmitSet(RuntimeContext context, string name, ITypeSymbolBuilder tb, IFieldSymbol field) { - MethodBuilder set = tb.DefineMethod(name, MethodAttributes.Public | MethodAttributes.Virtual, context.Types.Void, new Type[] { context.Types.Object, context.Types.Object }); - CodeEmitter ilgen = context.CodeEmitterFactory.Create(set); - ilgen.Emit(OpCodes.Ldarg_1); - ilgen.Emit(OpCodes.Castclass, field.DeclaringType); - ilgen.Emit(OpCodes.Ldarg_2); - ilgen.Emit(OpCodes.Castclass, field.FieldType); - ilgen.Emit(OpCodes.Volatile); - ilgen.Emit(OpCodes.Stfld, field); + var set = tb.DefineMethod(name, MethodAttributes.Public | MethodAttributes.Virtual, context.Types.Void, [context.Types.Object, context.Types.Object]); + var ilgen = context.CodeEmitterFactory.Create(set); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldarg_1); + ilgen.Emit(System.Reflection.Emit.OpCodes.Castclass, field.DeclaringType); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldarg_2); + ilgen.Emit(System.Reflection.Emit.OpCodes.Castclass, field.FieldType); + ilgen.Emit(System.Reflection.Emit.OpCodes.Volatile); + ilgen.Emit(System.Reflection.Emit.OpCodes.Stfld, field); ilgen.EmitMemoryBarrier(); - ilgen.Emit(OpCodes.Ret); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ret); ilgen.DoEmit(); } @@ -136,11 +129,11 @@ class InterlockedMethods readonly RuntimeContext context; - internal readonly MethodInfo AddInt32; - internal readonly MethodInfo CompareExchangeInt32; - internal readonly MethodInfo CompareExchangeInt64; - internal readonly MethodInfo CompareExchangeOfT; - internal readonly MethodInfo ExchangeOfT; + internal readonly IMethodSymbol AddInt32; + internal readonly IMethodSymbol CompareExchangeInt32; + internal readonly IMethodSymbol CompareExchangeInt64; + internal readonly IMethodSymbol CompareExchangeOfT; + internal readonly IMethodSymbol ExchangeOfT; /// /// Initializes a new instance. @@ -150,11 +143,11 @@ public InterlockedMethods(RuntimeContext context) { this.context = context; - var type = context.Resolver.ResolveCoreType(typeof(System.Threading.Interlocked).FullName).AsReflection(); + var type = context.Resolver.ResolveCoreType(typeof(System.Threading.Interlocked).FullName); AddInt32 = type.GetMethod("Add", [context.Types.Int32.MakeByRefType(), context.Types.Int32]); - CompareExchangeInt32 = type.GetMethod("CompareExchange", new Type[] { context.Types.Int32.MakeByRefType(), context.Types.Int32, context.Types.Int32 }); - CompareExchangeInt64 = type.GetMethod("CompareExchange", new Type[] { context.Types.Int64.MakeByRefType(), context.Types.Int64, context.Types.Int64 }); - foreach (MethodInfo m in type.GetMethods()) + CompareExchangeInt32 = type.GetMethod("CompareExchange", [context.Types.Int32.MakeByRefType(), context.Types.Int32, context.Types.Int32]); + CompareExchangeInt64 = type.GetMethod("CompareExchange", [context.Types.Int64.MakeByRefType(), context.Types.Int64, context.Types.Int64]); + foreach (var m in type.GetMethods()) { if (m.IsGenericMethodDefinition) { diff --git a/src/IKVM.Runtime/compiler.cs b/src/IKVM.Runtime/compiler.cs index 72f7e81b4..54e99b691 100644 --- a/src/IKVM.Runtime/compiler.cs +++ b/src/IKVM.Runtime/compiler.cs @@ -26,13 +26,12 @@ Jeroen Frijters using System.Diagnostics; using System.Diagnostics.SymbolStore; -using IKVM.CoreLib.Diagnostics; +using IKVM.CoreLib.Symbols; +using IKVM.CoreLib.Symbols.Emit; using IKVM.Attributes; using IKVM.ByteCode; #if IMPORTER -using IKVM.Reflection; -using IKVM.Reflection.Emit; using IKVM.Tools.Importer; using Type = IKVM.Reflection.Type; @@ -45,7 +44,6 @@ Jeroen Frijters using LocalVariableTableEntry = IKVM.Runtime.ClassFile.Method.LocalVariableTableEntry; using Instruction = IKVM.Runtime.ClassFile.Method.Instruction; using InstructionFlags = IKVM.Runtime.ClassFile.Method.InstructionFlags; -using System.Runtime.CompilerServices; namespace IKVM.Runtime { @@ -85,12 +83,12 @@ class CompilerFactory readonly RuntimeContext context; readonly bool bootstrap; - MethodInfo unmapExceptionMethod; - MethodInfo fixateExceptionMethod; - MethodInfo suppressFillInStackTraceMethod; - MethodInfo getTypeFromHandleMethod; - MethodInfo getTypeMethod; - MethodInfo keepAliveMethod; + IMethodSymbol unmapExceptionMethod; + IMethodSymbol fixateExceptionMethod; + IMethodSymbol suppressFillInStackTraceMethod; + IMethodSymbol getTypeFromHandleMethod; + IMethodSymbol getTypeMethod; + IMethodSymbol keepAliveMethod; RuntimeJavaMethod getClassFromTypeHandle; RuntimeJavaMethod getClassFromTypeHandle2; @@ -104,7 +102,7 @@ public CompilerFactory(RuntimeContext context, bool bootstrap) this.context = context; this.bootstrap = bootstrap; - if (bootstrap && Throwable.TypeAsBaseType is TypeBuilder) + if (bootstrap && Throwable.TypeAsBaseType is ITypeSymbolBuilder) foreach (var m in Throwable.GetMethods()) m.Link(); @@ -114,17 +112,17 @@ public CompilerFactory(RuntimeContext context, bool bootstrap) public RuntimeJavaType Throwable => context.JavaBase.TypeOfjavaLangThrowable; - public MethodInfo UnmapExceptionMethod => unmapExceptionMethod ??= bootstrap ? (MethodInfo)Throwable.GetMethodWrapper("__", "(Ljava.lang.Throwable;)Ljava.lang.Throwable;", false).GetMethod() : Throwable.TypeAsBaseType.GetMethod("__", new Type[] { context.Types.Exception }); + public IMethodSymbol UnmapExceptionMethod => unmapExceptionMethod ??= bootstrap ? (IMethodSymbol)Throwable.GetMethodWrapper("__", "(Ljava.lang.Throwable;)Ljava.lang.Throwable;", false).GetMethod() : Throwable.TypeAsBaseType.GetMethod("__", new ITypeSymbol[] { context.Types.Exception }); - public MethodInfo FixateExceptionMethod => fixateExceptionMethod ??= bootstrap ? (MethodInfo)Throwable.GetMethodWrapper("__", "(Ljava.lang.Throwable;)Ljava.lang.Throwable;", false).GetMethod() : Throwable.TypeAsBaseType.GetMethod("__", new Type[] { context.Types.Exception }); + public IMethodSymbol FixateExceptionMethod => fixateExceptionMethod ??= bootstrap ? (IMethodSymbol)Throwable.GetMethodWrapper("__", "(Ljava.lang.Throwable;)Ljava.lang.Throwable;", false).GetMethod() : Throwable.TypeAsBaseType.GetMethod("__", new ITypeSymbol[] { context.Types.Exception }); - public MethodInfo SuppressFillInStackTraceMethod => suppressFillInStackTraceMethod ??= bootstrap ? (MethodInfo)Throwable.GetMethodWrapper("__", "()V", false).GetMethod() : Throwable.TypeAsBaseType.GetMethod("__", []); + public IMethodSymbol SuppressFillInStackTraceMethod => suppressFillInStackTraceMethod ??= bootstrap ? (IMethodSymbol)Throwable.GetMethodWrapper("__", "()V", false).GetMethod() : Throwable.TypeAsBaseType.GetMethod("__", []); - public MethodInfo GetTypeFromHandleMethod => getTypeFromHandleMethod ??= context.Types.Type.GetMethod("GetTypeFromHandle", BindingFlags.Static | BindingFlags.Public, null, [context.Types.RuntimeTypeHandle], null); + public IMethodSymbol GetTypeFromHandleMethod => getTypeFromHandleMethod ??= context.Types.Type.GetMethod("GetTypeFromHandle", BindingFlags.Static | BindingFlags.Public, [context.Types.RuntimeTypeHandle]); - public MethodInfo GetTypeMethod => getTypeMethod ??= context.Types.Object.GetMethod("GetType", BindingFlags.Public | BindingFlags.Instance, null, [], null); + public IMethodSymbol GetTypeMethod => getTypeMethod ??= context.Types.Object.GetMethod("GetType", BindingFlags.Public | BindingFlags.Instance, []); - public MethodInfo KeepAliveMethod => keepAliveMethod ??= context.Resolver.ResolveCoreType(typeof(GC).FullName).AsReflection().GetMethod("KeepAlive", BindingFlags.Static | BindingFlags.Public, null, [context.Types.Object], null); + public IMethodSymbol KeepAliveMethod => keepAliveMethod ??= context.Resolver.ResolveCoreType(typeof(GC).FullName).GetMethod("KeepAlive", BindingFlags.Static | BindingFlags.Public, [context.Types.Object]); public RuntimeJavaMethod GetClassFromTypeHandle => getClassFromTypeHandle ??= context.ClassLoaderFactory.LoadClassCritical("ikvm.runtime.Util").GetMethodWrapper("getClassFromTypeHandle", "(Lcli.System.RuntimeTypeHandle;)Ljava.lang.Class;", false); @@ -2723,19 +2721,19 @@ internal static bool HasUnloadable(RuntimeJavaType[] args, RuntimeJavaType ret) static class InvokeDynamicBuilder { - internal static void Emit(Compiler compiler, ClassFile.ConstantPoolItemInvokeDynamic cpi, Type delegateType) + internal static void Emit(Compiler compiler, ClassFile.ConstantPoolItemInvokeDynamic cpi, ITypeSymbol delegateType) { var typeofOpenIndyCallSite = compiler.finish.Context.Resolver.ResolveRuntimeType("IKVM.Runtime.IndyCallSite`1").AsReflection(); var methodLookup = compiler.finish.Context.ClassLoaderFactory.LoadClassCritical("java.lang.invoke.MethodHandles").GetMethodWrapper("lookup", "()Ljava.lang.invoke.MethodHandles$Lookup;", false); methodLookup.Link(); var typeofIndyCallSite = typeofOpenIndyCallSite.MakeGenericType(delegateType); - MethodInfo methodCreateBootStrap; - MethodInfo methodGetTarget; + IMethodSymbol methodCreateBootStrap; + IMethodSymbol methodGetTarget; if (ReflectUtil.ContainsTypeBuilder(typeofIndyCallSite)) { - methodCreateBootStrap = TypeBuilder.GetMethod(typeofIndyCallSite, typeofOpenIndyCallSite.GetMethod("CreateBootstrap")); - methodGetTarget = TypeBuilder.GetMethod(typeofIndyCallSite, typeofOpenIndyCallSite.GetMethod("GetTarget")); + methodCreateBootStrap = ITypeSymbolBuilder.GetMethod(typeofIndyCallSite, typeofOpenIndyCallSite.GetMethod("CreateBootstrap")); + methodGetTarget = ITypeSymbolBuilder.GetMethod(typeofIndyCallSite, typeofOpenIndyCallSite.GetMethod("GetTarget")); } else { @@ -2758,7 +2756,7 @@ internal static void Emit(Compiler compiler, ClassFile.ConstantPoolItemInvokeDyn compiler.ilGenerator.Emit(OpCodes.Call, methodGetTarget); } - static MethodBuilder CreateBootstrapStub(Compiler compiler, ClassFile.ConstantPoolItemInvokeDynamic cpi, Type delegateType, TypeBuilder tb, FieldBuilder fb, MethodInfo methodGetTarget) + static IMethodSymbolBuilder CreateBootstrapStub(Compiler compiler, ClassFile.ConstantPoolItemInvokeDynamic cpi, ITypeSymbol delegateType, ITypeSymbolBuilder tb, IFieldSymbolBuilder fb, IMethodSymbol methodGetTarget) { var typeofCallSite = compiler.finish.Context.ClassLoaderFactory.LoadClassCritical("java.lang.invoke.CallSite").TypeAsSignatureType; var args = []; @@ -3045,7 +3043,7 @@ void EmitInvokeDynamic(ClassFile.ConstantPoolItemInvokeDynamic cpi) sealed class MethodHandleConstant { - FieldBuilder field; + IFieldSymbolBuilder field; internal void Emit(Compiler compiler, CodeEmitter ilgen, MethodHandleConstantHandle handle) { @@ -3067,7 +3065,7 @@ internal void Emit(Compiler compiler, CodeEmitter ilgen, MethodHandleConstantHan sealed class MethodTypeConstant { - FieldBuilder field; + IFieldSymbolBuilder field; bool dynamic; internal void Emit(Compiler compiler, CodeEmitter ilgen, MethodTypeConstantHandle handle) @@ -3088,7 +3086,7 @@ internal void Emit(Compiler compiler, CodeEmitter ilgen, MethodTypeConstantHandl } } - static FieldBuilder CreateField(Compiler compiler, MethodTypeConstantHandle handle, ref bool dynamic) + static IFieldSymbolBuilder CreateField(Compiler compiler, MethodTypeConstantHandle handle, ref bool dynamic) { var cpi = compiler.classFile.GetConstantPoolConstantMethodType(handle); var args = cpi.GetArgTypes(); @@ -3504,10 +3502,11 @@ private void EmitInvokeMaxArity(CodeEmitter ilgen) temps[i] = ilgen.DeclareLocal(args[i].TypeAsSignatureType); ilgen.Emit(OpCodes.Stloc, temps[i]); } - Type delegateType = compiler.finish.Context.MethodHandleUtil.CreateMethodHandleDelegateType(args, cpi.GetRetType()); + + var delegateType = compiler.finish.Context.MethodHandleUtil.CreateMethodHandleDelegateType(args, cpi.GetRetType()); ilgen.Emit(OpCodes.Call, compiler.finish.Context.ByteCodeHelperMethods.LoadMethodType.MakeGenericMethod(delegateType)); compiler.finish.Context.JavaBase.TypeOfJavaLangInvokeMethodHandle.GetMethodWrapper("asType", "(Ljava.lang.invoke.MethodType;)Ljava.lang.invoke.MethodHandle;", false).EmitCallvirt(ilgen); - MethodInfo mi = compiler.finish.Context.ByteCodeHelperMethods.GetDelegateForInvokeExact.MakeGenericMethod(delegateType); + var mi = compiler.finish.Context.ByteCodeHelperMethods.GetDelegateForInvokeExact.MakeGenericMethod(delegateType); ilgen.Emit(OpCodes.Call, mi); for (int i = 0; i < args.Length; i++) { @@ -3531,10 +3530,10 @@ private void EmitInvoke(CodeEmitter ilgen) ilgen.Emit(OpCodes.Stloc, temps[i]); } Type delegateType = compiler.finish.Context.MethodHandleUtil.CreateMethodHandleDelegateType(args, cpi.GetRetType()); - MethodInfo mi = ilgen.Context.ByteCodeHelperMethods.GetDelegateForInvoke.MakeGenericMethod(delegateType); + var mi = ilgen.Context.ByteCodeHelperMethods.GetDelegateForInvoke.MakeGenericMethod(delegateType); var typeofInvokeCache = compiler.finish.Context.Resolver.ResolveRuntimeType("IKVM.Runtime.InvokeCache`1").AsReflection(); - FieldBuilder fb = compiler.finish.DefineMethodHandleInvokeCacheField(typeofInvokeCache.MakeGenericType(delegateType)); + var fb = compiler.finish.DefineMethodHandleInvokeCacheField(typeofInvokeCache.MakeGenericType(delegateType)); ilgen.Emit(OpCodes.Ldloc, temps[0]); if (HasUnloadable(cpi.GetArgTypes(), cpi.GetRetType())) { @@ -3579,8 +3578,8 @@ internal static void EmitInvokeBasic(RuntimeContext context, CodeEmitter ilgen, } temps[0] = ilgen.DeclareLocal(args[0].TypeAsSignatureType); ilgen.Emit(OpCodes.Stloc, temps[0]); - Type delegateType = context.MethodHandleUtil.CreateMemberWrapperDelegateType(args, retType); - MethodInfo mi = context.ByteCodeHelperMethods.GetDelegateForInvokeBasic.MakeGenericMethod(delegateType); + var delegateType = context.MethodHandleUtil.CreateMemberWrapperDelegateType(args, retType); + var mi = context.ByteCodeHelperMethods.GetDelegateForInvokeBasic.MakeGenericMethod(delegateType); ilgen.Emit(OpCodes.Ldloc, temps[0]); ilgen.Emit(OpCodes.Call, mi); for (int i = 0; i < args.Length; i++) @@ -3616,7 +3615,8 @@ internal override void EmitNewobj(CodeEmitter ilgen) private sealed class DynamicFieldBinder { - private MethodInfo method; + + private IMethodSymbol method; internal void Emit(Compiler compiler, ClassFile.ConstantPoolItemFieldref cpi, MethodHandleKind kind) { @@ -3626,7 +3626,7 @@ internal void Emit(Compiler compiler, ClassFile.ConstantPoolItemFieldref cpi, Me compiler.ilGenerator.Emit(OpCodes.Call, method); } - private static MethodInfo CreateMethod(Compiler compiler, ClassFile.ConstantPoolItemFieldref cpi, MethodHandleKind kind) + private static IMethodSymbol CreateMethod(Compiler compiler, ClassFile.ConstantPoolItemFieldref cpi, MethodHandleKind kind) { RuntimeJavaType ret; RuntimeJavaType[] args; @@ -3666,7 +3666,7 @@ internal RuntimeJavaMethod Get(Compiler compiler, MethodHandleKind kind, ClassFi return mw ??= new DynamicBinderMethodWrapper(cpi, Emit(compiler, kind, cpi, privileged), kind); } - private static MethodInfo Emit(Compiler compiler, MethodHandleKind kind, ClassFile.ConstantPoolItemMI cpi, bool privileged) + private static IMethodSymbol Emit(Compiler compiler, MethodHandleKind kind, ClassFile.ConstantPoolItemMI cpi, bool privileged) { RuntimeJavaType ret; RuntimeJavaType[] args; @@ -3688,23 +3688,23 @@ private static MethodInfo Emit(Compiler compiler, MethodHandleKind kind, ClassFi return Emit(compiler, kind, cpi, ret, args, privileged); } - internal static MethodInfo Emit(Compiler compiler, MethodHandleKind kind, ClassFile.ConstantPoolItemFMI cpi, RuntimeJavaType ret, RuntimeJavaType[] args, bool privileged) + internal static IMethodSymbol Emit(Compiler compiler, MethodHandleKind kind, ClassFile.ConstantPoolItemFMI cpi, RuntimeJavaType ret, RuntimeJavaType[] args, bool privileged) { var ghostTarget = (kind == MethodHandleKind.InvokeSpecial || kind == MethodHandleKind.InvokeVirtual || kind == MethodHandleKind.InvokeInterface) && args[0].IsGhost; var delegateType = compiler.finish.Context.MethodHandleUtil.CreateMethodHandleDelegateType(args, ret); var fb = compiler.finish.DefineMethodHandleInvokeCacheField(delegateType); - var types = new Type[args.Length]; + var types = new ITypeSymbol[args.Length]; for (int i = 0; i < types.Length; i++) types[i] = args[i].TypeAsSignatureType; if (ghostTarget) types[0] = types[0].MakeByRefType(); - MethodBuilder mb = compiler.finish.DefineMethodHandleDispatchStub(ret.TypeAsSignatureType, types); - CodeEmitter ilgen = compiler.finish.Context.CodeEmitterFactory.Create(mb); + var mb = compiler.finish.DefineMethodHandleDispatchStub(ret.TypeAsSignatureType, types); + var ilgen = compiler.finish.Context.CodeEmitterFactory.Create(mb); ilgen.Emit(OpCodes.Ldsfld, fb); - CodeEmitterLabel label = ilgen.DefineLabel(); + var label = ilgen.DefineLabel(); ilgen.EmitBrtrue(label); ilgen.EmitLdc_I4((int)kind); ilgen.Emit(OpCodes.Ldstr, cpi.Class); @@ -3740,9 +3740,9 @@ internal static MethodInfo Emit(Compiler compiler, MethodHandleKind kind, ClassF sealed class DynamicBinderMethodWrapper : RuntimeJavaMethod { - readonly MethodInfo method; + readonly IMethodSymbol method; - internal DynamicBinderMethodWrapper(ClassFile.ConstantPoolItemMI cpi, MethodInfo method, MethodHandleKind kind) : + internal DynamicBinderMethodWrapper(ClassFile.ConstantPoolItemMI cpi, IMethodSymbol method, MethodHandleKind kind) : base(cpi.GetClassType(), cpi.Name, cpi.Signature, null, cpi.GetRetType(), cpi.GetArgTypes(), kind == MethodHandleKind.InvokeStatic ? Modifiers.Public | Modifiers.Static : Modifiers.Public, MemberFlags.None) { this.method = method; @@ -3955,7 +3955,7 @@ LocalVar StoreLocal(int instructionIndex) return v; } - Type GetLocalBuilderType(RuntimeJavaType tw) + ITypeSymbol GetLocalBuilderType(RuntimeJavaType tw) { if (tw.IsUnloadable) return finish.Context.Types.Object; From 6425e9b95b7b0040c1b4356617d82abc70bf5878 Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Fri, 20 Sep 2024 18:04:32 -0500 Subject: [PATCH 10/51] Rebuild. --- .../Collections/IndexRangeDictionaryTests.cs | 66 +- .../IkvmReflectionSymbolTests.cs | 54 +- .../Collections/IndexRangeDictionary.cs | 103 +-- src/IKVM.CoreLib/IKVM.CoreLib.csproj | 8 - src/IKVM.CoreLib/Symbols/Emit/IILGenerator.cs | 6 +- src/IKVM.CoreLib/Symbols/Emit/ILabel.cs | 4 + .../Symbols/Emit/IModuleSymbolBuilder.cs | 14 +- .../Symbols/Emit/ITypeSymbolBuilder.cs | 2 +- src/IKVM.CoreLib/Symbols/ISymbolContext.cs | 21 +- .../IIkvmReflectionAssemblySymbolBuilder.cs | 9 +- ...IIkvmReflectionConstructorSymbolBuilder.cs | 5 +- .../Emit/IIkvmReflectionEventSymbolBuilder.cs | 5 +- .../Emit/IIkvmReflectionFieldSymbolBuilder.cs | 2 +- ...ectionGenericTypeParameterSymbolBuilder.cs | 2 +- .../IIkvmReflectionMemberSymbolBuilder.cs | 7 +- .../IIkvmReflectionMethodBaseSymbolBuilder.cs | 10 +- .../IIkvmReflectionMethodSymbolBuilder.cs | 9 +- .../IIkvmReflectionModuleSymbolBuilder.cs | 58 +- .../IIkvmReflectionParameterSymbolBuilder.cs | 2 +- .../IIkvmReflectionPropertySymbolBuilder.cs | 6 +- .../Emit/IIkvmReflectionSymbolBuilder.cs | 85 ++- .../Emit/IIkvmReflectionTypeSymbolBuilder.cs | 44 +- .../IkvmReflectionAssemblySymbolBuilder.cs | 43 +- .../IkvmReflectionConstructorSymbolBuilder.cs | 8 +- .../Emit/IkvmReflectionEventSymbolBuilder.cs | 2 +- .../Emit/IkvmReflectionFieldSymbolBuilder.cs | 2 +- ...ectionGenericTypeParameterSymbolBuilder.cs | 467 +++++++----- .../Emit/IkvmReflectionILGenerator.cs | 499 ++++++++++++ .../Emit/IkvmReflectionLabel.cs | 28 + .../Emit/IkvmReflectionLocalBuilder.cs | 55 ++ .../Emit/IkvmReflectionMemberSymbolBuilder.cs | 259 ++++--- .../IkvmReflectionMethodBaseSymbolBuilder.cs | 27 +- .../Emit/IkvmReflectionMethodSymbolBuilder.cs | 48 +- .../Emit/IkvmReflectionModuleSymbolBuilder.cs | 249 +++--- .../IkvmReflectionParameterSymbolBuilder.cs | 14 +- .../IkvmReflectionPropertySymbolBuilder.cs | 16 +- .../Emit/IkvmReflectionSymbolBuilder.cs | 12 +- .../Emit/IkvmReflectionTypeSymbolBuilder.cs | 474 +++++++----- .../IIkvmReflectionAssemblySymbol.cs | 7 - .../IIkvmReflectionMethodBaseSymbol.cs | 7 + .../IIkvmReflectionMethodSymbol.cs | 7 + .../IIkvmReflectionModuleSymbol.cs | 48 +- .../IIkvmReflectionParameterSymbol.cs | 4 +- .../IIkvmReflectionPropertySymbol.cs | 7 + .../IkvmReflection/IIkvmReflectionSymbol.cs | 79 +- .../IIkvmReflectionTypeSymbol.cs | 85 ++- .../IkvmReflectionAssemblySymbol.cs | 33 +- .../IkvmReflectionEventTable.cs | 94 +++ .../IkvmReflectionFieldTable.cs | 80 ++ ...kvmReflectionGenericTypeParameterSymbol.cs | 456 ++++++----- ...IkvmReflectionGenericTypeParameterTable.cs | 82 ++ .../IkvmReflectionMemberSymbol.cs | 153 +--- .../IkvmReflectionMethodBaseSymbol.cs | 12 + .../IkvmReflectionMethodSpecTable.cs | 66 ++ .../IkvmReflectionMethodSymbol.cs | 15 + .../IkvmReflectionMethodTable.cs | 157 ++++ .../IkvmReflectionModuleMetadata.cs | 480 ------------ .../IkvmReflectionModuleSymbol.cs | 99 +-- ...tadata.cs => IkvmReflectionModuleTable.cs} | 31 +- .../IkvmReflectionParameterSymbol.cs | 10 +- .../IkvmReflectionParameterTable.cs | 94 +++ .../IkvmReflectionPropertySymbol.cs | 17 + .../IkvmReflectionPropertyTable.cs | 80 ++ .../IkvmReflection/IkvmReflectionSymbol.cs | 51 +- .../IkvmReflectionSymbolContext.cs | 76 +- .../IkvmReflection/IkvmReflectionTypeImpl.cs | 587 --------------- .../IkvmReflectionTypeSpecTable.cs | 129 ++++ .../IkvmReflectionTypeSymbol.cs | 437 ++++++----- .../IkvmReflection/IkvmReflectionTypeTable.cs | 76 ++ .../IkvmReflection/IkvmReflectionUtil.cs | 140 +++- src/IKVM.CoreLib/Symbols/InterfaceMapping.cs | 10 +- .../ReflectionConstructorSymbolBuilder.cs | 6 +- .../Reflection/Emit/ReflectionILGenerator.cs | 265 +++++++ .../Reflection/Emit/ReflectionLabel.cs | 29 + .../Reflection/Emit/ReflectionLocalBuilder.cs | 59 ++ .../Emit/ReflectionMethodSymbolBuilder.cs | 14 +- .../Emit/ReflectionModuleSymbolBuilder.cs | 13 +- .../Emit/ReflectionTypeSymbolBuilder.cs | 2 +- .../Symbols/Reflection/IReflectionSymbol.cs | 7 + .../Reflection/ReflectionAssemblyMetadata.cs | 2 +- .../Reflection/ReflectionModuleSymbol.cs | 2 - .../Symbols/Reflection/ReflectionSymbol.cs | 52 +- .../Reflection/ReflectionSymbolContext.cs | 28 + .../Symbols/Reflection/ReflectionTypeImpl.cs | 2 +- .../Symbols/Reflection/ReflectionUtil.cs | 89 +++ src/IKVM.Reflection/Emit/ILGenerator.cs | 19 + src/IKVM.Reflection/MemberInfo.cs | 2 + src/IKVM.Reflection/Type.cs | 2 +- src/IKVM.Runtime/AttributeHelper.cs | 4 +- src/IKVM.Runtime/CodeEmitter.cs | 26 +- src/IKVM.Runtime/CodeEmitterLocal.cs | 21 +- src/IKVM.Runtime/DynamicClassLoader.cs | 64 +- src/IKVM.Runtime/ExceptionHelper.cs | 34 +- src/IKVM.Runtime/IRuntimeSymbolResolver.cs | 35 +- .../Java/Externs/ikvm/runtime/Util.cs | 62 +- .../Java/Externs/java/lang/Package.cs | 2 +- .../Java/Externs/sun/misc/Unsafe.cs | 8 +- src/IKVM.Runtime/LambdaMetafactory.cs | 12 +- src/IKVM.Runtime/MethodHandleUtil.compiler.cs | 49 +- src/IKVM.Runtime/RuntimeArrayJavaType.cs | 2 +- .../RuntimeAssemblyClassLoader.cs | 24 +- .../RuntimeByteCodeJavaType.FinishContext.cs | 34 +- ...peImpl.DelegateConstructorMethodWrapper.cs | 22 +- ...ypeImpl.DelegateInvokeStubMethodWrapper.cs | 15 +- .../RuntimeByteCodeJavaType.JavaTypeImpl.cs | 25 +- src/IKVM.Runtime/RuntimeByteCodeJavaType.cs | 13 +- src/IKVM.Runtime/RuntimeJavaType.cs | 10 +- .../RuntimeManagedByteCodeJavaType.cs | 22 +- .../RuntimeManagedJavaType.ByRefJavaMethod.cs | 13 +- .../RuntimeManagedJavaType.CloneJavaMethod.cs | 14 +- ...agedJavaType.DelegateInnerClassJavaType.cs | 2 +- ...RuntimeManagedJavaType.EnumEnumJavaType.cs | 13 +- src/IKVM.Runtime/RuntimeManagedJavaType.cs | 25 +- src/IKVM.Runtime/RuntimeUnloadableJavaType.cs | 12 +- src/IKVM.Runtime/Serialization.cs | 43 +- src/IKVM.Runtime/compiler.cs | 710 +++++++++--------- src/IKVM.Runtime/intrinsics.cs | 22 +- src/IKVM.Tools.Exporter/ExportImpl.cs | 6 +- .../ManagedTypeResolver.cs | 127 ++-- src/ikvmstub/Properties/launchSettings.json | 2 +- src/ikvmstub/ikvmstub.csproj | 2 +- testenvironments.json | 1 - 122 files changed, 5190 insertions(+), 3313 deletions(-) create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionILGenerator.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionLabel.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionLocalBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionEventTable.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionFieldTable.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionGenericTypeParameterTable.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodSpecTable.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodTable.cs delete mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleMetadata.cs rename src/IKVM.CoreLib/Symbols/IkvmReflection/{IkvmReflectionAssemblyMetadata.cs => IkvmReflectionModuleTable.cs} (59%) create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterTable.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionPropertyTable.cs delete mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeImpl.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSpecTable.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeTable.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionILGenerator.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionLabel.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionLocalBuilder.cs diff --git a/src/IKVM.CoreLib.Tests/Collections/IndexRangeDictionaryTests.cs b/src/IKVM.CoreLib.Tests/Collections/IndexRangeDictionaryTests.cs index b42cc97a8..04f64fc0c 100644 --- a/src/IKVM.CoreLib.Tests/Collections/IndexRangeDictionaryTests.cs +++ b/src/IKVM.CoreLib.Tests/Collections/IndexRangeDictionaryTests.cs @@ -11,12 +11,47 @@ namespace IKVM.CoreLib.Tests.Collections public class IndexRangeDictionaryTests { + [TestMethod] + public void AlignTowardsInfinity() + { + IndexRangeDictionary.AlignTowardsInfinity(0).Should().Be(0); + IndexRangeDictionary.AlignTowardsInfinity(1).Should().Be(8); + IndexRangeDictionary.AlignTowardsInfinity(7).Should().Be(8); + IndexRangeDictionary.AlignTowardsInfinity(8).Should().Be(8); + IndexRangeDictionary.AlignTowardsInfinity(9).Should().Be(16); + + IndexRangeDictionary.AlignTowardsInfinity(-0).Should().Be(-0); + IndexRangeDictionary.AlignTowardsInfinity(-1).Should().Be(-8); + IndexRangeDictionary.AlignTowardsInfinity(-7).Should().Be(-8); + IndexRangeDictionary.AlignTowardsInfinity(-8).Should().Be(-8); + IndexRangeDictionary.AlignTowardsInfinity(-9).Should().Be(-16); + } + + [TestMethod] + public void AlignTowardsZero() + { + IndexRangeDictionary.AlignTowardsZero(0).Should().Be(0); + IndexRangeDictionary.AlignTowardsZero(1).Should().Be(0); + IndexRangeDictionary.AlignTowardsZero(7).Should().Be(0); + IndexRangeDictionary.AlignTowardsZero(8).Should().Be(8); + IndexRangeDictionary.AlignTowardsZero(9).Should().Be(8); + + IndexRangeDictionary.AlignTowardsZero(-0).Should().Be(-0); + IndexRangeDictionary.AlignTowardsZero(-1).Should().Be(-0); + IndexRangeDictionary.AlignTowardsZero(-7).Should().Be(-0); + IndexRangeDictionary.AlignTowardsZero(-8).Should().Be(-8); + IndexRangeDictionary.AlignTowardsZero(-9).Should().Be(-8); + } + [TestMethod] public void CanAddBasicItem() { var d = new IndexRangeDictionary(); d[0] = "Item1"; d[0].Should().Be("Item1"); + d._minKey.Should().Be(0); + d._maxKey.Should().Be(0); + d._items.Length.Should().Be(8); } [TestMethod] @@ -25,6 +60,9 @@ public void CanAddOffsetItem() var d = new IndexRangeDictionary(); d[10] = "Item1"; d[10].Should().Be("Item1"); + d._minKey.Should().Be(8); + d._maxKey.Should().Be(16); + d._items.Length.Should().Be(16); } [TestMethod] @@ -32,10 +70,19 @@ public void CanAddSparseRange() { var d = new IndexRangeDictionary(); d[10] = "Item1"; + d[10].Should().Be("Item1"); + d._minKey.Should().Be(8); + d._maxKey.Should().Be(16); + d._items.Length.Should().Be(16); d[20] = "Item2"; - d[9].Should().BeNull(); d[10].Should().Be("Item1"); - d[11].Should().BeNull(); + d[20].Should().Be("Item2"); + d._minKey.Should().Be(8); + d._maxKey.Should().Be(24); + d._items.Length.Should().Be(32); + d[5].Should().BeNull(); + d[10].Should().Be("Item1"); + d[15].Should().BeNull(); d[19].Should().BeNull(); d[20].Should().Be("Item2"); d[21].Should().BeNull(); @@ -46,9 +93,22 @@ public void CanAddMaxBeforeMin() { var d = new IndexRangeDictionary(); d[20] = "Item1"; - d[10] = "Item2"; d[20].Should().Be("Item1"); + d[10] = "Item2"; d[10].Should().Be("Item2"); + d[20] = "Item1"; + d[20].Should().Be("Item1"); + } + + [TestMethod] + public void ShiftShouldBeEmpty() + { + var d = new IndexRangeDictionary(); + d[2] = "Item2"; + d[2].Should().Be("Item2"); + d[0] = "Item0"; + d[0].Should().Be("Item0"); + d[1].Should().BeNull(); } } diff --git a/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs b/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs index b33adef9e..0147fea23 100644 --- a/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs +++ b/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs @@ -66,7 +66,7 @@ public void Setup() [TestMethod] public void SameTypeShouldBeSame() { - var c = new IkvmReflectionSymbolContext(); + var c = new IkvmReflectionSymbolContext(universe); var s1 = c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.Object")); var s2 = c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.Object")); s1.Should().BeOfType(); @@ -76,7 +76,7 @@ public void SameTypeShouldBeSame() [TestMethod] public void GenericTypeDefinitionShouldBeSame() { - var c = new IkvmReflectionSymbolContext(); + var c = new IkvmReflectionSymbolContext(universe); var s1 = c.GetOrCreateTypeSymbol(thisAssembly.GetType("IKVM.CoreLib.Tests.Symbols.IkvmReflection.IkvmReflectionSymbolTests+Foo`1")); var s2 = c.GetOrCreateTypeSymbol(thisAssembly.GetType("IKVM.CoreLib.Tests.Symbols.IkvmReflection.IkvmReflectionSymbolTests+Foo`1")); s1.Should().BeSameAs(s2); @@ -85,7 +85,7 @@ public void GenericTypeDefinitionShouldBeSame() [TestMethod] public void GenericTypeShouldBeSame() { - var c = new IkvmReflectionSymbolContext(); + var c = new IkvmReflectionSymbolContext(universe); var s1 = c.GetOrCreateTypeSymbol(thisAssembly.GetType("IKVM.CoreLib.Tests.Symbols.IkvmReflection.IkvmReflectionSymbolTests+Foo`1").MakeGenericType(coreAssembly.GetType("System.Int32"))); var s2 = c.GetOrCreateTypeSymbol(thisAssembly.GetType("IKVM.CoreLib.Tests.Symbols.IkvmReflection.IkvmReflectionSymbolTests+Foo`1").MakeGenericType(coreAssembly.GetType("System.Int32"))); s1.Should().BeSameAs(s2); @@ -94,7 +94,7 @@ public void GenericTypeShouldBeSame() [TestMethod] public void ArrayTypeShouldBeSame() { - var c = new IkvmReflectionSymbolContext(); + var c = new IkvmReflectionSymbolContext(universe); var s1 = c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.Object").MakeArrayType(2)); var s2 = c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.Object").MakeArrayType(2)); s1.Should().BeSameAs(s2); @@ -103,7 +103,7 @@ public void ArrayTypeShouldBeSame() [TestMethod] public void SZArrayTypeShouldBeSame() { - var c = new IkvmReflectionSymbolContext(); + var c = new IkvmReflectionSymbolContext(universe); var s1 = c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.Int32").MakeArrayType()); var s2 = c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.Int32").MakeArrayType()); s1.Should().BeSameAs(s2); @@ -112,7 +112,7 @@ public void SZArrayTypeShouldBeSame() [TestMethod] public unsafe void PointerTypeShouldBeSame() { - var c = new IkvmReflectionSymbolContext(); + var c = new IkvmReflectionSymbolContext(universe); var s1 = c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.Int32").MakePointerType()); var s2 = c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.Int32").MakePointerType()); s1.Should().BeSameAs(s2); @@ -121,7 +121,7 @@ public unsafe void PointerTypeShouldBeSame() [TestMethod] public unsafe void ByRefTypeShouldBeSame() { - var c = new IkvmReflectionSymbolContext(); + var c = new IkvmReflectionSymbolContext(universe); var s1 = c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.Int32").MakeByRefType()); var s2 = c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.Int32").MakeByRefType()); s1.Should().BeSameAs(s2); @@ -130,7 +130,7 @@ public unsafe void ByRefTypeShouldBeSame() [TestMethod] public void EnumTypeShouldBeSame() { - var c = new IkvmReflectionSymbolContext(); + var c = new IkvmReflectionSymbolContext(universe); var s1 = c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.AttributeTargets")); var s2 = c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.AttributeTargets")); s1.Should().BeSameAs(s2); @@ -139,7 +139,7 @@ public void EnumTypeShouldBeSame() [TestMethod] public void CanResolveType() { - var c = new IkvmReflectionSymbolContext(); + var c = new IkvmReflectionSymbolContext(universe); var s = c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.Object")); s.Name.Should().Be("Object"); s.FullName.Should().Be("System.Object"); @@ -148,7 +148,7 @@ public void CanResolveType() [TestMethod] public void CanResolveFieldOfGenericTypeDefinition() { - var c = new IkvmReflectionSymbolContext(); + var c = new IkvmReflectionSymbolContext(universe); var s = c.GetOrCreateTypeSymbol(thisAssembly.GetType("IKVM.CoreLib.Tests.Symbols.IkvmReflection.IkvmReflectionSymbolTests+Foo`1")); s.IsGenericType.Should().BeTrue(); s.IsGenericTypeDefinition.Should().BeTrue(); @@ -161,7 +161,7 @@ public void CanResolveFieldOfGenericTypeDefinition() [TestMethod] public void CanResolveFieldOfGenericType() { - var c = new IkvmReflectionSymbolContext(); + var c = new IkvmReflectionSymbolContext(universe); var s = c.GetOrCreateTypeSymbol(thisAssembly.GetType("IKVM.CoreLib.Tests.Symbols.IkvmReflection.IkvmReflectionSymbolTests+Foo`1").MakeGenericType(coreAssembly.GetType("System.Int32"))); s.IsGenericType.Should().BeTrue(); s.IsGenericTypeDefinition.Should().BeFalse(); @@ -175,7 +175,7 @@ public void CanResolveFieldOfGenericType() [TestMethod] public void CanResolveMethod() { - var c = new IkvmReflectionSymbolContext(); + var c = new IkvmReflectionSymbolContext(universe); var s = c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.Object")); var m = s.GetMethod("ToString"); m.Name.Should().Be("ToString"); @@ -190,7 +190,7 @@ public void CanResolveMethod() [TestMethod] public void CanResolveGenericMethod() { - var c = new IkvmReflectionSymbolContext(); + var c = new IkvmReflectionSymbolContext(universe); var s = c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.ValueTuple")); var m = s.GetMethods().FirstOrDefault(i => i.Name == "Create" && i.GetGenericArguments().Length == 1); m.Name.Should().Be("Create"); @@ -205,7 +205,7 @@ public void CanResolveGenericMethod() [TestMethod] public void CanResolveParameters() { - var c = new IkvmReflectionSymbolContext(); + var c = new IkvmReflectionSymbolContext(universe); var s = c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.Object")); var m = s.GetMethod("ReferenceEquals"); m.Name.Should().Be("ReferenceEquals"); @@ -247,7 +247,7 @@ class ClassWithAttributeWithType [TestMethod] public void CanReadCustomAttributes() { - var c = new IkvmReflectionSymbolContext(); + var c = new IkvmReflectionSymbolContext(universe); var s = c.GetOrCreateTypeSymbol(thisAssembly.GetType("IKVM.CoreLib.Tests.Symbols.IkvmReflection.IkvmReflectionSymbolTests+ClassWithAttributeWithType")); var a = s.GetCustomAttribute(c.GetOrCreateTypeSymbol(thisAssembly.GetType("IKVM.CoreLib.Tests.Symbols.IkvmReflection.IkvmReflectionSymbolTests+AttributeWithType"))); var v = a.Value.ConstructorArguments[0].Value; @@ -257,7 +257,7 @@ public void CanReadCustomAttributes() [TestMethod] public void CanResolveAssemblyBuilder() { - var c = new IkvmReflectionSymbolContext(); + var c = new IkvmReflectionSymbolContext(universe); var a = universe.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Save); var assemblySymbol = c.GetOrCreateAssemblySymbol(a); assemblySymbol.Should().BeOfType(); @@ -267,7 +267,7 @@ public void CanResolveAssemblyBuilder() [TestMethod] public void CanResolveModuleBuilder() { - var c = new IkvmReflectionSymbolContext(); + var c = new IkvmReflectionSymbolContext(universe); var a = universe.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Save); var m = a.DefineDynamicModule("DynamicModule", "DynamicModule.dll"); var moduleSymbol = c.GetOrCreateModuleSymbol(m); @@ -278,7 +278,7 @@ public void CanResolveModuleBuilder() [TestMethod] public void CanResolveTypeBuilder() { - var c = new IkvmReflectionSymbolContext(); + var c = new IkvmReflectionSymbolContext(universe); var a = universe.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Save); var m = a.DefineDynamicModule("DynamicModule", "DynamicModule.dll"); @@ -291,7 +291,7 @@ public void CanResolveTypeBuilder() [TestMethod] public void CanResolveMultipleTypeBuilders() { - var c = new IkvmReflectionSymbolContext(); + var c = new IkvmReflectionSymbolContext(universe); var a = universe.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Save); var m = a.DefineDynamicModule("DynamicModule", "DynamicModule.dll"); @@ -310,7 +310,7 @@ public void CanResolveMultipleTypeBuilders() [TestMethod] public void CanResolveMethodBuilder() { - var c = new IkvmReflectionSymbolContext(); + var c = new IkvmReflectionSymbolContext(universe); var a = universe.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Save); var m = a.DefineDynamicModule("DynamicModule", "DynamicModule.dll"); var t = m.DefineType("DynamicType"); @@ -324,7 +324,7 @@ public void CanResolveMethodBuilder() [TestMethod] public void CanResolveMultipleMethodBuilders() { - var c = new IkvmReflectionSymbolContext(); + var c = new IkvmReflectionSymbolContext(universe); var a = universe.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Save); var m = a.DefineDynamicModule("DynamicModule", "DynamicModule.dll"); var t = m.DefineType("DynamicType"); @@ -343,7 +343,7 @@ public void CanResolveMultipleMethodBuilders() [TestMethod] public void CanResolveFieldBuilder() { - var c = new IkvmReflectionSymbolContext(); + var c = new IkvmReflectionSymbolContext(universe); var a = universe.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Save); var m = a.DefineDynamicModule("DynamicModule", "DynamicModule.dll"); var t = m.DefineType("DynamicType"); @@ -357,7 +357,7 @@ public void CanResolveFieldBuilder() [TestMethod] public void CanResolveMultipleFieldBuilders() { - var c = new IkvmReflectionSymbolContext(); + var c = new IkvmReflectionSymbolContext(universe); var a = universe.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Save); var m = a.DefineDynamicModule("DynamicModule", "DynamicModule.dll"); var t = m.DefineType("DynamicType"); @@ -376,7 +376,7 @@ public void CanResolveMultipleFieldBuilders() [TestMethod] public void CanResolvePropertyBuilder() { - var c = new IkvmReflectionSymbolContext(); + var c = new IkvmReflectionSymbolContext(universe); var a = universe.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Save); var m = a.DefineDynamicModule("DynamicModule", "DynamicModule.dll"); var t = m.DefineType("DynamicType"); @@ -390,7 +390,7 @@ public void CanResolvePropertyBuilder() [TestMethod] public void CanResolveMultiplePropertyBuilders() { - var c = new IkvmReflectionSymbolContext(); + var c = new IkvmReflectionSymbolContext(universe); var a = universe.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Save); var m = a.DefineDynamicModule("DynamicModule", "DynamicModule.dll"); var t = m.DefineType("DynamicType"); @@ -409,7 +409,7 @@ public void CanResolveMultiplePropertyBuilders() [TestMethod] public void CanResolveEventBuilder() { - var c = new IkvmReflectionSymbolContext(); + var c = new IkvmReflectionSymbolContext(universe); var a = universe.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Save); var m = a.DefineDynamicModule("DynamicModule", "DynamicModule.dll"); var t = m.DefineType("DynamicType"); @@ -423,7 +423,7 @@ public void CanResolveEventBuilder() [TestMethod] public void CanResolveMultipleEventBuilders() { - var c = new IkvmReflectionSymbolContext(); + var c = new IkvmReflectionSymbolContext(universe); var a = universe.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Save); var m = a.DefineDynamicModule("DynamicModule", "DynamicModule.dll"); var t = m.DefineType("DynamicType"); diff --git a/src/IKVM.CoreLib/Collections/IndexRangeDictionary.cs b/src/IKVM.CoreLib/Collections/IndexRangeDictionary.cs index deae4e8ae..e361df9bb 100644 --- a/src/IKVM.CoreLib/Collections/IndexRangeDictionary.cs +++ b/src/IKVM.CoreLib/Collections/IndexRangeDictionary.cs @@ -1,5 +1,6 @@ using System; using System.Diagnostics; +using System.Runtime.CompilerServices; namespace IKVM.CoreLib.Collections { @@ -11,15 +12,35 @@ namespace IKVM.CoreLib.Collections struct IndexRangeDictionary { - int _initialCapacity; + const int ALIGNMENT = 8; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static internal int AlignTowardsInfinity(int i) + { + if (i >= 0) + return (i + (ALIGNMENT - 1)) & -ALIGNMENT; + else + return -((-i + (ALIGNMENT - 1)) & -ALIGNMENT); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static internal int AlignTowardsZero(int i) + { + if (i >= 0) + return i - (i % ALIGNMENT); + else + return -(-i - (-i % ALIGNMENT)); + } + int _maxCapacity; - int _minKey; - T?[]? _items; + internal int _minKey = 0; + internal int _maxKey = 0; + internal T?[] _items = []; /// /// Initializes a new instance. /// - public IndexRangeDictionary() : this(initialCapacity: 4, maxCapacity: int.MaxValue) + public IndexRangeDictionary() : this(maxCapacity: int.MaxValue) { } @@ -27,21 +48,18 @@ public IndexRangeDictionary() : this(initialCapacity: 4, maxCapacity: int.MaxVal /// /// Initializes a new instance. /// - public IndexRangeDictionary(int initialCapacity = 4, int maxCapacity = int.MaxValue) + public IndexRangeDictionary(int maxCapacity = int.MaxValue) { - if (initialCapacity < 0) - throw new ArgumentOutOfRangeException(nameof(initialCapacity)); if (maxCapacity < 0) throw new ArgumentOutOfRangeException(nameof(maxCapacity)); - _initialCapacity = initialCapacity; _maxCapacity = maxCapacity; } /// /// Gets the capacity of the dictionary. /// - public readonly int Capacity => _items?.Length ?? 0; + public readonly int Capacity => _items.Length; /// /// Gets or sets the item with the specified key, optionally growing the list to accomidate. @@ -61,47 +79,48 @@ public T? this[int key] /// public void EnsureCapacity(int key) { - // initial state, first item, hold only that - if (_items == null) + // on first hit, set keys to this key (not 0) + if (_items.Length == 0) { _minKey = key; - _items = new T[_initialCapacity]; + _maxKey = key; } - // key is less than minKey, grow and shift by difference - if (key < _minKey) - { - // increase length until we encompass key - var len = _items.Length; - while (key - _minKey + len - _items.Length < 0) - len *= 2; - - if (len > _maxCapacity || len < 0) - throw new InvalidOperationException(); + // calculate new min and max aligned + var newMin = Math.Min(_minKey, Math.Min(AlignTowardsZero(key), AlignTowardsInfinity(key))); + var newMax = Math.Max(_maxKey, Math.Max(AlignTowardsZero(key), AlignTowardsInfinity(key))); - var end = _items.Length - 1; - Array.Resize(ref _items, len); - for (int i = end; i >= 0; i--) - _items[i + _minKey - key] = _items[i]; - Array.Clear(_items, 0, end); + // calculate desired length + var len = Math.Max(_items.Length, 8); + while (len < newMax - newMin + 1) + len *= 2; - _minKey = key; - } + // calculate amount to shift + int sft = 0; + if (newMin < _minKey) + sft = _minKey - newMin; - // desired position if after the end of the array, we need to grow, but no copies needed - if (key - _minKey >= _items.Length) + // if we calculated any resize or shift operation, apply + if (_items.Length != len || sft > 0) { - // increase length until we encompass key - var len = _items.Length; - while (key - _minKey >= len) - len *= 2; - - if (len > _maxCapacity || len < 0) - throw new InvalidOperationException(); - - Array.Resize(ref _items, len); + // we will be copying data either to either existing array or new array + var src = _items; + if (_items.Length != len) + _items = new T[len]; + + // copy source data to destination at shift + // clear newly exposed positions + if (src.Length > 0) + { + Array.Copy(src, 0, _items, sft, _maxKey - _minKey + 1); + Array.Clear(_items, 0, sft); + } } + // reset our min and max range + _minKey = newMin; + _maxKey = newMax; + Debug.Assert(key - _minKey >= 0); Debug.Assert(key - _minKey < _items.Length); } @@ -113,7 +132,7 @@ public void EnsureCapacity(int key) readonly T? Get(int key) { var pos = key - _minKey; - if (_items == null || pos < 0 || pos >= _items.Length) + if (pos < 0 || pos >= _items.Length) return default; else return _items[pos]; @@ -121,7 +140,7 @@ public void EnsureCapacity(int key) /// /// Adds a new item to the list. - /// + /// /// /// void Set(int key, T? value) diff --git a/src/IKVM.CoreLib/IKVM.CoreLib.csproj b/src/IKVM.CoreLib/IKVM.CoreLib.csproj index 13b96c3da..13d67775f 100644 --- a/src/IKVM.CoreLib/IKVM.CoreLib.csproj +++ b/src/IKVM.CoreLib/IKVM.CoreLib.csproj @@ -106,12 +106,4 @@ - - - - PreserveNewest - - - - diff --git a/src/IKVM.CoreLib/Symbols/Emit/IILGenerator.cs b/src/IKVM.CoreLib/Symbols/Emit/IILGenerator.cs index 1677d7076..bc74233ab 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/IILGenerator.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/IILGenerator.cs @@ -54,19 +54,19 @@ interface IILGenerator /// Declares a new label. /// /// - System.Reflection.Emit.Label DefineLabel(); + ILabel DefineLabel(); /// /// Begins an exception block for a non-filtered exception. /// /// - System.Reflection.Emit.Label BeginExceptionBlock(); + ILabel BeginExceptionBlock(); /// /// Marks the Microsoft intermediate language (MSIL) stream's current position with the given label. /// /// - void MarkLabel(System.Reflection.Emit.Label loc); + void MarkLabel(ILabel loc); /// /// Begins an exception block for a filtered exception. diff --git a/src/IKVM.CoreLib/Symbols/Emit/ILabel.cs b/src/IKVM.CoreLib/Symbols/Emit/ILabel.cs index c36f9d801..f8c926b72 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/ILabel.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/ILabel.cs @@ -2,5 +2,9 @@ { public interface ILabel { + + + } + } \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/Emit/IModuleSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IModuleSymbolBuilder.cs index 72bb9e7d7..90c4603e1 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/IModuleSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/IModuleSymbolBuilder.cs @@ -1,4 +1,6 @@ -using System.Reflection; +using System; +using System.Diagnostics.SymbolStore; +using System.Reflection; using System.Reflection.Emit; namespace IKVM.CoreLib.Symbols.Emit @@ -7,6 +9,16 @@ namespace IKVM.CoreLib.Symbols.Emit interface IModuleSymbolBuilder : ISymbolBuilder, IModuleSymbol { + /// + /// Defines a document for source. + /// + /// + /// + /// + /// + /// + ISymbolDocumentWriter? DefineDocument(string url, Guid language, Guid languageVendor, Guid documentType); + /// /// Constructs a TypeBuilder for a private type with the specified name in this module. /// diff --git a/src/IKVM.CoreLib/Symbols/Emit/ITypeSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/ITypeSymbolBuilder.cs index 6b4b44107..e888e5028 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/ITypeSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/ITypeSymbolBuilder.cs @@ -145,7 +145,7 @@ interface ITypeSymbolBuilder : ISymbolBuilder, IMemberSymbolBuilder /// /// /// - void DefineMethodOverride(IMethodSymbolBuilder methodInfoBody, IMethodSymbol methodInfoDeclaration); + void DefineMethodOverride(IMethodSymbol methodInfoBody, IMethodSymbol methodInfoDeclaration); /// /// Defines a nested type, given its name, attributes, the type that it extends, and the interfaces that it implements. diff --git a/src/IKVM.CoreLib/Symbols/ISymbolContext.cs b/src/IKVM.CoreLib/Symbols/ISymbolContext.cs index 81457295e..adef5b72e 100644 --- a/src/IKVM.CoreLib/Symbols/ISymbolContext.cs +++ b/src/IKVM.CoreLib/Symbols/ISymbolContext.cs @@ -1,4 +1,7 @@ -using IKVM.CoreLib.Symbols.Emit; +using System.Reflection; +using System.Reflection.Emit; + +using IKVM.CoreLib.Symbols.Emit; namespace IKVM.CoreLib.Symbols { @@ -6,6 +9,22 @@ namespace IKVM.CoreLib.Symbols interface ISymbolContext { + /// + /// Defines a dynamic assembly that has the specified name and access rights. + /// + /// + /// + /// + IAssemblySymbolBuilder DefineAssembly(AssemblyName name, AssemblyBuilderAccess access); + + /// + /// Defines a dynamic assembly that has the specified name and access rights. + /// + /// + /// + /// + IAssemblySymbolBuilder DefineAssembly(AssemblyName name, AssemblyBuilderAccess access, ICustomAttributeBuilder[]? assemblyAttributes); + /// /// Initializes an instance of the interface given the constructor for the custom attribute and the arguments to the constructor. /// diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionAssemblySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionAssemblySymbolBuilder.cs index c8f4ce03e..403ccdcd1 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionAssemblySymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionAssemblySymbolBuilder.cs @@ -4,7 +4,7 @@ namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit { - interface IIkvmReflectionAssemblySymbolBuilder : IIkvmReflectionSymbolBuilder, IAssemblySymbolBuilder, IIkvmReflectionAssemblySymbol + interface IIkvmReflectionAssemblySymbolBuilder : IIkvmReflectionSymbolBuilder, IAssemblySymbolBuilder, IIkvmReflectionAssemblySymbol { /// @@ -12,6 +12,13 @@ interface IIkvmReflectionAssemblySymbolBuilder : IIkvmReflectionSymbolBuilder AssemblyBuilder UnderlyingAssemblyBuilder { get; } + /// + /// Gets or creates a for the specified . + /// + /// + /// + IIkvmReflectionModuleSymbolBuilder GetOrCreateModuleSymbol(ModuleBuilder module); + } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionConstructorSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionConstructorSymbolBuilder.cs index 86b966f98..5f0747645 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionConstructorSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionConstructorSymbolBuilder.cs @@ -4,9 +4,12 @@ namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit { - interface IIkvmReflectionConstructorSymbolBuilder : IIkvmReflectionSymbolBuilder, IIkvmReflectionMethodBaseSymbolBuilder, IConstructorSymbolBuilder, IIkvmReflectionConstructorSymbol + interface IIkvmReflectionConstructorSymbolBuilder : IIkvmReflectionSymbolBuilder, IIkvmReflectionMethodBaseSymbolBuilder, IConstructorSymbolBuilder, IIkvmReflectionConstructorSymbol { + /// + /// Gets the underlying . + /// ConstructorBuilder UnderlyingConstructorBuilder { get; } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionEventSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionEventSymbolBuilder.cs index f5e3f728d..d76fd2a4a 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionEventSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionEventSymbolBuilder.cs @@ -4,9 +4,12 @@ namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit { - interface IIkvmReflectionEventSymbolBuilder : IIkvmReflectionSymbolBuilder, IIkvmReflectionMemberSymbolBuilder, IEventSymbolBuilder, IIkvmReflectionEventSymbol + interface IIkvmReflectionEventSymbolBuilder : IIkvmReflectionSymbolBuilder, IIkvmReflectionMemberSymbolBuilder, IEventSymbolBuilder, IIkvmReflectionEventSymbol { + /// + /// Gets the underlying . + /// EventBuilder UnderlyingEventBuilder { get; } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionFieldSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionFieldSymbolBuilder.cs index fe61f4f34..b70305e9c 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionFieldSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionFieldSymbolBuilder.cs @@ -4,7 +4,7 @@ namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit { - interface IIkvmReflectionFieldSymbolBuilder : IIkvmReflectionSymbolBuilder, IIkvmReflectionMemberSymbolBuilder, IFieldSymbolBuilder, IIkvmReflectionFieldSymbol + interface IIkvmReflectionFieldSymbolBuilder : IIkvmReflectionSymbolBuilder, IIkvmReflectionMemberSymbolBuilder, IFieldSymbolBuilder, IIkvmReflectionFieldSymbol { FieldBuilder UnderlyingFieldBuilder { get; } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionGenericTypeParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionGenericTypeParameterSymbolBuilder.cs index 889de61f2..1395991f1 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionGenericTypeParameterSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionGenericTypeParameterSymbolBuilder.cs @@ -4,7 +4,7 @@ namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit { - interface IIkvmReflectionGenericTypeParameterSymbolBuilder : IIkvmReflectionSymbolBuilder, IGenericTypeParameterSymbolBuilder, IIkvmReflectionTypeSymbol + interface IIkvmReflectionGenericTypeParameterSymbolBuilder : IIkvmReflectionSymbolBuilder, IGenericTypeParameterSymbolBuilder, IIkvmReflectionTypeSymbol { /// diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionMemberSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionMemberSymbolBuilder.cs index e6d8459ce..7e936c529 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionMemberSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionMemberSymbolBuilder.cs @@ -3,9 +3,14 @@ namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit { - interface IIkvmReflectionMemberSymbolBuilder : IIkvmReflectionSymbolBuilder, IMemberSymbolBuilder, IIkvmReflectionMemberSymbol + interface IIkvmReflectionMemberSymbolBuilder : IIkvmReflectionSymbolBuilder, IMemberSymbolBuilder, IIkvmReflectionMemberSymbol { + /// + /// Gets the resolving . + /// + public IIkvmReflectionModuleSymbolBuilder ResolvingModuleBuilder { get; } + /// /// Invoked when the type responsible for this builder is completed. Implementations should update their /// underlying type, and optionally dispatch the OnComplete invocation to downstream elements. diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionMethodBaseSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionMethodBaseSymbolBuilder.cs index b5e6fcd57..89377fdd7 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionMethodBaseSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionMethodBaseSymbolBuilder.cs @@ -1,12 +1,18 @@ using IKVM.CoreLib.Symbols.Emit; +using IKVM.Reflection.Emit; namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit { - interface IIkvmReflectionMethodBaseSymbolBuilder : IIkvmReflectionSymbolBuilder, IIkvmReflectionMemberSymbolBuilder, IMethodBaseSymbolBuilder, IIkvmReflectionMethodBaseSymbol + interface IIkvmReflectionMethodBaseSymbolBuilder : IIkvmReflectionSymbolBuilder, IIkvmReflectionMemberSymbolBuilder, IMethodBaseSymbolBuilder, IIkvmReflectionMethodBaseSymbol { - + /// + /// Gets or creates a for the given . + /// + /// + /// + public IIkvmReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter); } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionMethodSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionMethodSymbolBuilder.cs index 8de047893..aca0b7f63 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionMethodSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionMethodSymbolBuilder.cs @@ -4,7 +4,7 @@ namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit { - interface IIkvmReflectionMethodSymbolBuilder : IIkvmReflectionSymbolBuilder, IIkvmReflectionMethodBaseSymbolBuilder, IMethodSymbolBuilder, IIkvmReflectionMethodSymbol + interface IIkvmReflectionMethodSymbolBuilder : IIkvmReflectionSymbolBuilder, IIkvmReflectionMethodBaseSymbolBuilder, IMethodSymbolBuilder, IIkvmReflectionMethodSymbol { /// @@ -12,6 +12,13 @@ interface IIkvmReflectionMethodSymbolBuilder : IIkvmReflectionSymbolBuilder MethodBuilder UnderlyingMethodBuilder { get; } + /// + /// Gets or creates a for the given . + /// + /// + /// + IIkvmReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeParameterSymbol(GenericTypeParameterBuilder genericTypeParameter); + } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionModuleSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionModuleSymbolBuilder.cs index 564c9e551..fc5f3eb9d 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionModuleSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionModuleSymbolBuilder.cs @@ -4,7 +4,7 @@ namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit { - interface IIkvmReflectionModuleSymbolBuilder : IIkvmReflectionSymbolBuilder, IModuleSymbolBuilder, IIkvmReflectionModuleSymbol + interface IIkvmReflectionModuleSymbolBuilder : IIkvmReflectionSymbolBuilder, IModuleSymbolBuilder, IIkvmReflectionModuleSymbol { /// @@ -12,6 +12,62 @@ interface IIkvmReflectionModuleSymbolBuilder : IIkvmReflectionSymbolBuilder ModuleBuilder UnderlyingModuleBuilder { get; } + /// + /// Gets or creates a for the specified . + /// + /// + /// + IIkvmReflectionTypeSymbolBuilder GetOrCreateTypeSymbol(TypeBuilder type); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IIkvmReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IIkvmReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IIkvmReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IIkvmReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IIkvmReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IIkvmReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IIkvmReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeParameterSymbol(GenericTypeParameterBuilder genericTypeParameter); + } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionParameterSymbolBuilder.cs index 8d74fa945..5b9b0305d 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionParameterSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionParameterSymbolBuilder.cs @@ -4,7 +4,7 @@ namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit { - interface IIkvmReflectionParameterSymbolBuilder : IIkvmReflectionSymbolBuilder, IParameterSymbolBuilder, IIkvmReflectionParameterSymbol + interface IIkvmReflectionParameterSymbolBuilder : IIkvmReflectionSymbolBuilder, IParameterSymbolBuilder, IIkvmReflectionParameterSymbol { /// diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionPropertySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionPropertySymbolBuilder.cs index a52039bdd..723fc6ca0 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionPropertySymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionPropertySymbolBuilder.cs @@ -1,12 +1,16 @@ using IKVM.CoreLib.Symbols.Emit; +using IKVM.Reflection; using IKVM.Reflection.Emit; namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit { - interface IIkvmReflectionPropertySymbolBuilder : IIkvmReflectionSymbolBuilder, IIkvmReflectionMemberSymbolBuilder, IPropertySymbolBuilder, IIkvmReflectionPropertySymbol + interface IIkvmReflectionPropertySymbolBuilder : IIkvmReflectionSymbolBuilder, IIkvmReflectionMemberSymbolBuilder, IPropertySymbolBuilder, IIkvmReflectionPropertySymbol { + /// + /// Gets the underlying . + /// PropertyBuilder UnderlyingPropertyBuilder { get; } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionSymbolBuilder.cs index ce5e76e98..c19769466 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionSymbolBuilder.cs @@ -1,4 +1,7 @@ -using IKVM.CoreLib.Symbols.Emit; +using System.Diagnostics.CodeAnalysis; + +using IKVM.CoreLib.Symbols.Emit; +using IKVM.Reflection.Emit; namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit { @@ -6,13 +9,85 @@ namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit interface IIkvmReflectionSymbolBuilder : ISymbolBuilder { - } + /// + /// Resolves the symbol for the specified assembly builder. + /// + /// + /// + [return: NotNullIfNotNull(nameof(assembly))] + IIkvmReflectionAssemblySymbolBuilder ResolveAssemblySymbol(AssemblyBuilder assembly); - interface IIkvmReflectionSymbolBuilder : IIkvmReflectionSymbolBuilder, ISymbolBuilder - where TSymbol : IIkvmReflectionSymbol - { + /// + /// Resolves the symbol for the specified module. + /// + /// + /// + [return: NotNullIfNotNull(nameof(module))] + IIkvmReflectionModuleSymbolBuilder ResolveModuleSymbol(ModuleBuilder module); + + /// + /// Resolves the symbol for the specified type. + /// + /// + /// + [return: NotNullIfNotNull(nameof(type))] + IIkvmReflectionTypeSymbolBuilder ResolveTypeSymbol(TypeBuilder type); + + /// + /// Resolves the symbol for the specified constructor. + /// + /// + /// + [return: NotNullIfNotNull(nameof(ctor))] + IIkvmReflectionConstructorSymbolBuilder ResolveConstructorSymbol(ConstructorBuilder ctor); + + /// + /// Resolves the symbol for the specified method. + /// + /// + /// + [return: NotNullIfNotNull(nameof(method))] + IIkvmReflectionMethodSymbolBuilder ResolveMethodSymbol(MethodBuilder method); + + /// + /// Resolves the symbol for the specified field. + /// + /// + /// + [return: NotNullIfNotNull(nameof(field))] + IIkvmReflectionFieldSymbolBuilder ResolveFieldSymbol(FieldBuilder field); + + /// + /// Resolves the symbol for the specified property. + /// + /// + /// + [return: NotNullIfNotNull(nameof(property))] + IIkvmReflectionPropertySymbolBuilder ResolvePropertySymbol(PropertyBuilder property); + + /// + /// Resolves the symbol for the specified event. + /// + /// + /// + [return: NotNullIfNotNull(nameof(@event))] + IIkvmReflectionEventSymbolBuilder ResolveEventSymbol(EventBuilder @event); + /// + /// Resolves the symbol for the specified parameter. + /// + /// + /// + [return: NotNullIfNotNull(nameof(parameter))] + IIkvmReflectionParameterSymbolBuilder? ResolveParameterSymbol(ParameterBuilder parameter); + /// + /// Resolves the symbol for the specified generic type parameter. + /// + /// + /// + [return: NotNullIfNotNull(nameof(genericTypeParameter))] + IIkvmReflectionGenericTypeParameterSymbolBuilder? ResolveGenericTypeParameterSymbol(GenericTypeParameterBuilder genericTypeParameter); } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionTypeSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionTypeSymbolBuilder.cs index c16eeb22c..cb7b100a4 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionTypeSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionTypeSymbolBuilder.cs @@ -4,7 +4,7 @@ namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit { - interface IIkvmReflectionTypeSymbolBuilder : IIkvmReflectionSymbolBuilder, IIkvmReflectionMemberSymbolBuilder, ITypeSymbolBuilder, IIkvmReflectionTypeSymbol + interface IIkvmReflectionTypeSymbolBuilder : IIkvmReflectionMemberSymbolBuilder, ITypeSymbolBuilder, IIkvmReflectionTypeSymbol { /// @@ -12,6 +12,48 @@ interface IIkvmReflectionTypeSymbolBuilder : IIkvmReflectionSymbolBuilder TypeBuilder UnderlyingTypeBuilder { get; } + /// + /// Gets or creates a for the given . + /// + /// + /// + IIkvmReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor); + + /// + /// Gets or creates a for the given . + /// + /// + /// + IIkvmReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method); + + /// + /// Gets or creates a for the given . + /// + /// + /// + IIkvmReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field); + + /// + /// Gets or creates a for the given . + /// + /// + /// + IIkvmReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property); + + /// + /// Gets or creates a for the given . + /// + /// + /// + IIkvmReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event); + + /// + /// Gets or creates a for the given . + /// + /// + /// + IIkvmReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeParameterSymbol(GenericTypeParameterBuilder genericTypeParameter); + } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionAssemblySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionAssemblySymbolBuilder.cs index 21a7d7b02..d8e4da24a 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionAssemblySymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionAssemblySymbolBuilder.cs @@ -13,7 +13,8 @@ class IkvmReflectionAssemblySymbolBuilder : IkvmReflectionSymbolBuilder, IIkvmRe { readonly AssemblyBuilder _builder; - IkvmReflectionAssemblyMetadata _metadata; + + IkvmReflectionModuleTable _moduleTable; /// /// Initializes a new instance. @@ -24,7 +25,7 @@ public IkvmReflectionAssemblySymbolBuilder(IkvmReflectionSymbolContext context, base(context) { _builder = builder ?? throw new ArgumentNullException(nameof(builder)); - _metadata = new IkvmReflectionAssemblyMetadata(this); + _moduleTable = new IkvmReflectionModuleTable(context, this); } /// @@ -33,6 +34,26 @@ public IkvmReflectionAssemblySymbolBuilder(IkvmReflectionSymbolContext context, /// public AssemblyBuilder UnderlyingAssemblyBuilder => _builder; + #region IIkvmReflectionAssemblySymbolBuilder + + /// + public IIkvmReflectionModuleSymbolBuilder GetOrCreateModuleSymbol(ModuleBuilder module) + { + return _moduleTable.GetOrCreateModuleSymbol(module); + } + + #endregion + + #region IIkvmReflectionAssemblySymbol + + /// + public IIkvmReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) + { + return _moduleTable.GetOrCreateModuleSymbol(module); + } + + #endregion + #region IAssemblySymbolBuilder /// @@ -120,19 +141,19 @@ public IModuleSymbol[] GetModules(bool getResourceModules) /// public System.Reflection.AssemblyName GetName() { - return UnderlyingAssembly.GetName().ToAssemblyName(); + return UnderlyingAssembly.GetName().Pack(); } /// public System.Reflection.AssemblyName GetName(bool copiedName) { - return UnderlyingAssembly.GetName(copiedName).ToAssemblyName(); + return UnderlyingAssembly.GetName(copiedName).Pack(); } /// public System.Reflection.AssemblyName[] GetReferencedAssemblies() { - return UnderlyingAssembly.GetReferencedAssemblies().ToAssemblyNames(); + return UnderlyingAssembly.GetReferencedAssemblies().Pack(); } /// @@ -185,18 +206,6 @@ public bool IsDefined(ITypeSymbol attributeType, bool inherit = false) #endregion - /// - public IIkvmReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) - { - return _metadata.GetOrCreateModuleSymbol(module); - } - - /// - public IIkvmReflectionModuleSymbolBuilder GetOrCreateModuleSymbol(ModuleBuilder module) - { - return (IIkvmReflectionModuleSymbolBuilder)_metadata.GetOrCreateModuleSymbol(module); - } - } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionConstructorSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionConstructorSymbolBuilder.cs index 962750a1a..66e1ef64d 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionConstructorSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionConstructorSymbolBuilder.cs @@ -13,6 +13,8 @@ class IkvmReflectionConstructorSymbolBuilder : IkvmReflectionMethodBaseSymbolBui ConstructorBuilder? _builder; ConstructorInfo _ctor; + IkvmReflectionILGenerator? _il; + /// /// Initializes a new instance. /// @@ -21,7 +23,7 @@ class IkvmReflectionConstructorSymbolBuilder : IkvmReflectionMethodBaseSymbolBui /// /// /// - public IkvmReflectionConstructorSymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol resolvingModule, IIkvmReflectionTypeSymbol resolvingType, ConstructorBuilder builder) : + public IkvmReflectionConstructorSymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbolBuilder resolvingModule, IIkvmReflectionTypeSymbolBuilder resolvingType, ConstructorBuilder builder) : base(context, resolvingModule, resolvingType) { _builder = builder ?? throw new ArgumentNullException(nameof(builder)); @@ -54,13 +56,13 @@ public IParameterSymbolBuilder DefineParameter(int iSequence, System.Reflection. /// public IILGenerator GetILGenerator() { - throw new NotImplementedException(); + return _il ??= new IkvmReflectionILGenerator(Context, UnderlyingConstructorBuilder.GetILGenerator()); } /// public IILGenerator GetILGenerator(int streamSize) { - throw new NotImplementedException(); + return _il ??= new IkvmReflectionILGenerator(Context, UnderlyingConstructorBuilder.GetILGenerator(streamSize)); } /// diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionEventSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionEventSymbolBuilder.cs index 385d80655..b7c2ca9c3 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionEventSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionEventSymbolBuilder.cs @@ -21,7 +21,7 @@ class IkvmReflectionEventSymbolBuilder : IkvmReflectionMemberSymbolBuilder, IIkv /// /// /// - public IkvmReflectionEventSymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol resolvingModule, IIkvmReflectionTypeSymbol resolvingType, EventBuilder builder) : + public IkvmReflectionEventSymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbolBuilder resolvingModule, IIkvmReflectionTypeSymbolBuilder resolvingType, EventBuilder builder) : base(context, resolvingModule, resolvingType) { _builder = builder ?? throw new ArgumentNullException(nameof(builder)); diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionFieldSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionFieldSymbolBuilder.cs index b485e6561..342d6bce4 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionFieldSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionFieldSymbolBuilder.cs @@ -21,7 +21,7 @@ class IkvmReflectionFieldSymbolBuilder : IkvmReflectionMemberSymbolBuilder, IIkv /// /// /// - public IkvmReflectionFieldSymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol resolvingModule, IIkvmReflectionTypeSymbol? resolvingType, FieldBuilder builder) : + public IkvmReflectionFieldSymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbolBuilder resolvingModule, IIkvmReflectionTypeSymbolBuilder? resolvingType, FieldBuilder builder) : base(context, resolvingModule, resolvingType) { _builder = builder ?? throw new ArgumentNullException(nameof(builder)); diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionGenericTypeParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionGenericTypeParameterSymbolBuilder.cs index 011eb9985..12c2606df 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionGenericTypeParameterSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionGenericTypeParameterSymbolBuilder.cs @@ -11,28 +11,28 @@ namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit class IkvmReflectionGenericTypeParameterSymbolBuilder : IkvmReflectionMemberSymbolBuilder, IIkvmReflectionGenericTypeParameterSymbolBuilder { - readonly IIkvmReflectionMethodSymbol? _resolvingMethod; + readonly IIkvmReflectionMemberSymbol? _resolvingMember; GenericTypeParameterBuilder? _builder; Type _type; - IkvmReflectionTypeImpl _impl; + + IkvmReflectionTypeSpecTable _specTable; /// /// Initializes a new instance. /// /// /// - /// - /// + /// /// /// - public IkvmReflectionGenericTypeParameterSymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol resolvingModule, IIkvmReflectionTypeSymbol? resolvingType, IIkvmReflectionMethodSymbol? resolvingMethod, GenericTypeParameterBuilder builder) : - base(context, resolvingModule, resolvingType) + public IkvmReflectionGenericTypeParameterSymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbolBuilder resolvingModule, IIkvmReflectionMemberSymbolBuilder resolvingMember, GenericTypeParameterBuilder builder) : + base(context, resolvingModule, resolvingMember as IIkvmReflectionTypeSymbolBuilder) { - _resolvingMethod = resolvingMethod; + _resolvingMember = resolvingMember ?? throw new ArgumentNullException(nameof(resolvingMember)); _builder = builder ?? throw new ArgumentNullException(nameof(builder)); _type = _builder; - _impl = new IkvmReflectionTypeImpl(this); + _specTable = new IkvmReflectionTypeSpecTable(); } /// @@ -41,9 +41,125 @@ public IkvmReflectionGenericTypeParameterSymbolBuilder(IkvmReflectionSymbolConte /// public override MemberInfo UnderlyingMember => UnderlyingType; + #region IIkvmReflectionGenericTypeParameterSymbolBuilder + /// public GenericTypeParameterBuilder UnderlyingGenericTypeParameterBuilder => _builder ?? throw new InvalidOperationException(); + #endregion + + #region IIkvmReflectionTypeSymbol + + /// + public IIkvmReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method) + { + throw new NotSupportedException(); + } + + /// + public IIkvmReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) + { + throw new NotSupportedException(); + } + + /// + public IIkvmReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor) + { + throw new NotSupportedException(); + } + + /// + public IIkvmReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) + { + throw new NotSupportedException(); + } + + /// + public IIkvmReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method) + { + throw new NotSupportedException(); + } + + /// + public IIkvmReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) + { + throw new NotSupportedException(); + } + + /// + public IIkvmReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field) + { + throw new NotSupportedException(); + } + + /// + public IIkvmReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) + { + throw new NotSupportedException(); + } + + /// + public IIkvmReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property) + { + throw new NotSupportedException(); + } + + /// + public IIkvmReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) + { + throw new NotSupportedException(); + } + + /// + public IIkvmReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event) + { + throw new NotSupportedException(); + } + + /// + public IIkvmReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type type) + { + throw new NotSupportedException(); + } + + /// + public IIkvmReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeSymbol(GenericTypeParameterBuilder genericType) + { + throw new NotSupportedException(); + } + + /// + public IIkvmReflectionTypeSymbol GetOrCreateSZArrayTypeSymbol() + { + return _specTable.GetOrCreateSZArrayTypeSymbol(); + } + + /// + public IIkvmReflectionTypeSymbol GetOrCreateArrayTypeSymbol(int rank) + { + return _specTable.GetOrCreateArrayTypeSymbol(rank); + } + + /// + public IIkvmReflectionTypeSymbol GetOrCreatePointerTypeSymbol() + { + return _specTable.GetOrCreatePointerTypeSymbol(); + } + + /// + public IIkvmReflectionTypeSymbol GetOrCreateByRefTypeSymbol() + { + return _specTable.GetOrCreateByRefTypeSymbol(); + } + + /// + public IIkvmReflectionTypeSymbol GetOrCreateGenericTypeSymbol(Type[] genericTypeDefinition) + { + return _specTable.GetOrCreateGenericTypeSymbol(genericTypeDefinition); + } + + #endregion + #region ITypeSymbolBuilder /// @@ -69,506 +185,513 @@ public void SetInterfaceConstraints(params ITypeSymbol[]? interfaceConstraints) #region ITypeSymbol /// - public System.Reflection.TypeAttributes Attributes => (System.Reflection.TypeAttributes)_impl.Attributes; + public IAssemblySymbol Assembly => ResolveAssemblySymbol(UnderlyingType.Assembly); /// - public IAssemblySymbol Assembly => _impl.Assembly; + public string? AssemblyQualifiedName => UnderlyingType.AssemblyQualifiedName; /// - public IMethodBaseSymbol? DeclaringMethod => _impl.DeclaringMethod; + public System.Reflection.TypeAttributes Attributes => (System.Reflection.TypeAttributes)UnderlyingType.Attributes; /// - public string? AssemblyQualifiedName => _impl.AssemblyQualifiedName; + public ITypeSymbol? BaseType => ResolveTypeSymbol(UnderlyingType.BaseType); /// - public string? FullName => _impl.FullName; + public bool ContainsGenericParameters => UnderlyingType.ContainsGenericParameters; /// - public string? Namespace => _impl.Namespace; + public IMethodBaseSymbol? DeclaringMethod => ResolveMethodBaseSymbol(UnderlyingType.DeclaringMethod); /// - public TypeCode TypeCode => _impl.TypeCode; + public string? FullName => UnderlyingType.FullName; /// - public ITypeSymbol? BaseType => _impl.BaseType; + public string? Namespace => UnderlyingType.Namespace; /// - public bool ContainsGenericParameters => _impl.ContainsGenericParameters; + public System.Reflection.GenericParameterAttributes GenericParameterAttributes => (System.Reflection.GenericParameterAttributes)UnderlyingType.GenericParameterAttributes; /// - public System.Reflection.GenericParameterAttributes GenericParameterAttributes => (System.Reflection.GenericParameterAttributes)_impl.GenericParameterAttributes; + public int GenericParameterPosition => UnderlyingType.GenericParameterPosition; /// - public int GenericParameterPosition => _impl.GenericParameterPosition; + public ITypeSymbol[] GenericTypeArguments => ResolveTypeSymbols(UnderlyingType.GenericTypeArguments); /// - public ITypeSymbol[] GenericTypeArguments => _impl.GenericTypeArguments; + public bool HasElementType => UnderlyingType.HasElementType; /// - public bool IsConstructedGenericType => _impl.IsConstructedGenericType; + public TypeCode TypeCode => Type.GetTypeCode(UnderlyingType); /// - public bool IsGenericType => _impl.IsGenericType; + public bool IsAbstract => UnderlyingType.IsAbstract; /// - public bool IsGenericTypeDefinition => _impl.IsGenericTypeDefinition; + public bool IsSZArray => UnderlyingType.IsSZArray; /// - public bool IsGenericParameter => _impl.IsGenericParameter; + public bool IsArray => UnderlyingType.IsArray; /// - public bool IsAutoLayout => _impl.IsAutoLayout; + public bool IsAutoLayout => UnderlyingType.IsAutoLayout; /// - public bool IsExplicitLayout => _impl.IsExplicitLayout; + public bool IsExplicitLayout => UnderlyingType.IsExplicitLayout; /// - public bool IsLayoutSequential => _impl.IsLayoutSequential; + public bool IsByRef => UnderlyingType.IsByRef; /// - public bool HasElementType => _impl.HasElementType; + public bool IsClass => UnderlyingType.IsClass; /// - public bool IsClass => _impl.IsClass; + public bool IsEnum => UnderlyingType.IsEnum; /// - public bool IsValueType => _impl.IsValueType; + public bool IsInterface => UnderlyingType.IsInterface; /// - public bool IsInterface => _impl.IsInterface; + public bool IsConstructedGenericType => UnderlyingType.IsConstructedGenericType; /// - public bool IsPrimitive => _impl.IsPrimitive; + public bool IsGenericParameter => UnderlyingType.IsGenericParameter; /// - public bool IsSZArray => _impl.IsSZArray; + public bool IsGenericType => UnderlyingType.IsGenericType; /// - public bool IsArray => _impl.IsArray; + public bool IsGenericTypeDefinition => UnderlyingType.IsGenericTypeDefinition; /// - public bool IsEnum => _impl.IsEnum; + public bool IsLayoutSequential => UnderlyingType.IsLayoutSequential; /// - public bool IsPointer => _impl.IsPointer; + public bool IsNested => UnderlyingType.IsNested; /// - public bool IsFunctionPointer => _impl.IsFunctionPointer; + public bool IsNestedAssembly => UnderlyingType.IsNestedAssembly; /// - public bool IsUnmanagedFunctionPointer => _impl.IsUnmanagedFunctionPointer; + public bool IsNestedFamANDAssem => UnderlyingType.IsNestedFamANDAssem; /// - public bool IsByRef => _impl.IsByRef; + public bool IsNestedFamORAssem => UnderlyingType.IsNestedFamORAssem; /// - public bool IsAbstract => _impl.IsAbstract; + public bool IsNestedFamily => UnderlyingType.IsNestedFamily; /// - public bool IsSealed => _impl.IsSealed; + public bool IsNestedPrivate => UnderlyingType.IsNestedPrivate; /// - public bool IsVisible => _impl.IsVisible; + public bool IsNestedPublic => UnderlyingType.IsNestedPublic; /// - public bool IsPublic => _impl.IsPublic; + public bool IsNotPublic => UnderlyingType.IsNotPublic; /// - public bool IsNotPublic => _impl.IsNotPublic; + public bool IsPointer => UnderlyingType.IsPointer; /// - public bool IsNested => _impl.IsNested; + public bool IsFunctionPointer => UnderlyingType.IsFunctionPointer; /// - public bool IsNestedAssembly => _impl.IsNestedAssembly; + public bool IsUnmanagedFunctionPointer => UnderlyingType.IsUnmanagedFunctionPointer; /// - public bool IsNestedFamANDAssem => _impl.IsNestedFamANDAssem; + public bool IsPrimitive => UnderlyingType.IsPrimitive; /// - public bool IsNestedFamily => _impl.IsNestedFamily; + public bool IsPublic => UnderlyingType.IsPublic; /// - public bool IsNestedFamORAssem => _impl.IsNestedFamORAssem; + public bool IsSealed => UnderlyingType.IsSealed; /// - public bool IsNestedPrivate => _impl.IsNestedPrivate; + public bool IsSerializable => UnderlyingType.IsSerializable; /// - public bool IsNestedPublic => _impl.IsNestedPublic; + public bool IsValueType => UnderlyingType.IsValueType; /// - public bool IsSerializable => _impl.IsSerializable; + public bool IsVisible => UnderlyingType.IsVisible; /// - public bool IsSignatureType => _impl.IsSignatureType; + public bool IsSignatureType => throw new NotImplementedException(); /// - public bool IsSpecialName => _impl.IsSpecialName; + public bool IsSpecialName => UnderlyingType.IsSpecialName; /// - public IConstructorSymbol? TypeInitializer => _impl.TypeInitializer; + public IConstructorSymbol? TypeInitializer => ResolveConstructorSymbol(UnderlyingType.TypeInitializer); /// - public override bool IsComplete => _builder == null; + public int GetArrayRank() + { + return UnderlyingType.GetArrayRank(); + } /// - public int GetArrayRank() + public IConstructorSymbol? GetConstructor(System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) { - return _impl.GetArrayRank(); + return ResolveConstructorSymbol(UnderlyingType.GetConstructor((BindingFlags)bindingAttr, binder: null, types.Unpack(), modifiers: null)); } /// - public IMemberSymbol[] GetDefaultMembers() + public IConstructorSymbol? GetConstructor(ITypeSymbol[] types) { - return _impl.GetDefaultMembers(); + return ResolveConstructorSymbol(UnderlyingType.GetConstructor(types.Unpack())); } /// - public ITypeSymbol? GetElementType() + public IConstructorSymbol[] GetConstructors() { - return _impl.GetElementType(); + return ResolveConstructorSymbols(UnderlyingType.GetConstructors()); } /// - public string? GetEnumName(object value) + public IConstructorSymbol[] GetConstructors(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetEnumName(value); + return ResolveConstructorSymbols(UnderlyingType.GetConstructors((BindingFlags)bindingAttr)); } /// - public string[] GetEnumNames() + public IMemberSymbol[] GetDefaultMembers() { - return _impl.GetEnumNames(); + return ResolveMemberSymbols(UnderlyingType.GetDefaultMembers()); } /// - public ITypeSymbol GetEnumUnderlyingType() + public ITypeSymbol? GetElementType() { - return _impl.GetEnumUnderlyingType(); + return ResolveTypeSymbol(UnderlyingType.GetElementType()); } /// - public ITypeSymbol[] GetGenericArguments() + public string? GetEnumName(object value) { - return _impl.GetGenericArguments(); + return UnderlyingType.GetEnumName(value); } /// - public ITypeSymbol[] GetGenericParameterConstraints() + public string[] GetEnumNames() { - return _impl.GetGenericParameterConstraints(); + return UnderlyingType.GetEnumNames(); } /// - public ITypeSymbol GetGenericTypeDefinition() + public ITypeSymbol GetEnumUnderlyingType() { - return _impl.GetGenericTypeDefinition(); + return ResolveTypeSymbol(UnderlyingType.GetEnumUnderlyingType()); } /// - public ITypeSymbol? GetInterface(string name) + public Array GetEnumValues() { - return _impl.GetInterface(name); + return UnderlyingType.GetEnumValues(); } /// - public ITypeSymbol? GetInterface(string name, bool ignoreCase) + public IEventSymbol? GetEvent(string name) { - return _impl.GetInterface(name, ignoreCase); + return ResolveEventSymbol(UnderlyingType.GetEvent(name)); } /// - public ITypeSymbol[] GetInterfaces(bool inherit = true) + public IEventSymbol? GetEvent(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetInterfaces(inherit); + return ResolveEventSymbol(UnderlyingType.GetEvent(name, (BindingFlags)bindingAttr)); } /// - public InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) + public IEventSymbol[] GetEvents() { - return _impl.GetInterfaceMap(interfaceType); + return ResolveEventSymbols(UnderlyingType.GetEvents()); } /// - public IMemberSymbol[] GetMember(string name) + public IEventSymbol[] GetEvents(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMember(name); + return ResolveEventSymbols(UnderlyingType.GetEvents((BindingFlags)bindingAttr)); } /// - public IMemberSymbol[] GetMember(string name, System.Reflection.BindingFlags bindingAttr) + public IFieldSymbol? GetField(string name) { - return _impl.GetMember(name, bindingAttr); + return ResolveFieldSymbol(UnderlyingType.GetField(name)); } /// - public IMemberSymbol[] GetMember(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) + public IFieldSymbol? GetField(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMember(name, type, bindingAttr); + return ResolveFieldSymbol(UnderlyingType.GetField(name, (BindingFlags)bindingAttr)); } /// - public IMemberSymbol[] GetMembers() + public IFieldSymbol[] GetFields() { - return _impl.GetMembers(); + return ResolveFieldSymbols(UnderlyingType.GetFields()); } /// - public IMemberSymbol[] GetMembers(System.Reflection.BindingFlags bindingAttr) + public IFieldSymbol[] GetFields(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMembers(bindingAttr); + return ResolveFieldSymbols(UnderlyingType.GetFields((BindingFlags)bindingAttr)); } - public IConstructorSymbol? GetConstructor(ITypeSymbol[] types) + /// + public ITypeSymbol[] GetGenericArguments() { - return _impl.GetConstructor(types); + return ResolveTypeSymbols(UnderlyingType.GetGenericArguments()); } /// - public IConstructorSymbol? GetConstructor(System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) + public ITypeSymbol[] GetGenericParameterConstraints() { - return _impl.GetConstructor(bindingAttr, types); + return ResolveTypeSymbols(UnderlyingType.GetGenericParameterConstraints()); } /// - public IConstructorSymbol[] GetConstructors() + public ITypeSymbol GetGenericTypeDefinition() { - return _impl.GetConstructors(); + return ResolveTypeSymbol(UnderlyingType.GetGenericTypeDefinition()); } /// - public IConstructorSymbol[] GetConstructors(System.Reflection.BindingFlags bindingAttr) + public ITypeSymbol? GetInterface(string name) { - return _impl.GetConstructors(bindingAttr); + return ResolveTypeSymbol(UnderlyingType.GetInterface(name)); } /// - public IFieldSymbol? GetField(string name) + public ITypeSymbol? GetInterface(string name, bool ignoreCase) { - return _impl.GetField(name); + return ResolveTypeSymbol(UnderlyingType.GetInterface(name, ignoreCase)); } /// - public IFieldSymbol? GetField(string name, System.Reflection.BindingFlags bindingAttr) + public InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) { - return _impl.GetField(name, bindingAttr); + return ResolveInterfaceMapping(UnderlyingType.GetInterfaceMap(interfaceType.Unpack())); } /// - public IFieldSymbol[] GetFields() + public ITypeSymbol[] GetInterfaces(bool inherit = true) { - return _impl.GetFields(); + if (inherit) + return ResolveTypeSymbols(UnderlyingType.GetInterfaces()); + else + throw new NotImplementedException(); } /// - public IFieldSymbol[] GetFields(System.Reflection.BindingFlags bindingAttr) + public IMemberSymbol[] GetMember(string name) { - return _impl.GetFields(bindingAttr); + return ResolveMemberSymbols(UnderlyingType.GetMember(name)); } /// - public IMethodSymbol? GetMethod(string name) + public IMemberSymbol[] GetMember(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMethod(name); + return ResolveMemberSymbols(UnderlyingType.GetMember(name, (BindingFlags)bindingAttr)); } /// - public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) + public IMemberSymbol[] GetMember(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMethod(name, types); + return ResolveMemberSymbols(UnderlyingType.GetMember(name, (MemberTypes)type, (BindingFlags)bindingAttr)); } /// - public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr) + public IMemberSymbol[] GetMembers(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMethod(name, bindingAttr); + return ResolveMemberSymbols(UnderlyingType.GetMembers((BindingFlags)bindingAttr)); } /// - public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) + public IMemberSymbol[] GetMembers() { - return _impl.GetMethod(name, bindingAttr, types); + return ResolveMemberSymbols(UnderlyingType.GetMembers()); } /// - public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMethod(name, bindingAttr, callConvention, types, modifiers); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr)); } /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) { - return _impl.GetMethod(name, genericParameterCount, bindingAttr, callConvention, types, modifiers); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, types.Unpack())); } /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) { - return _impl.GetMethod(name, genericParameterCount, bindingAttr, types, modifiers); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), null)); } /// - public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name) { - return _impl.GetMethod(name, bindingAttr, types, modifiers); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name)); } /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return _impl.GetMethod(name, genericParameterCount, types, modifiers); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, (CallingConventions)callConvention, types.Unpack(), modifiers?.Unpack())); } /// - public IMethodSymbol[] GetMethods() + public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return _impl.GetMethods(); + throw new NotImplementedException(); } /// - public IMethodSymbol[] GetMethods(System.Reflection.BindingFlags bindingAttr) + public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return _impl.GetMethods(bindingAttr); + throw new NotImplementedException(); } /// - public IPropertySymbol? GetProperty(string name) + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return _impl.GetProperty(name); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), modifiers?.Unpack())); } /// - public IPropertySymbol? GetProperty(string name, System.Reflection.BindingFlags bindingAttr) + public IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return _impl.GetProperty(name, bindingAttr); + throw new NotImplementedException(); } /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol[] types) + public IMethodSymbol[] GetMethods(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetProperty(name, types); + return ResolveMethodSymbols(UnderlyingType.GetMethods((BindingFlags)bindingAttr)); } /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types) + public IMethodSymbol[] GetMethods() { - return _impl.GetProperty(name, returnType, types); + return ResolveMethodSymbols(UnderlyingType.GetMethods()); } /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) + public ITypeSymbol? GetNestedType(string name) { - return _impl.GetProperty(name, returnType); + return ResolveTypeSymbol(UnderlyingType.GetNestedType(name)); } /// - public IPropertySymbol[] GetProperties() + public ITypeSymbol? GetNestedType(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetProperties(); + return ResolveTypeSymbol(UnderlyingType.GetNestedType(name, (BindingFlags)bindingAttr)); } /// - public IPropertySymbol[] GetProperties(System.Reflection.BindingFlags bindingAttr) + public ITypeSymbol[] GetNestedTypes() { - return _impl.GetProperties(bindingAttr); + return ResolveTypeSymbols(UnderlyingType.GetNestedTypes()); } /// - public IEventSymbol? GetEvent(string name) + public ITypeSymbol[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetEvent(name); + return ResolveTypeSymbols(UnderlyingType.GetNestedTypes((BindingFlags)bindingAttr)); } /// - public IEventSymbol? GetEvent(string name, System.Reflection.BindingFlags bindingAttr) + public IPropertySymbol[] GetProperties() { - return _impl.GetEvent(name, bindingAttr); + return ResolvePropertySymbols(UnderlyingType.GetProperties()); } /// - public IEventSymbol[] GetEvents() + public IPropertySymbol[] GetProperties(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetEvents(); + return ResolvePropertySymbols(UnderlyingType.GetProperties((BindingFlags)bindingAttr)); } /// - public IEventSymbol[] GetEvents(System.Reflection.BindingFlags bindingAttr) + public IPropertySymbol? GetProperty(string name, ITypeSymbol[] types) { - return _impl.GetEvents(bindingAttr); + return ResolvePropertySymbol(UnderlyingType.GetProperty(name, types.Unpack())); } /// - public ITypeSymbol? GetNestedType(string name) + public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types) { - return _impl.GetNestedType(name); + return ResolvePropertySymbol(UnderlyingType.GetProperty(name, returnType?.Unpack(), types.Unpack())); } /// - public ITypeSymbol? GetNestedType(string name, System.Reflection.BindingFlags bindingAttr) + public IPropertySymbol? GetProperty(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetNestedType(name, bindingAttr); + return ResolvePropertySymbol(UnderlyingType.GetProperty(name, (BindingFlags)bindingAttr)); } /// - public ITypeSymbol[] GetNestedTypes() + public IPropertySymbol? GetProperty(string name) { - return _impl.GetNestedTypes(); + return ResolvePropertySymbol(UnderlyingType.GetProperty(name)); } /// - public ITypeSymbol[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr) + public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) { - return _impl.GetNestedTypes(); + return ResolvePropertySymbol(UnderlyingType.GetProperty(name, returnType?.Unpack())); } /// public bool IsAssignableFrom(ITypeSymbol? c) { - return _impl.IsAssignableFrom(c); + return UnderlyingType.IsAssignableFrom(c?.Unpack()); } /// - public bool IsSubclassOf(ITypeSymbol c) + public bool IsEnumDefined(object value) { - return _impl.IsSubclassOf(c); + return UnderlyingType.IsEnumDefined(value); } /// - public bool IsEnumDefined(object value) + public bool IsSubclassOf(ITypeSymbol c) { - return _impl.IsEnumDefined(value); + return UnderlyingType.IsSubclassOf(c.Unpack()); } /// public ITypeSymbol MakeArrayType() { - return _impl.MakeArrayType(); + return ResolveTypeSymbol(UnderlyingType.MakeArrayType()); } /// public ITypeSymbol MakeArrayType(int rank) { - return _impl.MakeArrayType(rank); + return ResolveTypeSymbol(UnderlyingType.MakeArrayType(rank)); } /// - public ITypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments) + public ITypeSymbol MakeByRefType() { - return _impl.MakeGenericType(typeArguments); + return ResolveTypeSymbol(UnderlyingType.MakeByRefType()); } /// public ITypeSymbol MakePointerType() { - return _impl.MakePointerType(); + return ResolveTypeSymbol(UnderlyingType.MakePointerType()); } /// - public ITypeSymbol MakeByRefType() + public ITypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments) { - return _impl.MakeByRefType(); + return ResolveTypeSymbol(UnderlyingType.MakeGenericType(typeArguments.Unpack())); } #endregion diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionILGenerator.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionILGenerator.cs new file mode 100644 index 000000000..f83e7c390 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionILGenerator.cs @@ -0,0 +1,499 @@ +using System; +using System.Diagnostics.SymbolStore; +using System.Runtime.InteropServices; + +using IKVM.CoreLib.Symbols.Emit; +using IKVM.Reflection; +using IKVM.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + class IkvmReflectionILGenerator : IILGenerator + { + + readonly IkvmReflectionSymbolContext _context; + readonly ILGenerator _il; + + /// + /// Initializes a new instance. + /// + /// + public IkvmReflectionILGenerator(IkvmReflectionSymbolContext context, ILGenerator il) + { + _context = context ?? throw new ArgumentNullException(nameof(context)); + _il = il ?? throw new ArgumentNullException(nameof(il)); + } + + /// + public int ILOffset => _il.ILOffset; + + /// + public void BeginCatchBlock(ITypeSymbol? exceptionType) + { + _il.BeginCatchBlock(exceptionType?.Unpack()); + } + + /// + public void BeginExceptFilterBlock() + { + _il.BeginExceptFilterBlock(); + } + + /// + public ILabel BeginExceptionBlock() + { + return new IkvmReflectionLabel(_il.BeginExceptionBlock()); + } + + /// + public void BeginFaultBlock() + { + _il.BeginFaultBlock(); + } + + /// + public void BeginFinallyBlock() + { + _il.BeginFinallyBlock(); + } + + /// + public void BeginScope() + { + _il.BeginScope(); + } + + /// + public ILocalBuilder DeclareLocal(ITypeSymbol localType, bool pinned) + { + return new IkvmReflectionLocalBuilder(_context, _il.DeclareLocal(localType.Unpack(), pinned)); + } + + /// + public ILocalBuilder DeclareLocal(ITypeSymbol localType) + { + return new IkvmReflectionLocalBuilder(_context, _il.DeclareLocal(localType.Unpack())); + } + + /// + public ILabel DefineLabel() + { + return new IkvmReflectionLabel(_il.DefineLabel()); + } + + /// + public void Emit(System.Reflection.Emit.OpCode opcode, ILocalBuilder local) + { + _il.Emit(Convert(opcode), local.Unpack()); + } + + /// + public void Emit(System.Reflection.Emit.OpCode opcode, ITypeSymbol cls) + { + _il.Emit(Convert(opcode), cls.Unpack()); + } + + /// + public void Emit(System.Reflection.Emit.OpCode opcode, string str) + { + _il.Emit(Convert(opcode), str); + } + + /// + public void Emit(System.Reflection.Emit.OpCode opcode, float arg) + { + _il.Emit(Convert(opcode), arg); + } + + /// + public void Emit(System.Reflection.Emit.OpCode opcode, sbyte arg) + { + _il.Emit(Convert(opcode), arg); + } + + /// + public void Emit(System.Reflection.Emit.OpCode opcode, IMethodSymbol meth) + { + _il.Emit(Convert(opcode), meth.Unpack()); + } + + /// + public void Emit(System.Reflection.Emit.OpCode opcode, ISignatureHelper signature) + { + throw new NotImplementedException(); + //_il.Emit(Convert(opcode), signature.Unpack()); + } + + /// + public void Emit(System.Reflection.Emit.OpCode opcode, ILabel[] labels) + { + _il.Emit(Convert(opcode), labels.Unpack()); + } + + /// + public void Emit(System.Reflection.Emit.OpCode opcode, IFieldSymbol field) + { + _il.Emit(Convert(opcode), field.Unpack()); + } + + /// + public void Emit(System.Reflection.Emit.OpCode opcode, IConstructorSymbol con) + { + _il.Emit(Convert(opcode), con.Unpack()); + } + + /// + public void Emit(System.Reflection.Emit.OpCode opcode, long arg) + { + _il.Emit(Convert(opcode), arg); + } + + /// + public void Emit(System.Reflection.Emit.OpCode opcode, int arg) + { + _il.Emit(Convert(opcode), arg); + } + + /// + public void Emit(System.Reflection.Emit.OpCode opcode, short arg) + { + _il.Emit(Convert(opcode), arg); + } + + /// + public void Emit(System.Reflection.Emit.OpCode opcode, double arg) + { + _il.Emit(Convert(opcode), arg); + } + + /// + public void Emit(System.Reflection.Emit.OpCode opcode, byte arg) + { + _il.Emit(Convert(opcode), arg); + } + + /// + public void Emit(System.Reflection.Emit.OpCode opcode) + { + _il.Emit(Convert(opcode)); + } + + /// + public void Emit(System.Reflection.Emit.OpCode opcode, ILabel label) + { + _il.Emit(Convert(opcode), label.Unpack()); + } + + /// + public void EmitCall(System.Reflection.Emit.OpCode opcode, IMethodSymbol methodInfo, ITypeSymbol[]? optionalParameterTypes) + { + _il.EmitCall(Convert(opcode), methodInfo.Unpack(), optionalParameterTypes?.Unpack()); + } + + /// + public void EmitCalli(System.Reflection.Emit.OpCode opcode, CallingConvention unmanagedCallConv, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes) + { + _il.EmitCalli(Convert(opcode), unmanagedCallConv, returnType?.Unpack(), parameterTypes?.Unpack()); + } + + /// + public void EmitCalli(System.Reflection.Emit.OpCode opcode, System.Reflection.CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes, ITypeSymbol[]? optionalParameterTypes) + { + _il.EmitCalli(Convert(opcode), (CallingConventions)callingConvention, returnType?.Unpack(), parameterTypes?.Unpack(), optionalParameterTypes?.Unpack()); + } + + /// + public void EmitWriteLine(string value) + { + throw new NotImplementedException(); + } + + /// + public void EmitWriteLine(IFieldSymbol fld) + { + throw new NotImplementedException(); + } + + /// + public void EmitWriteLine(ILocalBuilder localBuilder) + { + throw new NotImplementedException(); + } + + /// + public void EndExceptionBlock() + { + _il.EndExceptionBlock(); + } + + /// + public void EndScope() + { + _il.EndScope(); + } + + /// + public void MarkLabel(ILabel loc) + { + _il.MarkLabel(loc.Unpack()); + } + + /// + public void MarkSequencePoint(ISymbolDocumentWriter document, int startLine, int startColumn, int endLine, int endColumn) + { +#if NETFRAMEWORK + _il.MarkSequencePoint(document, startLine, startColumn, endLine, endColumn); +#endif + } + + /// + public void ThrowException(ITypeSymbol excType) + { + _il.ThrowException(excType.Unpack()); + } + + /// + public void UsingNamespace(string usingNamespace) + { + _il.UsingNamespace(usingNamespace); + } + + /// + /// Converts the given OpCode value into a IKVM OpCode value. + /// + /// + /// + /// + OpCode Convert(System.Reflection.Emit.OpCode opcode) + { + return (ushort)opcode.Value switch + { + 0x00 => OpCodes.Nop, + 0x01 => OpCodes.Break, + 0x02 => OpCodes.Ldarg_0, + 0x03 => OpCodes.Ldarg_1, + 0x04 => OpCodes.Ldarg_2, + 0x05 => OpCodes.Ldarg_3, + 0x06 => OpCodes.Ldloc_0, + 0x07 => OpCodes.Ldloc_1, + 0x08 => OpCodes.Ldloc_2, + 0x09 => OpCodes.Ldloc_3, + 0x0a => OpCodes.Stloc_0, + 0x0b => OpCodes.Stloc_1, + 0x0c => OpCodes.Stloc_2, + 0x0d => OpCodes.Stloc_3, + 0x0e => OpCodes.Ldarg_S, + 0x0f => OpCodes.Ldarga_S, + 0x10 => OpCodes.Starg_S, + 0x11 => OpCodes.Ldloc_S, + 0x12 => OpCodes.Ldloca_S, + 0x13 => OpCodes.Stloc_S, + 0x14 => OpCodes.Ldnull, + 0x15 => OpCodes.Ldc_I4_M1, + 0x16 => OpCodes.Ldc_I4_0, + 0x17 => OpCodes.Ldc_I4_1, + 0x18 => OpCodes.Ldc_I4_2, + 0x19 => OpCodes.Ldc_I4_3, + 0x1a => OpCodes.Ldc_I4_4, + 0x1b => OpCodes.Ldc_I4_5, + 0x1c => OpCodes.Ldc_I4_6, + 0x1d => OpCodes.Ldc_I4_7, + 0x1e => OpCodes.Ldc_I4_8, + 0x1f => OpCodes.Ldc_I4_S, + 0x20 => OpCodes.Ldc_I4, + 0x21 => OpCodes.Ldc_I8, + 0x22 => OpCodes.Ldc_R4, + 0x23 => OpCodes.Ldc_R8, + 0x25 => OpCodes.Dup, + 0x26 => OpCodes.Pop, + 0x27 => OpCodes.Jmp, + 0x28 => OpCodes.Call, + 0x29 => OpCodes.Calli, + 0x2a => OpCodes.Ret, + 0x2b => OpCodes.Br_S, + 0x2c => OpCodes.Brfalse_S, + 0x2d => OpCodes.Brtrue_S, + 0x2e => OpCodes.Beq_S, + 0x2f => OpCodes.Bge_S, + 0x30 => OpCodes.Bgt_S, + 0x31 => OpCodes.Ble_S, + 0x32 => OpCodes.Blt_S, + 0x33 => OpCodes.Bne_Un_S, + 0x34 => OpCodes.Bge_Un_S, + 0x35 => OpCodes.Bgt_Un_S, + 0x36 => OpCodes.Ble_Un_S, + 0x37 => OpCodes.Blt_Un_S, + 0x38 => OpCodes.Br, + 0x39 => OpCodes.Brfalse, + 0x3a => OpCodes.Brtrue, + 0x3b => OpCodes.Beq, + 0x3c => OpCodes.Bge, + 0x3d => OpCodes.Bgt, + 0x3e => OpCodes.Ble, + 0x3f => OpCodes.Blt, + 0x40 => OpCodes.Bne_Un, + 0x41 => OpCodes.Bge_Un, + 0x42 => OpCodes.Bgt_Un, + 0x43 => OpCodes.Ble_Un, + 0x44 => OpCodes.Blt_Un, + 0x45 => OpCodes.Switch, + 0x46 => OpCodes.Ldind_I1, + 0x47 => OpCodes.Ldind_U1, + 0x48 => OpCodes.Ldind_I2, + 0x49 => OpCodes.Ldind_U2, + 0x4a => OpCodes.Ldind_I4, + 0x4b => OpCodes.Ldind_U4, + 0x4c => OpCodes.Ldind_I8, + 0x4d => OpCodes.Ldind_I, + 0x4e => OpCodes.Ldind_R4, + 0x4f => OpCodes.Ldind_R8, + 0x50 => OpCodes.Ldind_Ref, + 0x51 => OpCodes.Stind_Ref, + 0x52 => OpCodes.Stind_I1, + 0x53 => OpCodes.Stind_I2, + 0x54 => OpCodes.Stind_I4, + 0x55 => OpCodes.Stind_I8, + 0x56 => OpCodes.Stind_R4, + 0x57 => OpCodes.Stind_R8, + 0x58 => OpCodes.Add, + 0x59 => OpCodes.Sub, + 0x5a => OpCodes.Mul, + 0x5b => OpCodes.Div, + 0x5c => OpCodes.Div_Un, + 0x5d => OpCodes.Rem, + 0x5e => OpCodes.Rem_Un, + 0x5f => OpCodes.And, + 0x60 => OpCodes.Or, + 0x61 => OpCodes.Xor, + 0x62 => OpCodes.Shl, + 0x63 => OpCodes.Shr, + 0x64 => OpCodes.Shr_Un, + 0x65 => OpCodes.Neg, + 0x66 => OpCodes.Not, + 0x67 => OpCodes.Conv_I1, + 0x68 => OpCodes.Conv_I2, + 0x69 => OpCodes.Conv_I4, + 0x6a => OpCodes.Conv_I8, + 0x6b => OpCodes.Conv_R4, + 0x6c => OpCodes.Conv_R8, + 0x6d => OpCodes.Conv_U4, + 0x6e => OpCodes.Conv_U8, + 0x6f => OpCodes.Callvirt, + 0x70 => OpCodes.Cpobj, + 0x71 => OpCodes.Ldobj, + 0x72 => OpCodes.Ldstr, + 0x73 => OpCodes.Newobj, + 0x74 => OpCodes.Castclass, + 0x75 => OpCodes.Isinst, + 0x76 => OpCodes.Conv_R_Un, + 0x79 => OpCodes.Unbox, + 0x7a => OpCodes.Throw, + 0x7b => OpCodes.Ldfld, + 0x7c => OpCodes.Ldflda, + 0x7d => OpCodes.Stfld, + 0x7e => OpCodes.Ldsfld, + 0x7f => OpCodes.Ldsflda, + 0x80 => OpCodes.Stsfld, + 0x81 => OpCodes.Stobj, + 0x82 => OpCodes.Conv_Ovf_I1_Un, + 0x83 => OpCodes.Conv_Ovf_I2_Un, + 0x84 => OpCodes.Conv_Ovf_I4_Un, + 0x85 => OpCodes.Conv_Ovf_I8_Un, + 0x86 => OpCodes.Conv_Ovf_U1_Un, + 0x87 => OpCodes.Conv_Ovf_U2_Un, + 0x88 => OpCodes.Conv_Ovf_U4_Un, + 0x89 => OpCodes.Conv_Ovf_U8_Un, + 0x8a => OpCodes.Conv_Ovf_I_Un, + 0x8b => OpCodes.Conv_Ovf_U_Un, + 0x8c => OpCodes.Box, + 0x8d => OpCodes.Newarr, + 0x8e => OpCodes.Ldlen, + 0x8f => OpCodes.Ldelema, + 0x90 => OpCodes.Ldelem_I1, + 0x91 => OpCodes.Ldelem_U1, + 0x92 => OpCodes.Ldelem_I2, + 0x93 => OpCodes.Ldelem_U2, + 0x94 => OpCodes.Ldelem_I4, + 0x95 => OpCodes.Ldelem_U4, + 0x96 => OpCodes.Ldelem_I8, + 0x97 => OpCodes.Ldelem_I, + 0x98 => OpCodes.Ldelem_R4, + 0x99 => OpCodes.Ldelem_R8, + 0x9a => OpCodes.Ldelem_Ref, + 0x9b => OpCodes.Stelem_I, + 0x9c => OpCodes.Stelem_I1, + 0x9d => OpCodes.Stelem_I2, + 0x9e => OpCodes.Stelem_I4, + 0x9f => OpCodes.Stelem_I8, + 0xa0 => OpCodes.Stelem_R4, + 0xa1 => OpCodes.Stelem_R8, + 0xa2 => OpCodes.Stelem_Ref, + 0xa3 => OpCodes.Ldelem, + 0xa4 => OpCodes.Stelem, + 0xa5 => OpCodes.Unbox_Any, + 0xb3 => OpCodes.Conv_Ovf_I1, + 0xb4 => OpCodes.Conv_Ovf_U1, + 0xb5 => OpCodes.Conv_Ovf_I2, + 0xb6 => OpCodes.Conv_Ovf_U2, + 0xb7 => OpCodes.Conv_Ovf_I4, + 0xb8 => OpCodes.Conv_Ovf_U4, + 0xb9 => OpCodes.Conv_Ovf_I8, + 0xba => OpCodes.Conv_Ovf_U8, + 0xc2 => OpCodes.Refanyval, + 0xc3 => OpCodes.Ckfinite, + 0xc6 => OpCodes.Mkrefany, + 0xd0 => OpCodes.Ldtoken, + 0xd1 => OpCodes.Conv_U2, + 0xd2 => OpCodes.Conv_U1, + 0xd3 => OpCodes.Conv_I, + 0xd4 => OpCodes.Conv_Ovf_I, + 0xd5 => OpCodes.Conv_Ovf_U, + 0xd6 => OpCodes.Add_Ovf, + 0xd7 => OpCodes.Add_Ovf_Un, + 0xd8 => OpCodes.Mul_Ovf, + 0xd9 => OpCodes.Mul_Ovf_Un, + 0xda => OpCodes.Sub_Ovf, + 0xdb => OpCodes.Sub_Ovf_Un, + 0xdc => OpCodes.Endfinally, + 0xdd => OpCodes.Leave, + 0xde => OpCodes.Leave_S, + 0xdf => OpCodes.Stind_I, + 0xe0 => OpCodes.Conv_U, + 0xf8 => OpCodes.Prefix7, + 0xf9 => OpCodes.Prefix6, + 0xfa => OpCodes.Prefix5, + 0xfb => OpCodes.Prefix4, + 0xfc => OpCodes.Prefix3, + 0xfd => OpCodes.Prefix2, + 0xfe => OpCodes.Prefix1, + 0xff => OpCodes.Prefixref, + 0xfe00 => OpCodes.Arglist, + 0xfe01 => OpCodes.Ceq, + 0xfe02 => OpCodes.Cgt, + 0xfe03 => OpCodes.Cgt_Un, + 0xfe04 => OpCodes.Clt, + 0xfe05 => OpCodes.Clt_Un, + 0xfe06 => OpCodes.Ldftn, + 0xfe07 => OpCodes.Ldvirtftn, + 0xfe09 => OpCodes.Ldarg, + 0xfe0a => OpCodes.Ldarga, + 0xfe0b => OpCodes.Starg, + 0xfe0c => OpCodes.Ldloc, + 0xfe0d => OpCodes.Ldloca, + 0xfe0e => OpCodes.Stloc, + 0xfe0f => OpCodes.Localloc, + 0xfe11 => OpCodes.Endfilter, + 0xfe15 => OpCodes.Initobj, + 0xfe17 => OpCodes.Cpblk, + 0xfe18 => OpCodes.Initblk, + 0xfe1a => OpCodes.Rethrow, + 0xfe1c => OpCodes.Sizeof, + 0xfe1d => OpCodes.Refanytype, + _ => throw new NotImplementedException(), + }; + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionLabel.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionLabel.cs new file mode 100644 index 000000000..bad25b195 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionLabel.cs @@ -0,0 +1,28 @@ +using IKVM.CoreLib.Symbols.Emit; +using IKVM.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + class IkvmReflectionLabel : ILabel + { + + readonly Label _label; + + /// + /// Initializes a new instance. + /// + /// + public IkvmReflectionLabel(Label label) + { + _label = label; + } + + /// + /// Gets the underlying . + /// + public Label UnderlyingLabel => _label; + + } + +} \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionLocalBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionLocalBuilder.cs new file mode 100644 index 000000000..edd6541b4 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionLocalBuilder.cs @@ -0,0 +1,55 @@ +using System; + +using IKVM.CoreLib.Symbols.Emit; +using IKVM.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + class IkvmReflectionLocalBuilder : ILocalBuilder + { + + readonly IkvmReflectionSymbolContext _context; + readonly LocalBuilder _builder; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + public IkvmReflectionLocalBuilder(IkvmReflectionSymbolContext context, LocalBuilder builder) + { + _context = context ?? throw new ArgumentNullException(nameof(context)); + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + } + + /// + /// Gets the underlying . + /// + public LocalBuilder UnderlyingLocalBuilder => _builder; + + /// + public bool IsPinned => _builder.IsPinned; + + /// + public int LocalIndex => _builder.LocalIndex; + + /// + public ITypeSymbol LocalType => _context.GetOrCreateTypeSymbol(_builder.LocalType); + + /// + public void SetLocalSymInfo(string name) + { + _builder.SetLocalSymInfo(name); + } + + /// + public void SetLocalSymInfo(string name, int startOffset, int endOffset) + { + _builder.SetLocalSymInfo(name, startOffset, endOffset); + } + + } + +} \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMemberSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMemberSymbolBuilder.cs index 1b643dfda..58ac56a0f 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMemberSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMemberSymbolBuilder.cs @@ -13,8 +13,8 @@ namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit abstract class IkvmReflectionMemberSymbolBuilder : IkvmReflectionSymbolBuilder, IIkvmReflectionMemberSymbolBuilder { - readonly IIkvmReflectionModuleSymbol _resolvingModule; - readonly IIkvmReflectionTypeSymbol? _resolvingType; + readonly IIkvmReflectionModuleSymbolBuilder _resolvingModule; + readonly IIkvmReflectionTypeSymbolBuilder? _resolvingType; /// /// Initializes a new instance. @@ -22,14 +22,14 @@ abstract class IkvmReflectionMemberSymbolBuilder : IkvmReflectionSymbolBuilder, /// /// /// - public IkvmReflectionMemberSymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol resolvingModule, IIkvmReflectionTypeSymbol? resolvingType) : + public IkvmReflectionMemberSymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbolBuilder resolvingModule, IIkvmReflectionTypeSymbolBuilder? resolvingType) : base(context) { _resolvingModule = resolvingModule ?? throw new ArgumentNullException(nameof(resolvingModule)); _resolvingType = resolvingType; } - #region IMemberSymbol + #region IIkvmReflectionMemberSymbol /// public abstract MemberInfo UnderlyingMember { get; } @@ -38,49 +38,128 @@ public IkvmReflectionMemberSymbolBuilder(IkvmReflectionSymbolContext context, II public IIkvmReflectionModuleSymbol ResolvingModule => _resolvingModule; /// - public IIkvmReflectionTypeSymbol? ResolvingType => ResolvingType; + public IIkvmReflectionModuleSymbolBuilder ResolvingModuleBuilder => _resolvingModule; /// - public virtual IModuleSymbol Module => ResolveModuleSymbol(UnderlyingMember.Module)!; + public IIkvmReflectionTypeSymbol? ResolvingType => _resolvingType; - /// - public virtual ITypeSymbol? DeclaringType => ResolveTypeSymbol(UnderlyingMember.DeclaringType)!; + #endregion + + #region IIkvmReflectionSymbolBuilder /// - public virtual System.Reflection.MemberTypes MemberType => (System.Reflection.MemberTypes)UnderlyingMember.MemberType; + [return: NotNullIfNotNull("type")] + public override IIkvmReflectionTypeSymbolBuilder ResolveTypeSymbol(TypeBuilder type) + { + if (type is null) + throw new ArgumentNullException(nameof(type)); + + if (UnderlyingMember == type) + return (IIkvmReflectionTypeSymbolBuilder)this; + + if (_resolvingType != null && type == _resolvingType.UnderlyingType) + return (IIkvmReflectionTypeSymbolBuilder)_resolvingType; + + if (type.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateTypeSymbol(type); + + return base.ResolveTypeSymbol(type); + } /// - public virtual int MetadataToken => UnderlyingMember.MetadataToken; + [return: NotNullIfNotNull(nameof(ctor))] + public override IIkvmReflectionConstructorSymbolBuilder ResolveConstructorSymbol(ConstructorBuilder ctor) + { + if (ctor is null) + throw new ArgumentNullException(nameof(ctor)); + + if (UnderlyingMember == ctor) + return (IIkvmReflectionConstructorSymbolBuilder)this; + + if (ctor.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateConstructorSymbol(ctor); + + return base.ResolveConstructorSymbol(ctor); + } /// - public virtual string Name => UnderlyingMember.Name; + [return: NotNullIfNotNull(nameof(method))] + public override IIkvmReflectionMethodSymbolBuilder ResolveMethodSymbol(MethodBuilder method) + { + if (method is null) + throw new ArgumentNullException(nameof(method)); + + if (UnderlyingMember == method) + return (IIkvmReflectionMethodSymbolBuilder)this; + + if (method.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateMethodSymbol(method); + + return base.ResolveMethodSymbol(method); + } /// - public CustomAttribute[] GetCustomAttributes(bool inherit = false) + [return: NotNullIfNotNull(nameof(field))] + public override IIkvmReflectionFieldSymbolBuilder ResolveFieldSymbol(FieldBuilder field) { - return ResolveCustomAttributes(UnderlyingMember.__GetCustomAttributes(null, inherit)); + if (field is null) + throw new ArgumentNullException(nameof(field)); + + if (UnderlyingMember == field) + return (IIkvmReflectionFieldSymbolBuilder)this; + + if (field.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateFieldSymbol(field); + + return base.ResolveFieldSymbol(field); } /// - public virtual CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) + [return: NotNullIfNotNull(nameof(property))] + public override IIkvmReflectionPropertySymbolBuilder ResolvePropertySymbol(PropertyBuilder property) { - return ResolveCustomAttributes(UnderlyingMember.__GetCustomAttributes(attributeType.Unpack(), inherit)); + if (property is null) + throw new ArgumentNullException(nameof(property)); + + if (UnderlyingMember == property) + return (IIkvmReflectionPropertySymbolBuilder)this; + + if (property.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreatePropertySymbol(property); + + return base.ResolvePropertySymbol(property); } /// - public virtual CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) + [return: NotNullIfNotNull(nameof(@event))] + public override IIkvmReflectionEventSymbolBuilder ResolveEventSymbol(EventBuilder @event) { - return ResolveCustomAttribute(UnderlyingMember.__GetCustomAttributes(attributeType.Unpack(), inherit).FirstOrDefault()); + if (@event is null) + throw new ArgumentNullException(nameof(@event)); + + if (@event.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateEventSymbol(@event); + + return base.ResolveEventSymbol(@event); } /// - public virtual bool IsDefined(ITypeSymbol attributeType, bool inherit = false) + [return: NotNullIfNotNull(nameof(parameter))] + public override IIkvmReflectionParameterSymbolBuilder ResolveParameterSymbol(ParameterBuilder parameter) { - return UnderlyingMember.IsDefined(attributeType.Unpack(), inherit); + if (parameter is null) + throw new ArgumentNullException(nameof(parameter)); + + if (parameter.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateParameterSymbol(parameter); + + return base.ResolveParameterSymbol(parameter); } #endregion + #region IIkvmReflectionSymbol + /// [return: NotNullIfNotNull(nameof(type))] public override IIkvmReflectionTypeSymbol? ResolveTypeSymbol(Type? type) @@ -100,25 +179,6 @@ public virtual bool IsDefined(ITypeSymbol attributeType, bool inherit = false) return base.ResolveTypeSymbol(type); } - /// - [return: NotNullIfNotNull("type")] - public override IIkvmReflectionTypeSymbolBuilder ResolveTypeSymbol(TypeBuilder type) - { - if (type is null) - throw new ArgumentNullException(nameof(type)); - - if (UnderlyingMember == type) - return (IIkvmReflectionTypeSymbolBuilder)this; - - if (_resolvingType != null && type == _resolvingType.UnderlyingType) - return (IIkvmReflectionTypeSymbolBuilder)_resolvingType; - - if (type.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateTypeSymbol(type); - - return base.ResolveTypeSymbol(type); - } - /// [return: NotNullIfNotNull(nameof(ctor))] public override IIkvmReflectionConstructorSymbol? ResolveConstructorSymbol(ConstructorInfo? ctor) @@ -135,22 +195,6 @@ public override IIkvmReflectionTypeSymbolBuilder ResolveTypeSymbol(TypeBuilder t return base.ResolveConstructorSymbol(ctor); } - /// - [return: NotNullIfNotNull(nameof(ctor))] - public override IIkvmReflectionConstructorSymbolBuilder ResolveConstructorSymbol(ConstructorBuilder ctor) - { - if (ctor is null) - throw new ArgumentNullException(nameof(ctor)); - - if (UnderlyingMember == ctor) - return (IIkvmReflectionConstructorSymbolBuilder)this; - - if (ctor.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateConstructorSymbol(ctor); - - return base.ResolveConstructorSymbol(ctor); - } - /// [return: NotNullIfNotNull(nameof(method))] public override IIkvmReflectionMethodSymbol? ResolveMethodSymbol(MethodInfo? method) @@ -167,22 +211,6 @@ public override IIkvmReflectionConstructorSymbolBuilder ResolveConstructorSymbol return base.ResolveMethodSymbol(method); } - /// - [return: NotNullIfNotNull(nameof(method))] - public override IIkvmReflectionMethodSymbolBuilder ResolveMethodSymbol(MethodBuilder method) - { - if (method is null) - throw new ArgumentNullException(nameof(method)); - - if (UnderlyingMember == method) - return (IIkvmReflectionMethodSymbolBuilder)this; - - if (method.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateMethodSymbol(method); - - return base.ResolveMethodSymbol(method); - } - /// [return: NotNullIfNotNull(nameof(field))] public override IIkvmReflectionFieldSymbol? ResolveFieldSymbol(FieldInfo? field) @@ -199,22 +227,6 @@ public override IIkvmReflectionMethodSymbolBuilder ResolveMethodSymbol(MethodBui return base.ResolveFieldSymbol(field); } - /// - [return: NotNullIfNotNull(nameof(field))] - public override IIkvmReflectionFieldSymbolBuilder ResolveFieldSymbol(FieldBuilder field) - { - if (field is null) - throw new ArgumentNullException(nameof(field)); - - if (UnderlyingMember == field) - return (IIkvmReflectionFieldSymbolBuilder)this; - - if (field.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateFieldSymbol(field); - - return base.ResolveFieldSymbol(field); - } - /// [return: NotNullIfNotNull(nameof(property))] public override IIkvmReflectionPropertySymbol? ResolvePropertySymbol(PropertyInfo? property) @@ -231,22 +243,6 @@ public override IIkvmReflectionFieldSymbolBuilder ResolveFieldSymbol(FieldBuilde return base.ResolvePropertySymbol(property); } - /// - [return: NotNullIfNotNull(nameof(property))] - public override IIkvmReflectionPropertySymbolBuilder ResolvePropertySymbol(PropertyBuilder property) - { - if (property is null) - throw new ArgumentNullException(nameof(property)); - - if (UnderlyingMember == property) - return (IIkvmReflectionPropertySymbolBuilder)this; - - if (property.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreatePropertySymbol(property); - - return base.ResolvePropertySymbol(property); - } - /// [return: NotNullIfNotNull(nameof(@event))] public override IIkvmReflectionEventSymbol? ResolveEventSymbol(EventInfo? @event) @@ -263,19 +259,6 @@ public override IIkvmReflectionPropertySymbolBuilder ResolvePropertySymbol(Prope return base.ResolveEventSymbol(@event); } - /// - [return: NotNullIfNotNull(nameof(@event))] - public override IIkvmReflectionEventSymbolBuilder ResolveEventSymbol(EventBuilder @event) - { - if (@event is null) - throw new ArgumentNullException(nameof(@event)); - - if (@event.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateEventSymbol(@event); - - return base.ResolveEventSymbol(@event); - } - /// [return: NotNullIfNotNull(nameof(parameter))] public override IIkvmReflectionParameterSymbol? ResolveParameterSymbol(ParameterInfo? parameter) @@ -289,19 +272,51 @@ public override IIkvmReflectionEventSymbolBuilder ResolveEventSymbol(EventBuilde return base.ResolveParameterSymbol(parameter); } + #endregion + + #region IMemberSymbol + /// - [return: NotNullIfNotNull(nameof(parameter))] - public override IIkvmReflectionParameterSymbolBuilder ResolveParameterSymbol(ParameterBuilder parameter) + public virtual IModuleSymbol Module => ResolveModuleSymbol(UnderlyingMember.Module)!; + + /// + public virtual ITypeSymbol? DeclaringType => ResolveTypeSymbol(UnderlyingMember.DeclaringType)!; + + /// + public virtual System.Reflection.MemberTypes MemberType => (System.Reflection.MemberTypes)UnderlyingMember.MemberType; + + /// + public virtual int MetadataToken => UnderlyingMember.MetadataToken; + + /// + public virtual string Name => UnderlyingMember.Name; + + /// + public CustomAttribute[] GetCustomAttributes(bool inherit = false) { - if (parameter is null) - throw new ArgumentNullException(nameof(parameter)); + return ResolveCustomAttributes(UnderlyingMember.__GetCustomAttributes(null, inherit)); + } - if (parameter.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateParameterSymbol(parameter); + /// + public virtual CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) + { + return ResolveCustomAttributes(UnderlyingMember.__GetCustomAttributes(attributeType.Unpack(), inherit)); + } - return base.ResolveParameterSymbol(parameter); + /// + public virtual CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) + { + return ResolveCustomAttribute(UnderlyingMember.__GetCustomAttributes(attributeType.Unpack(), inherit).FirstOrDefault()); } + /// + public virtual bool IsDefined(ITypeSymbol attributeType, bool inherit = false) + { + return UnderlyingMember.IsDefined(attributeType.Unpack(), inherit); + } + + #endregion + /// public virtual void OnComplete() { diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodBaseSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodBaseSymbolBuilder.cs index b6a2326dd..573c98183 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodBaseSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodBaseSymbolBuilder.cs @@ -1,4 +1,5 @@ using IKVM.Reflection; +using IKVM.Reflection.Emit; namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit { @@ -6,16 +7,18 @@ namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit abstract class IkvmReflectionMethodBaseSymbolBuilder : IkvmReflectionMemberSymbolBuilder, IIkvmReflectionMethodBaseSymbolBuilder { + IkvmReflectionParameterTable _parameterTable; + /// /// Initializes a new instance. /// /// /// /// - public IkvmReflectionMethodBaseSymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol resolvingModule, IIkvmReflectionTypeSymbol? resolvingType) : + public IkvmReflectionMethodBaseSymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbolBuilder resolvingModule, IIkvmReflectionTypeSymbolBuilder? resolvingType) : base(context, resolvingModule, resolvingType) { - + _parameterTable = new IkvmReflectionParameterTable(context, resolvingModule, this); } /// @@ -24,6 +27,26 @@ public IkvmReflectionMethodBaseSymbolBuilder(IkvmReflectionSymbolContext context /// public override MemberInfo UnderlyingMember => UnderlyingMethodBase; + #region IIkvmReflectionMethodBaseSymbolBuilder + + /// + public IIkvmReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter) + { + return _parameterTable.GetOrCreateParameterSymbol(parameter); + } + + #endregion + + #region IIkvmReflectionMethodBaseSymbol + + /// + public IIkvmReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) + { + return _parameterTable.GetOrCreateParameterSymbol(parameter); + } + + #endregion + #region IMethodBaseSymbol /// diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodSymbolBuilder.cs index db3c96967..23b82a638 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodSymbolBuilder.cs @@ -4,6 +4,8 @@ using IKVM.Reflection; using IKVM.Reflection.Emit; +using Type = IKVM.Reflection.Type; + namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit { @@ -13,6 +15,10 @@ class IkvmReflectionMethodSymbolBuilder : IkvmReflectionMethodBaseSymbolBuilder, MethodBuilder? _builder; MethodInfo _method; + IkvmReflectionGenericTypeParameterTable _genericTypeParameterTable; + + IkvmReflectionILGenerator? _il; + /// /// Initializes a new instance. /// @@ -21,11 +27,12 @@ class IkvmReflectionMethodSymbolBuilder : IkvmReflectionMethodBaseSymbolBuilder, /// /// /// - public IkvmReflectionMethodSymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol resolvingModule, IIkvmReflectionTypeSymbol? resolvingType, MethodBuilder builder) : + public IkvmReflectionMethodSymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbolBuilder resolvingModule, IIkvmReflectionTypeSymbolBuilder? resolvingType, MethodBuilder builder) : base(context, resolvingModule, resolvingType) { _builder = builder ?? throw new ArgumentNullException(nameof(builder)); _method = _builder; + _genericTypeParameterTable = new IkvmReflectionGenericTypeParameterTable(context, resolvingModule, this); } /// @@ -37,6 +44,34 @@ public IkvmReflectionMethodSymbolBuilder(IkvmReflectionSymbolContext context, II /// public MethodBuilder UnderlyingMethodBuilder => _builder ?? throw new InvalidOperationException(); + #region IIkvmReflectionMethodSymbolBuilder + + /// + public IIkvmReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeParameterSymbol(GenericTypeParameterBuilder genericTypeParameter) + { + return _genericTypeParameterTable.GetOrCreateGenericTypeParameterSymbol(genericTypeParameter); + } + + #endregion + + #region IIkvmReflectionMethodSymbol + + /// + public IIkvmReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type genericTypeParameter) + { + return _genericTypeParameterTable.GetOrCreateGenericTypeParameterSymbol(genericTypeParameter); + } + + #endregion + + #region IIkvmReflectionMethodBaseSymbol + + #endregion + + #region IIkvmReflectionMethodBaseSymbolBuilder + + #endregion + #region IMethodSymbolBuilder /// @@ -68,7 +103,7 @@ public IGenericTypeParameterSymbolBuilder[] DefineGenericParameters(params strin var l = UnderlyingMethodBuilder.DefineGenericParameters(names); var a = new IGenericTypeParameterSymbolBuilder[l.Length]; for (int i = 0; i < l.Length; i++) - a[i] = new IkvmReflectionGenericTypeParameterSymbolBuilder(Context, ResolvingModule, ResolvingType, this, l[i]); + a[i] = ResolveGenericTypeParameterSymbol(l[i]); return a; } @@ -79,14 +114,16 @@ public IParameterSymbolBuilder DefineParameter(int position, System.Reflection.P return ResolveParameterSymbol(UnderlyingMethodBuilder.DefineParameter(position, (ParameterAttributes)attributes, strParamName)); } + /// public IILGenerator GetILGenerator() { - throw new NotImplementedException(); + return _il ??= new IkvmReflectionILGenerator(Context, UnderlyingMethodBuilder.GetILGenerator()); } - public IILGenerator GetILGenerator(int size) + /// + public IILGenerator GetILGenerator(int streamSize) { - throw new NotImplementedException(); + return _il ??= new IkvmReflectionILGenerator(Context, UnderlyingMethodBuilder.GetILGenerator(streamSize)); } /// @@ -144,7 +181,6 @@ public override void OnComplete() _builder = null; base.OnComplete(); } - } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionModuleSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionModuleSymbolBuilder.cs index deb3feca4..b5e84e7f5 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionModuleSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionModuleSymbolBuilder.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics.SymbolStore; using System.Linq; using IKVM.CoreLib.Symbols.Emit; @@ -14,36 +15,184 @@ class IkvmReflectionModuleSymbolBuilder : IkvmReflectionSymbolBuilder, IIkvmRefl { readonly IIkvmReflectionAssemblySymbol _resolvingAssembly; + readonly ModuleBuilder _module; + + IkvmReflectionTypeTable _typeTable; + IkvmReflectionMethodTable _methodTable; + IkvmReflectionFieldTable _fieldTable; - readonly ModuleBuilder _builder; - IkvmReflectionModuleMetadata _metadata; /// /// Initializes a new instance. /// /// /// - /// + /// /// - public IkvmReflectionModuleSymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionAssemblySymbol resolvingAssembly, ModuleBuilder builder) : + public IkvmReflectionModuleSymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionAssemblySymbol resolvingAssembly, ModuleBuilder module) : base(context) { _resolvingAssembly = resolvingAssembly ?? throw new ArgumentNullException(nameof(resolvingAssembly)); - _builder = builder ?? throw new ArgumentNullException(nameof(builder)); - _metadata = new IkvmReflectionModuleMetadata(this); + _module = module ?? throw new ArgumentNullException(nameof(module)); + + _typeTable = new IkvmReflectionTypeTable(context, this, null); + _methodTable = new IkvmReflectionMethodTable(context, this, null); + _fieldTable = new IkvmReflectionFieldTable(context, this, null); } /// public Module UnderlyingModule => UnderlyingModuleBuilder; /// - public ModuleBuilder UnderlyingModuleBuilder => _builder; + public ModuleBuilder UnderlyingModuleBuilder => _module; /// public IIkvmReflectionAssemblySymbol ResolvingAssembly => _resolvingAssembly; + #region IIkvmReflectionModuleSymbol + + /// + public IIkvmReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) + { + if (type.IsTypeDefinition()) + return _typeTable.GetOrCreateTypeSymbol(type); + else if (type.IsGenericType) + return ResolveTypeSymbol(type.GetGenericTypeDefinition()).GetOrCreateGenericTypeSymbol(type.GetGenericArguments()); + else if (type.IsSZArray) + return ResolveTypeSymbol(type.GetElementType()).GetOrCreateSZArrayTypeSymbol(); + else if (type.IsArray) + return ResolveTypeSymbol(type.GetElementType()).GetOrCreateArrayTypeSymbol(type.GetArrayRank()); + else if (type.IsPointer) + return ResolveTypeSymbol(type.GetElementType()).GetOrCreatePointerTypeSymbol(); + else if (type.IsByRef) + return ResolveTypeSymbol(type.GetElementType()).GetOrCreateByRefTypeSymbol(); + else + throw new InvalidOperationException(); + } + + /// + public IIkvmReflectionTypeSymbolBuilder GetOrCreateTypeSymbol(TypeBuilder type) + { + return (IIkvmReflectionTypeSymbolBuilder)_typeTable.GetOrCreateTypeSymbol((Type)type); + } + + /// + public IIkvmReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method) + { + if (method.DeclaringType is { } dt) + return ResolveTypeSymbol(dt).GetOrCreateMethodBaseSymbol(method); + else + return _methodTable.GetOrCreateMethodBaseSymbol(method); + } + + /// + public IIkvmReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) + { + return ResolveTypeSymbol(ctor.DeclaringType).GetOrCreateConstructorSymbol(ctor); + } + + /// + public IIkvmReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor) + { + return ResolveTypeSymbol((TypeBuilder)ctor.DeclaringType).GetOrCreateConstructorSymbol(ctor); + } + + /// + public IIkvmReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) + { + if (method.DeclaringType is { } dt) + return ResolveTypeSymbol(dt).GetOrCreateMethodSymbol(method); + else + return _methodTable.GetOrCreateMethodSymbol(method); + } + + /// + public IIkvmReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method) + { + if (method.DeclaringType is { } dt) + return ResolveTypeSymbol((TypeBuilder)dt).GetOrCreateMethodSymbol(method); + else + return _methodTable.GetOrCreateMethodSymbol(method); + } + + /// + public IIkvmReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) + { + if (field.DeclaringType is { } dt) + return ResolveTypeSymbol(dt).GetOrCreateFieldSymbol(field); + else + return _fieldTable.GetOrCreateFieldSymbol(field); + } + + /// + public IIkvmReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field) + { + if (field.DeclaringType is { } dt) + return ResolveTypeSymbol((TypeBuilder)dt).GetOrCreateFieldSymbol(field); + else + return _fieldTable.GetOrCreateFieldSymbol(field); + } + + /// + public IIkvmReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) + { + return ResolveTypeSymbol(property.DeclaringType).GetOrCreatePropertySymbol(property); + } + + /// + public IIkvmReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property) + { + return ResolveTypeSymbol((TypeBuilder)property.DeclaringType).GetOrCreatePropertySymbol(property); + } + + /// + public IIkvmReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) + { + return ResolveTypeSymbol(@event.DeclaringType).GetOrCreateEventSymbol(@event); + } + + /// + public IIkvmReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event) + { + return ResolveTypeSymbol((TypeBuilder)@event.DeclaringType).GetOrCreateEventSymbol(@event); + } + + /// + public IIkvmReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) + { + return ResolveMemberSymbol(parameter.Member) switch + { + IIkvmReflectionMethodBaseSymbol method => method.GetOrCreateParameterSymbol(parameter), + IIkvmReflectionPropertySymbol property => property.GetOrCreateParameterSymbol(parameter), + _ => throw new InvalidOperationException(), + }; + } + + /// + public IIkvmReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter) + { + return ResolveMethodSymbol((MethodBuilder)parameter.Method).GetOrCreateParameterSymbol(parameter); + } + + /// + public IIkvmReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeParameterSymbol(GenericTypeParameterBuilder genericParameterType) + { + if (genericParameterType.DeclaringMethod is MethodBuilder dm) + return ResolveMethodSymbol(dm).GetOrCreateGenericTypeParameterSymbol(genericParameterType); + else + return ResolveTypeSymbol((TypeBuilder)genericParameterType.DeclaringType).GetOrCreateGenericTypeParameterSymbol(genericParameterType); + } + + #endregion + #region IModuleSymbolBuilder + /// + public ISymbolDocumentWriter? DefineDocument(string url, Guid language, Guid languageVendor, Guid documentType) + { + return UnderlyingModuleBuilder.DefineDocument(url, language, languageVendor, documentType); + } + /// public ITypeSymbolBuilder DefineType(string name) { @@ -121,7 +270,7 @@ public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) public string ScopeName => UnderlyingModule.ScopeName; /// - public override bool IsComplete => _builder == null; + public override bool IsComplete => _module == null; /// public IFieldSymbol? GetField(string name) @@ -293,90 +442,6 @@ public bool IsDefined(ITypeSymbol attributeType, bool inherit = false) #endregion - /// - public IIkvmReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) - { - return _metadata.GetOrCreateTypeSymbol(type); - } - - /// - public IIkvmReflectionTypeSymbolBuilder GetOrCreateTypeSymbol(TypeBuilder type) - { - return _metadata.GetOrCreateTypeSymbol(type); - } - - /// - public IIkvmReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) - { - return _metadata.GetOrCreateConstructorSymbol(ctor); - } - - /// - public IIkvmReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor) - { - return _metadata.GetOrCreateConstructorSymbol(ctor); - } - - /// - public IIkvmReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) - { - return _metadata.GetOrCreateMethodSymbol(method); - } - - /// - public IIkvmReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method) - { - return _metadata.GetOrCreateMethodSymbol(method); - } - - /// - public IIkvmReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) - { - return _metadata.GetOrCreateFieldSymbol(field); - } - - /// - public IIkvmReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field) - { - return _metadata.GetOrCreateFieldSymbol(field); - } - - /// - public IIkvmReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) - { - return _metadata.GetOrCreatePropertySymbol(property); - } - - /// - public IIkvmReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property) - { - return _metadata.GetOrCreatePropertySymbol(property); - } - - /// - public IIkvmReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) - { - return _metadata.GetOrCreateEventSymbol(@event); - } - - /// - public IIkvmReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event) - { - return _metadata.GetOrCreateEventSymbol(@event); - } - - /// - public IIkvmReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) - { - return _metadata.GetOrCreateParameterSymbol(parameter); - } - - /// - public IIkvmReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter) - { - return _metadata.GetOrCreateParameterSymbol(parameter); - } - } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterSymbolBuilder.cs index fa7506bd8..e49827c7d 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterSymbolBuilder.cs @@ -12,7 +12,7 @@ class IkvmReflectionParameterSymbolBuilder : IkvmReflectionSymbolBuilder, IIkvmR { readonly IIkvmReflectionModuleSymbol _resolvingModule; - readonly IIkvmReflectionMethodBaseSymbol _resolvingMethod; + readonly IIkvmReflectionMemberSymbol _resolvingMethod; ParameterBuilder? _builder; ParameterInfo _parameter; @@ -26,7 +26,7 @@ class IkvmReflectionParameterSymbolBuilder : IkvmReflectionSymbolBuilder, IIkvmR /// /// /// - public IkvmReflectionParameterSymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol resolvingModule, IIkvmReflectionMethodBaseSymbol resolvingMethod, ParameterBuilder builder) : + public IkvmReflectionParameterSymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol resolvingModule, IIkvmReflectionMemberSymbol resolvingMethod, ParameterBuilder builder) : base(context) { _resolvingModule = resolvingModule ?? throw new ArgumentNullException(nameof(resolvingModule)); @@ -39,7 +39,7 @@ public IkvmReflectionParameterSymbolBuilder(IkvmReflectionSymbolContext context, public IIkvmReflectionModuleSymbol ResolvingModule => _resolvingMethod.ResolvingModule; /// - public IIkvmReflectionMethodBaseSymbol ResolvingMethod => _resolvingMethod; + public IIkvmReflectionMemberSymbol ResolvingMember => _resolvingMethod; /// public ParameterInfo UnderlyingParameter => _parameter; @@ -154,8 +154,12 @@ public ITypeSymbol[] GetRequiredCustomModifiers() /// public void OnComplete() { - var p = ResolvingMethod.UnderlyingMethodBase.GetParameters(); - _parameter = p[Position]; + if (ResolvingMember is IIkvmReflectionMethodBaseSymbolBuilder b) + _parameter = b.UnderlyingMethodBase.GetParameters()[Position]; + + if (ResolvingMember is IIkvmReflectionPropertySymbolBuilder p) + _parameter = p.UnderlyingPropertyBuilder.GetIndexParameters()[Position]; + _builder = null; } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionPropertySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionPropertySymbolBuilder.cs index 8ec05eeff..731828bd7 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionPropertySymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionPropertySymbolBuilder.cs @@ -13,6 +13,8 @@ class IkvmReflectionPropertySymbolBuilder : IkvmReflectionMemberSymbolBuilder, I PropertyBuilder? _builder; PropertyInfo _property; + IkvmReflectionParameterTable _parameterTable; + /// /// Initializes a new instance. /// @@ -21,11 +23,12 @@ class IkvmReflectionPropertySymbolBuilder : IkvmReflectionMemberSymbolBuilder, I /// /// /// - public IkvmReflectionPropertySymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol resolvingModule, IIkvmReflectionTypeSymbol resolvingType, PropertyBuilder builder) : + public IkvmReflectionPropertySymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbolBuilder resolvingModule, IIkvmReflectionTypeSymbolBuilder resolvingType, PropertyBuilder builder) : base(context, resolvingModule, resolvingType) { _builder = builder ?? throw new ArgumentNullException(nameof(builder)); _property = _builder; + _parameterTable = new IkvmReflectionParameterTable(context, resolvingModule, this); } /// @@ -37,6 +40,15 @@ public IkvmReflectionPropertySymbolBuilder(IkvmReflectionSymbolContext context, /// public override MemberInfo UnderlyingMember => UnderlyingProperty; + #region IIkvmPropertySymbol + + public IIkvmReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) + { + return _parameterTable.GetOrCreateParameterSymbol(parameter); + } + + #endregion + #region IPropertySymbol /// @@ -169,7 +181,7 @@ public ITypeSymbol[] GetRequiredCustomModifiers() return ResolveTypeSymbols(UnderlyingProperty.GetRequiredCustomModifiers()); } -#endregion + #endregion /// public override void OnComplete() diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionSymbolBuilder.cs index f00d73726..ffa16919e 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionSymbolBuilder.cs @@ -1,4 +1,7 @@ -using IKVM.CoreLib.Symbols.Emit; +using System.Diagnostics.CodeAnalysis; + +using IKVM.CoreLib.Symbols.Emit; +using IKVM.Reflection.Emit; namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit { @@ -19,6 +22,13 @@ protected IkvmReflectionSymbolBuilder(IkvmReflectionSymbolContext context) : } + /// + [return: NotNullIfNotNull("genericTypeParameter")] + public IIkvmReflectionGenericTypeParameterSymbolBuilder? ResolveGenericTypeParameterSymbol(GenericTypeParameterBuilder genericTypeParameter) + { + return Context.GetOrCreateGenericTypeParameterSymbol(genericTypeParameter); + } + } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionTypeSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionTypeSymbolBuilder.cs index 323f309d1..d4183cb18 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionTypeSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionTypeSymbolBuilder.cs @@ -15,7 +15,13 @@ class IkvmReflectionTypeSymbolBuilder : IkvmReflectionMemberSymbolBuilder, IIkvm TypeBuilder? _builder; Type _type; - IkvmReflectionTypeImpl _impl; + + IkvmReflectionMethodTable _methodTable; + IkvmReflectionFieldTable _fieldTable; + IkvmReflectionPropertyTable _propertyTable; + IkvmReflectionEventTable _eventTable; + IkvmReflectionGenericTypeParameterTable _genericTypeParameterTable; + IkvmReflectionTypeSpecTable _specTable; /// /// Initializes a new instance. @@ -23,12 +29,16 @@ class IkvmReflectionTypeSymbolBuilder : IkvmReflectionMemberSymbolBuilder, IIkvm /// /// /// - public IkvmReflectionTypeSymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol resolvingModule, TypeBuilder builder) : + public IkvmReflectionTypeSymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbolBuilder resolvingModule, TypeBuilder builder) : base(context, resolvingModule, null) { _builder = builder ?? throw new ArgumentNullException(nameof(builder)); _type = _builder; - _impl = new IkvmReflectionTypeImpl(this); + _methodTable = new IkvmReflectionMethodTable(context, resolvingModule, this); + _fieldTable = new IkvmReflectionFieldTable(context, resolvingModule, this); + _propertyTable = new IkvmReflectionPropertyTable(context, resolvingModule, this); + _eventTable = new IkvmReflectionEventTable(context, resolvingModule, this); + _genericTypeParameterTable = new IkvmReflectionGenericTypeParameterTable(context, resolvingModule, this); } /// @@ -40,6 +50,128 @@ public IkvmReflectionTypeSymbolBuilder(IkvmReflectionSymbolContext context, IIkv /// public TypeBuilder UnderlyingTypeBuilder => _builder ?? throw new InvalidOperationException(); + #region IkvmReflectionTypeSymbol + + /// + public IIkvmReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) + { + return _methodTable.GetOrCreateConstructorSymbol(ctor); + } + + /// + public IIkvmReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method) + { + return _methodTable.GetOrCreateMethodBaseSymbol(method); + } + + /// + public IIkvmReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) + { + return _methodTable.GetOrCreateMethodSymbol(method); + } + + /// + public IIkvmReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) + { + return _fieldTable.GetOrCreateFieldSymbol(field); + } + + /// + public IIkvmReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) + { + return _propertyTable.GetOrCreatePropertySymbol(property); + } + + /// + public IIkvmReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) + { + return _eventTable.GetOrCreateEventSymbol(@event); + } + + /// + public IIkvmReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type genericTypeParameter) + { + return _genericTypeParameterTable.GetOrCreateGenericTypeParameterSymbol(genericTypeParameter); + } + + /// + public IIkvmReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeParameterSymbol(GenericTypeParameterBuilder genericTypeParameter) + { + return _genericTypeParameterTable.GetOrCreateGenericTypeParameterSymbol(genericTypeParameter); + } + + /// + public IIkvmReflectionTypeSymbol GetOrCreateSZArrayTypeSymbol() + { + return _specTable.GetOrCreateSZArrayTypeSymbol(); + } + + /// + public IIkvmReflectionTypeSymbol GetOrCreateArrayTypeSymbol(int rank) + { + return _specTable.GetOrCreateArrayTypeSymbol(rank); + } + + /// + public IIkvmReflectionTypeSymbol GetOrCreatePointerTypeSymbol() + { + return _specTable.GetOrCreatePointerTypeSymbol(); + } + + /// + public IIkvmReflectionTypeSymbol GetOrCreateByRefTypeSymbol() + { + return _specTable.GetOrCreateByRefTypeSymbol(); + } + + /// + public IIkvmReflectionTypeSymbol GetOrCreateGenericTypeSymbol(Type[] genericTypeDefinition) + { + return _specTable.GetOrCreateGenericTypeSymbol(genericTypeDefinition); + } + + #endregion + + #region IIkvmReflectionTypeSymbolBuilder + + /// + public IIkvmReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor) + { + return _methodTable.GetOrCreateConstructorSymbol(ctor); + } + + /// + public IIkvmReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method) + { + return _methodTable.GetOrCreateMethodSymbol(method); + } + + /// + public IIkvmReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field) + { + return _fieldTable.GetOrCreateFieldSymbol(field); + } + + /// + public IIkvmReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property) + { + return _propertyTable.GetOrCreatePropertySymbol(property); + } + + /// + public IIkvmReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event) + { + return _eventTable.GetOrCreateEventSymbol(@event); + } + + /// + public IIkvmReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter) + { + return ResolveMethodSymbol((MethodBuilder)parameter.Method).GetOrCreateParameterSymbol(parameter); + } + + #endregion + #region ITypeSymbolBuilder /// @@ -54,7 +186,7 @@ public IGenericTypeParameterSymbolBuilder[] DefineGenericParameters(params strin var l = UnderlyingTypeBuilder.DefineGenericParameters(names); var a = new IGenericTypeParameterSymbolBuilder[l.Length]; for (int i = 0; i < l.Length; i++) - a[i] = new IkvmReflectionGenericTypeParameterSymbolBuilder(Context, ResolvingModule, this, null, l[i]); + a[i] = ResolveGenericTypeParameterSymbol(l[i]); return a; } @@ -132,7 +264,7 @@ public IMethodSymbolBuilder DefineMethod(string name, System.Reflection.MethodAt } /// - public void DefineMethodOverride(IMethodSymbolBuilder methodInfoBody, IMethodSymbol methodInfoDeclaration) + public void DefineMethodOverride(IMethodSymbol methodInfoBody, IMethodSymbol methodInfoDeclaration) { UnderlyingTypeBuilder.DefineMethodOverride(methodInfoBody.Unpack(), methodInfoDeclaration.Unpack()); } @@ -243,506 +375,513 @@ public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) #region ITypeSymbol /// - public System.Reflection.TypeAttributes Attributes => _impl.Attributes; + public IAssemblySymbol Assembly => ResolveAssemblySymbol(UnderlyingType.Assembly); /// - public IAssemblySymbol Assembly => _impl.Assembly; + public string? AssemblyQualifiedName => UnderlyingType.AssemblyQualifiedName; /// - public IMethodBaseSymbol? DeclaringMethod => _impl.DeclaringMethod; + public System.Reflection.TypeAttributes Attributes => (System.Reflection.TypeAttributes)UnderlyingType.Attributes; /// - public string? AssemblyQualifiedName => _impl.AssemblyQualifiedName; + public ITypeSymbol? BaseType => ResolveTypeSymbol(UnderlyingType.BaseType); /// - public string? FullName => _impl.FullName; + public bool ContainsGenericParameters => UnderlyingType.ContainsGenericParameters; /// - public string? Namespace => _impl.Namespace; + public IMethodBaseSymbol? DeclaringMethod => ResolveMethodBaseSymbol(UnderlyingType.DeclaringMethod); /// - public TypeCode TypeCode => _impl.TypeCode; + public string? FullName => UnderlyingType.FullName; /// - public ITypeSymbol? BaseType => _impl.BaseType; + public string? Namespace => UnderlyingType.Namespace; /// - public bool ContainsGenericParameters => _impl.ContainsGenericParameters; + public System.Reflection.GenericParameterAttributes GenericParameterAttributes => (System.Reflection.GenericParameterAttributes)UnderlyingType.GenericParameterAttributes; /// - public System.Reflection.GenericParameterAttributes GenericParameterAttributes => _impl.GenericParameterAttributes; + public int GenericParameterPosition => UnderlyingType.GenericParameterPosition; /// - public int GenericParameterPosition => _impl.GenericParameterPosition; + public ITypeSymbol[] GenericTypeArguments => ResolveTypeSymbols(UnderlyingType.GenericTypeArguments); /// - public ITypeSymbol[] GenericTypeArguments => _impl.GenericTypeArguments; + public bool HasElementType => UnderlyingType.HasElementType; /// - public bool IsConstructedGenericType => _impl.IsConstructedGenericType; + public TypeCode TypeCode => Type.GetTypeCode(UnderlyingType); /// - public bool IsGenericType => _impl.IsGenericType; + public bool IsAbstract => UnderlyingType.IsAbstract; /// - public bool IsGenericTypeDefinition => _impl.IsGenericTypeDefinition; + public bool IsSZArray => UnderlyingType.IsSZArray; /// - public bool IsGenericParameter => _impl.IsGenericParameter; + public bool IsArray => UnderlyingType.IsArray; /// - public bool IsAutoLayout => _impl.IsAutoLayout; + public bool IsAutoLayout => UnderlyingType.IsAutoLayout; /// - public bool IsExplicitLayout => _impl.IsExplicitLayout; + public bool IsExplicitLayout => UnderlyingType.IsExplicitLayout; /// - public bool IsLayoutSequential => _impl.IsLayoutSequential; + public bool IsByRef => UnderlyingType.IsByRef; /// - public bool HasElementType => _impl.HasElementType; + public bool IsClass => UnderlyingType.IsClass; /// - public bool IsClass => _impl.IsClass; + public bool IsEnum => UnderlyingType.IsEnum; /// - public bool IsValueType => _impl.IsValueType; + public bool IsInterface => UnderlyingType.IsInterface; /// - public bool IsInterface => _impl.IsInterface; + public bool IsConstructedGenericType => UnderlyingType.IsConstructedGenericType; /// - public bool IsPrimitive => _impl.IsPrimitive; + public bool IsGenericParameter => UnderlyingType.IsGenericParameter; /// - public bool IsSZArray => _impl.IsSZArray; + public bool IsGenericType => UnderlyingType.IsGenericType; /// - public bool IsArray => _impl.IsArray; + public bool IsGenericTypeDefinition => UnderlyingType.IsGenericTypeDefinition; /// - public bool IsEnum => _impl.IsEnum; + public bool IsLayoutSequential => UnderlyingType.IsLayoutSequential; /// - public bool IsPointer => _impl.IsPointer; + public bool IsNested => UnderlyingType.IsNested; /// - public bool IsFunctionPointer => _impl.IsFunctionPointer; + public bool IsNestedAssembly => UnderlyingType.IsNestedAssembly; /// - public bool IsUnmanagedFunctionPointer => _impl.IsUnmanagedFunctionPointer; + public bool IsNestedFamANDAssem => UnderlyingType.IsNestedFamANDAssem; /// - public bool IsByRef => _impl.IsByRef; + public bool IsNestedFamORAssem => UnderlyingType.IsNestedFamORAssem; /// - public bool IsAbstract => _impl.IsAbstract; + public bool IsNestedFamily => UnderlyingType.IsNestedFamily; /// - public bool IsSealed => _impl.IsSealed; + public bool IsNestedPrivate => UnderlyingType.IsNestedPrivate; /// - public bool IsVisible => _impl.IsVisible; + public bool IsNestedPublic => UnderlyingType.IsNestedPublic; /// - public bool IsPublic => _impl.IsPublic; + public bool IsNotPublic => UnderlyingType.IsNotPublic; /// - public bool IsNotPublic => _impl.IsNotPublic; + public bool IsPointer => UnderlyingType.IsPointer; /// - public bool IsNested => _impl.IsNested; + public bool IsFunctionPointer => UnderlyingType.IsFunctionPointer; /// - public bool IsNestedAssembly => _impl.IsNestedAssembly; + public bool IsUnmanagedFunctionPointer => UnderlyingType.IsUnmanagedFunctionPointer; /// - public bool IsNestedFamANDAssem => _impl.IsNestedFamANDAssem; + public bool IsPrimitive => UnderlyingType.IsPrimitive; /// - public bool IsNestedFamily => _impl.IsNestedFamily; + public bool IsPublic => UnderlyingType.IsPublic; /// - public bool IsNestedFamORAssem => _impl.IsNestedFamORAssem; + public bool IsSealed => UnderlyingType.IsSealed; /// - public bool IsNestedPrivate => _impl.IsNestedPrivate; + public bool IsSerializable => UnderlyingType.IsSerializable; /// - public bool IsNestedPublic => _impl.IsNestedPublic; + public bool IsValueType => UnderlyingType.IsValueType; /// - public bool IsSerializable => _impl.IsSerializable; + public bool IsVisible => UnderlyingType.IsVisible; /// - public bool IsSignatureType => _impl.IsSignatureType; + public bool IsSignatureType => throw new NotImplementedException(); /// - public bool IsSpecialName => _impl.IsSpecialName; + public bool IsSpecialName => UnderlyingType.IsSpecialName; /// - public IConstructorSymbol? TypeInitializer => _impl.TypeInitializer; + public IConstructorSymbol? TypeInitializer => ResolveConstructorSymbol(UnderlyingType.TypeInitializer); /// - public override bool IsComplete => _builder == null; + public int GetArrayRank() + { + return UnderlyingType.GetArrayRank(); + } /// - public int GetArrayRank() + public IConstructorSymbol? GetConstructor(System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) { - return _impl.GetArrayRank(); + return ResolveConstructorSymbol(UnderlyingType.GetConstructor((BindingFlags)bindingAttr, binder: null, types.Unpack(), modifiers: null)); } /// - public IMemberSymbol[] GetDefaultMembers() + public IConstructorSymbol? GetConstructor(ITypeSymbol[] types) { - return _impl.GetDefaultMembers(); + return ResolveConstructorSymbol(UnderlyingType.GetConstructor(types.Unpack())); } /// - public ITypeSymbol? GetElementType() + public IConstructorSymbol[] GetConstructors() { - return _impl.GetElementType(); + return ResolveConstructorSymbols(UnderlyingType.GetConstructors()); } /// - public string? GetEnumName(object value) + public IConstructorSymbol[] GetConstructors(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetEnumName(value); + return ResolveConstructorSymbols(UnderlyingType.GetConstructors((BindingFlags)bindingAttr)); } /// - public string[] GetEnumNames() + public IMemberSymbol[] GetDefaultMembers() { - return _impl.GetEnumNames(); + return ResolveMemberSymbols(UnderlyingType.GetDefaultMembers()); } /// - public ITypeSymbol GetEnumUnderlyingType() + public ITypeSymbol? GetElementType() { - return _impl.GetEnumUnderlyingType(); + return ResolveTypeSymbol(UnderlyingType.GetElementType()); } /// - public ITypeSymbol[] GetGenericArguments() + public string? GetEnumName(object value) { - return _impl.GetGenericArguments(); + return UnderlyingType.GetEnumName(value); } /// - public ITypeSymbol[] GetGenericParameterConstraints() + public string[] GetEnumNames() { - return _impl.GetGenericParameterConstraints(); + return UnderlyingType.GetEnumNames(); } /// - public ITypeSymbol GetGenericTypeDefinition() + public ITypeSymbol GetEnumUnderlyingType() { - return _impl.GetGenericTypeDefinition(); + return ResolveTypeSymbol(UnderlyingType.GetEnumUnderlyingType()); } /// - public ITypeSymbol? GetInterface(string name) + public Array GetEnumValues() { - return _impl.GetInterface(name); + return UnderlyingType.GetEnumValues(); } /// - public ITypeSymbol? GetInterface(string name, bool ignoreCase) + public IEventSymbol? GetEvent(string name) { - return _impl.GetInterface(name, ignoreCase); + return ResolveEventSymbol(UnderlyingType.GetEvent(name)); } /// - public ITypeSymbol[] GetInterfaces(bool inherit = true) + public IEventSymbol? GetEvent(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetInterfaces(inherit); + return ResolveEventSymbol(UnderlyingType.GetEvent(name, (BindingFlags)bindingAttr)); } /// - public InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) + public IEventSymbol[] GetEvents() { - return _impl.GetInterfaceMap(interfaceType); + return ResolveEventSymbols(UnderlyingType.GetEvents()); } /// - public IMemberSymbol[] GetMember(string name) + public IEventSymbol[] GetEvents(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMember(name); + return ResolveEventSymbols(UnderlyingType.GetEvents((BindingFlags)bindingAttr)); } /// - public IMemberSymbol[] GetMember(string name, System.Reflection.BindingFlags bindingAttr) + public IFieldSymbol? GetField(string name) { - return _impl.GetMember(name, bindingAttr); + return ResolveFieldSymbol(UnderlyingType.GetField(name)); } /// - public IMemberSymbol[] GetMember(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) + public IFieldSymbol? GetField(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMember(name, type, bindingAttr); + return ResolveFieldSymbol(UnderlyingType.GetField(name, (BindingFlags)bindingAttr)); } /// - public IMemberSymbol[] GetMembers() + public IFieldSymbol[] GetFields() { - return _impl.GetMembers(); + return ResolveFieldSymbols(UnderlyingType.GetFields()); } /// - public IMemberSymbol[] GetMembers(System.Reflection.BindingFlags bindingAttr) + public IFieldSymbol[] GetFields(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMembers(bindingAttr); + return ResolveFieldSymbols(UnderlyingType.GetFields((BindingFlags)bindingAttr)); } - public IConstructorSymbol? GetConstructor(ITypeSymbol[] types) + /// + public ITypeSymbol[] GetGenericArguments() { - return _impl.GetConstructor(types); + return ResolveTypeSymbols(UnderlyingType.GetGenericArguments()); } /// - public IConstructorSymbol? GetConstructor(System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) + public ITypeSymbol[] GetGenericParameterConstraints() { - return _impl.GetConstructor(bindingAttr, types); + return ResolveTypeSymbols(UnderlyingType.GetGenericParameterConstraints()); } /// - public IConstructorSymbol[] GetConstructors() + public ITypeSymbol GetGenericTypeDefinition() { - return _impl.GetConstructors(); + return ResolveTypeSymbol(UnderlyingType.GetGenericTypeDefinition()); } /// - public IConstructorSymbol[] GetConstructors(System.Reflection.BindingFlags bindingAttr) + public ITypeSymbol? GetInterface(string name) { - return _impl.GetConstructors(bindingAttr); + return ResolveTypeSymbol(UnderlyingType.GetInterface(name)); } /// - public IFieldSymbol? GetField(string name) + public ITypeSymbol? GetInterface(string name, bool ignoreCase) { - return _impl.GetField(name); + return ResolveTypeSymbol(UnderlyingType.GetInterface(name, ignoreCase)); } /// - public IFieldSymbol? GetField(string name, System.Reflection.BindingFlags bindingAttr) + public InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) { - return _impl.GetField(name, bindingAttr); + throw new NotImplementedException(); } /// - public IFieldSymbol[] GetFields() + public ITypeSymbol[] GetInterfaces(bool inherit = true) { - return _impl.GetFields(); + if (inherit) + return ResolveTypeSymbols(UnderlyingType.GetInterfaces()); + else + throw new NotImplementedException(); } /// - public IFieldSymbol[] GetFields(System.Reflection.BindingFlags bindingAttr) + public IMemberSymbol[] GetMember(string name) { - return _impl.GetFields(bindingAttr); + return ResolveMemberSymbols(UnderlyingType.GetMember(name)); } /// - public IMethodSymbol? GetMethod(string name) + public IMemberSymbol[] GetMember(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMethod(name); + return ResolveMemberSymbols(UnderlyingType.GetMember(name, (BindingFlags)bindingAttr)); } /// - public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) + public IMemberSymbol[] GetMember(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMethod(name, types); + return ResolveMemberSymbols(UnderlyingType.GetMember(name, (MemberTypes)type, (BindingFlags)bindingAttr)); } /// - public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr) + public IMemberSymbol[] GetMembers(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMethod(name, bindingAttr); + return ResolveMemberSymbols(UnderlyingType.GetMembers((BindingFlags)bindingAttr)); } /// - public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) + public IMemberSymbol[] GetMembers() { - return _impl.GetMethod(name, bindingAttr, types); + return ResolveMemberSymbols(UnderlyingType.GetMembers()); } /// - public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMethod(name, bindingAttr, callConvention, types, modifiers); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr)); } /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) { - return _impl.GetMethod(name, genericParameterCount, bindingAttr, callConvention, types, modifiers); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, types.Unpack())); } /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) { - return _impl.GetMethod(name, genericParameterCount, bindingAttr, types, modifiers); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), null)); } /// - public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name) { - return _impl.GetMethod(name, bindingAttr, types, modifiers); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name)); } /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return _impl.GetMethod(name, genericParameterCount, types, modifiers); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, (CallingConventions)callConvention, types.Unpack(), modifiers?.Unpack())); } /// - public IMethodSymbol[] GetMethods() + public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return _impl.GetMethods(); + throw new NotImplementedException(); } /// - public IMethodSymbol[] GetMethods(System.Reflection.BindingFlags bindingAttr) + public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return _impl.GetMethods(bindingAttr); + throw new NotImplementedException(); } /// - public IPropertySymbol? GetProperty(string name) + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return _impl.GetProperty(name); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), modifiers?.Unpack())); } /// - public IPropertySymbol? GetProperty(string name, System.Reflection.BindingFlags bindingAttr) + public IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return _impl.GetProperty(name, bindingAttr); + throw new NotImplementedException(); } /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol[] types) + public IMethodSymbol[] GetMethods(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetProperty(name, types); + return ResolveMethodSymbols(UnderlyingType.GetMethods((BindingFlags)bindingAttr)); } /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types) + public IMethodSymbol[] GetMethods() { - return _impl.GetProperty(name, returnType, types); + return ResolveMethodSymbols(UnderlyingType.GetMethods()); } /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) + public ITypeSymbol? GetNestedType(string name) { - return _impl.GetProperty(name, returnType); + return ResolveTypeSymbol(UnderlyingType.GetNestedType(name)); } /// - public IPropertySymbol[] GetProperties() + public ITypeSymbol? GetNestedType(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetProperties(); + return ResolveTypeSymbol(UnderlyingType.GetNestedType(name, (BindingFlags)bindingAttr)); } /// - public IPropertySymbol[] GetProperties(System.Reflection.BindingFlags bindingAttr) + public ITypeSymbol[] GetNestedTypes() { - return _impl.GetProperties(bindingAttr); + return ResolveTypeSymbols(UnderlyingType.GetNestedTypes()); } /// - public IEventSymbol? GetEvent(string name) + public ITypeSymbol[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetEvent(name); + return ResolveTypeSymbols(UnderlyingType.GetNestedTypes((BindingFlags)bindingAttr)); } /// - public IEventSymbol? GetEvent(string name, System.Reflection.BindingFlags bindingAttr) + public IPropertySymbol[] GetProperties() { - return _impl.GetEvent(name, bindingAttr); + return ResolvePropertySymbols(UnderlyingType.GetProperties()); } /// - public IEventSymbol[] GetEvents() + public IPropertySymbol[] GetProperties(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetEvents(); + return ResolvePropertySymbols(UnderlyingType.GetProperties((BindingFlags)bindingAttr)); } /// - public IEventSymbol[] GetEvents(System.Reflection.BindingFlags bindingAttr) + public IPropertySymbol? GetProperty(string name, ITypeSymbol[] types) { - return _impl.GetEvents(bindingAttr); + return ResolvePropertySymbol(UnderlyingType.GetProperty(name, types.Unpack())); } /// - public ITypeSymbol? GetNestedType(string name) + public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types) { - return _impl.GetNestedType(name); + return ResolvePropertySymbol(UnderlyingType.GetProperty(name, returnType?.Unpack(), types.Unpack())); } /// - public ITypeSymbol? GetNestedType(string name, System.Reflection.BindingFlags bindingAttr) + public IPropertySymbol? GetProperty(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetNestedType(name, bindingAttr); + return ResolvePropertySymbol(UnderlyingType.GetProperty(name, (BindingFlags)bindingAttr)); } /// - public ITypeSymbol[] GetNestedTypes() + public IPropertySymbol? GetProperty(string name) { - return _impl.GetNestedTypes(); + return ResolvePropertySymbol(UnderlyingType.GetProperty(name)); } /// - public ITypeSymbol[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr) + public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) { - return _impl.GetNestedTypes(); + return ResolvePropertySymbol(UnderlyingType.GetProperty(name, returnType?.Unpack())); } /// public bool IsAssignableFrom(ITypeSymbol? c) { - return _impl.IsAssignableFrom(c); + return UnderlyingType.IsAssignableFrom(c?.Unpack()); } /// - public bool IsSubclassOf(ITypeSymbol c) + public bool IsEnumDefined(object value) { - return _impl.IsSubclassOf(c); + return UnderlyingType.IsEnumDefined(value); } /// - public bool IsEnumDefined(object value) + public bool IsSubclassOf(ITypeSymbol c) { - return _impl.IsEnumDefined(value); + return UnderlyingType.IsSubclassOf(c.Unpack()); } /// public ITypeSymbol MakeArrayType() { - return _impl.MakeArrayType(); + return ResolveTypeSymbol(_type.MakeArrayType()); } /// public ITypeSymbol MakeArrayType(int rank) { - return _impl.MakeArrayType(rank); + return ResolveTypeSymbol(_type.MakeArrayType(rank)); } /// public ITypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments) { - return _impl.MakeGenericType(typeArguments); + return ResolveTypeSymbol(_type.MakeGenericType(typeArguments.Unpack())); } /// public ITypeSymbol MakePointerType() { - return _impl.MakePointerType(); + return ResolveTypeSymbol(_type.MakePointerType()); } /// public ITypeSymbol MakeByRefType() { - return _impl.MakeByRefType(); + return ResolveTypeSymbol(_type.MakeByRefType()); } #endregion @@ -796,7 +935,6 @@ public override void OnComplete() base.OnComplete(); } - } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionAssemblySymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionAssemblySymbol.cs index 73df3a3be..3d783ca7d 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionAssemblySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionAssemblySymbol.cs @@ -20,13 +20,6 @@ interface IIkvmReflectionAssemblySymbol : IIkvmReflectionSymbol, IAssemblySymbol /// IIkvmReflectionModuleSymbol GetOrCreateModuleSymbol(Module module); - /// - /// Gets or creates a for the specified . - /// - /// - /// - IIkvmReflectionModuleSymbolBuilder GetOrCreateModuleSymbol(ModuleBuilder module); - } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionMethodBaseSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionMethodBaseSymbol.cs index 483704f37..86d071cfe 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionMethodBaseSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionMethodBaseSymbol.cs @@ -11,6 +11,13 @@ interface IIkvmReflectionMethodBaseSymbol : IIkvmReflectionMemberSymbol, IMethod /// MethodBase UnderlyingMethodBase { get; } + /// + /// Gets or creates a for the given . + /// + /// + /// + public IIkvmReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter); + } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionMethodSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionMethodSymbol.cs index c91b72a6b..8e64ccaa4 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionMethodSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionMethodSymbol.cs @@ -11,6 +11,13 @@ interface IIkvmReflectionMethodSymbol : IIkvmReflectionMethodBaseSymbol, IMethod /// MethodInfo UnderlyingMethod { get; } + /// + /// Gets or creates a for the given generic type parameter. + /// + /// + /// + IIkvmReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type genericTypeParameter); + } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionModuleSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionModuleSymbol.cs index 9c5129c3d..41a1252f2 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionModuleSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionModuleSymbol.cs @@ -28,11 +28,11 @@ interface IIkvmReflectionModuleSymbol : IIkvmReflectionSymbol, IModuleSymbol IIkvmReflectionTypeSymbol GetOrCreateTypeSymbol(Type type); /// - /// Gets or creates a for the specified . + /// Gets or creates a for the specified . /// - /// + /// /// - IIkvmReflectionTypeSymbolBuilder GetOrCreateTypeSymbol(TypeBuilder type); + IIkvmReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method); /// /// Gets or creates a for the specified . @@ -41,13 +41,6 @@ interface IIkvmReflectionModuleSymbol : IIkvmReflectionSymbol, IModuleSymbol /// IIkvmReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor); - /// - /// Gets or creates a for the specified . - /// - /// - /// - IIkvmReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor); - /// /// Gets or creates a for the specified . /// @@ -55,13 +48,6 @@ interface IIkvmReflectionModuleSymbol : IIkvmReflectionSymbol, IModuleSymbol /// IIkvmReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method); - /// - /// Gets or creates a for the specified . - /// - /// - /// - IIkvmReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method); - /// /// Gets or creates a for the specified . /// @@ -69,13 +55,6 @@ interface IIkvmReflectionModuleSymbol : IIkvmReflectionSymbol, IModuleSymbol /// IIkvmReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field); - /// - /// Gets or creates a for the specified . - /// - /// - /// - IIkvmReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field); - /// /// Gets or creates a for the specified . /// @@ -83,13 +62,6 @@ interface IIkvmReflectionModuleSymbol : IIkvmReflectionSymbol, IModuleSymbol /// IIkvmReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property); - /// - /// Gets or creates a for the specified . - /// - /// - /// - IIkvmReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property); - /// /// Gets or creates a for the specified . /// @@ -97,13 +69,6 @@ interface IIkvmReflectionModuleSymbol : IIkvmReflectionSymbol, IModuleSymbol /// IIkvmReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event); - /// - /// Gets or creates a for the specified . - /// - /// - /// - IIkvmReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event); - /// /// Gets or creates a for the specified . /// @@ -111,13 +76,6 @@ interface IIkvmReflectionModuleSymbol : IIkvmReflectionSymbol, IModuleSymbol /// IIkvmReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter); - /// - /// Gets or creates a for the specified . - /// - /// - /// - IIkvmReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter); - } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionParameterSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionParameterSymbol.cs index ddc2d8eb7..284719fb7 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionParameterSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionParameterSymbol.cs @@ -12,9 +12,9 @@ interface IIkvmReflectionParameterSymbol : IIkvmReflectionSymbol, IParameterSymb IIkvmReflectionModuleSymbol ResolvingModule { get; } /// - /// Gets the method that resolved the parameter. + /// Gets the member that resolved the parameter. /// - IIkvmReflectionMethodBaseSymbol ResolvingMethod { get; } + IIkvmReflectionMemberSymbol ResolvingMember { get; } /// /// Gets the underlying . diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionPropertySymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionPropertySymbol.cs index 57e05528e..f7c52268c 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionPropertySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionPropertySymbol.cs @@ -11,6 +11,13 @@ interface IIkvmReflectionPropertySymbol : IIkvmReflectionMemberSymbol, IProperty /// PropertyInfo UnderlyingProperty { get; } + /// + /// Gets or creates a for the given . + /// + /// + /// + public IIkvmReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter); + } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionSymbol.cs index 891dc53f8..af3369996 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionSymbol.cs @@ -27,14 +27,6 @@ interface IIkvmReflectionSymbol : ISymbol [return: NotNullIfNotNull(nameof(assembly))] IIkvmReflectionAssemblySymbol? ResolveAssemblySymbol(Assembly? assembly); - /// - /// Resolves the symbol for the specified assembly builder. - /// - /// - /// - [return: NotNullIfNotNull(nameof(assembly))] - IIkvmReflectionAssemblySymbolBuilder ResolveAssemblySymbol(AssemblyBuilder assembly); - /// /// Resolves the symbols for the specified assemblies. /// @@ -51,14 +43,6 @@ interface IIkvmReflectionSymbol : ISymbol [return: NotNullIfNotNull(nameof(module))] IIkvmReflectionModuleSymbol? ResolveModuleSymbol(Module? module); - /// - /// Resolves the symbol for the specified module. - /// - /// - /// - [return: NotNullIfNotNull(nameof(module))] - IIkvmReflectionModuleSymbolBuilder ResolveModuleSymbol(ModuleBuilder module); - /// /// Resolves the symbols for the specified modules. /// @@ -98,14 +82,6 @@ interface IIkvmReflectionSymbol : ISymbol [return: NotNullIfNotNull(nameof(type))] IIkvmReflectionTypeSymbol? ResolveTypeSymbol(Type? type); - /// - /// Resolves the symbol for the specified type. - /// - /// - /// - [return: NotNullIfNotNull(nameof(type))] - IIkvmReflectionTypeSymbolBuilder ResolveTypeSymbol(TypeBuilder type); - /// /// Resolves the symbols for the specified types. /// @@ -137,14 +113,6 @@ interface IIkvmReflectionSymbol : ISymbol [return: NotNullIfNotNull(nameof(ctor))] IIkvmReflectionConstructorSymbol? ResolveConstructorSymbol(ConstructorInfo? ctor); - /// - /// Resolves the symbol for the specified constructor. - /// - /// - /// - [return: NotNullIfNotNull(nameof(ctor))] - IIkvmReflectionConstructorSymbolBuilder ResolveConstructorSymbol(ConstructorBuilder ctor); - /// /// Resolves the symbols for the specified constructors. /// @@ -161,14 +129,6 @@ interface IIkvmReflectionSymbol : ISymbol [return: NotNullIfNotNull(nameof(method))] IIkvmReflectionMethodSymbol? ResolveMethodSymbol(MethodInfo? method); - /// - /// Resolves the symbol for the specified method. - /// - /// - /// - [return: NotNullIfNotNull(nameof(method))] - IIkvmReflectionMethodSymbolBuilder ResolveMethodSymbol(MethodBuilder method); - /// /// Resolves the symbols for the specified methods. /// @@ -185,14 +145,6 @@ interface IIkvmReflectionSymbol : ISymbol [return: NotNullIfNotNull(nameof(field))] IIkvmReflectionFieldSymbol? ResolveFieldSymbol(FieldInfo? field); - /// - /// Resolves the symbol for the specified field. - /// - /// - /// - [return: NotNullIfNotNull(nameof(field))] - IIkvmReflectionFieldSymbolBuilder ResolveFieldSymbol(FieldBuilder field); - /// /// Resolves the symbols for the specified fields. /// @@ -209,14 +161,6 @@ interface IIkvmReflectionSymbol : ISymbol [return: NotNullIfNotNull(nameof(property))] IIkvmReflectionPropertySymbol? ResolvePropertySymbol(PropertyInfo? property); - /// - /// Resolves the symbol for the specified property. - /// - /// - /// - [return: NotNullIfNotNull(nameof(property))] - IIkvmReflectionPropertySymbolBuilder ResolvePropertySymbol(PropertyBuilder property); - /// /// Resolves the symbols for the specified properties. /// @@ -233,14 +177,6 @@ interface IIkvmReflectionSymbol : ISymbol [return: NotNullIfNotNull(nameof(@event))] IIkvmReflectionEventSymbol? ResolveEventSymbol(EventInfo? @event); - /// - /// Resolves the symbol for the specified event. - /// - /// - /// - [return: NotNullIfNotNull(nameof(@event))] - IIkvmReflectionEventSymbolBuilder ResolveEventSymbol(EventBuilder @event); - /// /// Resolves the symbols for the specified events. /// @@ -257,14 +193,6 @@ interface IIkvmReflectionSymbol : ISymbol [return: NotNullIfNotNull(nameof(parameter))] IIkvmReflectionParameterSymbol? ResolveParameterSymbol(ParameterInfo? parameter); - /// - /// Resolves the symbol for the specified parameter. - /// - /// - /// - [return: NotNullIfNotNull(nameof(parameter))] - IIkvmReflectionParameterSymbolBuilder? ResolveParameterSymbol(ParameterBuilder parameter); - /// /// Resolves the symbols for the specified parameters. /// @@ -331,6 +259,13 @@ interface IIkvmReflectionSymbol : ISymbol /// CustomAttributeNamedArgument ResolveCustomAttributeNamedArgument(IKVM.Reflection.CustomAttributeNamedArgument arg); + /// + /// Transforms a into a symbol type. + /// + /// + /// + InterfaceMapping ResolveInterfaceMapping(IKVM.Reflection.InterfaceMapping arg); + } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionTypeSymbol.cs index fd6281149..b2dac0f00 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionTypeSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionTypeSymbol.cs @@ -1,4 +1,6 @@ -using Type = IKVM.Reflection.Type; +using IKVM.Reflection; + +using Type = IKVM.Reflection.Type; namespace IKVM.CoreLib.Symbols.IkvmReflection { @@ -11,6 +13,87 @@ interface IIkvmReflectionTypeSymbol : IIkvmReflectionMemberSymbol, ITypeSymbol /// Type UnderlyingType { get; } + /// + /// Gets or creates a for the given . + /// + /// + /// + IIkvmReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method); + + /// + /// Gets or creates a for the given . + /// + /// + /// + IIkvmReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor); + + /// + /// Gets or creates a for the given . + /// + /// + /// + IIkvmReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method); + + /// + /// Gets or creates a for the given . + /// + /// + /// + IIkvmReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field); + + /// + /// Gets or creates a for the given . + /// + /// + /// + IIkvmReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property); + + /// + /// Gets or creates a for the given . + /// + /// + /// + IIkvmReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event); + + /// + /// Gets or creates a for the given generic type parameter type. + /// + /// + /// + IIkvmReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type genericTypeParameter); + + /// + /// Gets or creates a for the given element type. + /// + /// + IIkvmReflectionTypeSymbol GetOrCreateSZArrayTypeSymbol(); + + /// + /// Gets or creates a for the given element type. + /// + /// + /// + IIkvmReflectionTypeSymbol GetOrCreateArrayTypeSymbol(int rank); + + /// + /// Gets or creates a for the given element type. + /// + /// + IIkvmReflectionTypeSymbol GetOrCreatePointerTypeSymbol(); + + /// + /// Gets or creates a for the given element type. + /// + /// + IIkvmReflectionTypeSymbol GetOrCreateByRefTypeSymbol(); + + /// + /// Gets or creates a for the given element type. + /// + /// + /// + IIkvmReflectionTypeSymbol GetOrCreateGenericTypeSymbol(Type[] genericTypeDefinition); + } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs index eb728f551..1b4b2ef00 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs @@ -2,9 +2,7 @@ using System.Collections.Generic; using System.Linq; -using IKVM.CoreLib.Symbols.IkvmReflection.Emit; using IKVM.Reflection; -using IKVM.Reflection.Emit; namespace IKVM.CoreLib.Symbols.IkvmReflection { @@ -13,7 +11,8 @@ class IkvmReflectionAssemblySymbol : IkvmReflectionSymbol, IIkvmReflectionAssemb { readonly Assembly _assembly; - IkvmReflectionAssemblyMetadata _impl; + + IkvmReflectionModuleTable _moduleTable; /// /// Initializes a new instance. @@ -24,7 +23,7 @@ public IkvmReflectionAssemblySymbol(IkvmReflectionSymbolContext context, Assembl base(context) { _assembly = assembly ?? throw new ArgumentNullException(nameof(assembly)); - _impl = new IkvmReflectionAssemblyMetadata(this); + _moduleTable = new IkvmReflectionModuleTable(context, this); } /// @@ -32,6 +31,16 @@ public IkvmReflectionAssemblySymbol(IkvmReflectionSymbolContext context, Assembl /// public Assembly UnderlyingAssembly => _assembly; + #region IIkvmAssemblySymbol + + /// + public IIkvmReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) + { + return _moduleTable.GetOrCreateModuleSymbol(module); + } + + #endregion + #region IAssemblySymbol /// @@ -82,19 +91,19 @@ public IModuleSymbol[] GetModules(bool getResourceModules) /// public System.Reflection.AssemblyName GetName() { - return _assembly.GetName().ToAssemblyName(); + return _assembly.GetName().Pack(); } /// public System.Reflection.AssemblyName GetName(bool copiedName) { - return _assembly.GetName().ToAssemblyName(); + return _assembly.GetName().Pack(); } /// public System.Reflection.AssemblyName[] GetReferencedAssemblies() { - return _assembly.GetReferencedAssemblies().ToAssemblyNames(); + return _assembly.GetReferencedAssemblies().Pack(); } /// @@ -147,16 +156,6 @@ public bool IsDefined(ITypeSymbol attributeType, bool inherit = false) #endregion - public IIkvmReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) - { - return _impl.GetOrCreateModuleSymbol(module); - } - - public IIkvmReflectionModuleSymbolBuilder GetOrCreateModuleSymbol(ModuleBuilder module) - { - return (IIkvmReflectionModuleSymbolBuilder)_impl.GetOrCreateModuleSymbol(module); - } - } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionEventTable.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionEventTable.cs new file mode 100644 index 000000000..c131d4927 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionEventTable.cs @@ -0,0 +1,94 @@ +using System; +using System.Reflection.Metadata.Ecma335; +using System.Threading; + +using IKVM.CoreLib.Collections; +using IKVM.CoreLib.Symbols.IkvmReflection.Emit; +using IKVM.CoreLib.Threading; +using IKVM.Reflection; +using IKVM.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + struct IkvmReflectionEventTable + { + + readonly IkvmReflectionSymbolContext _context; + readonly IIkvmReflectionModuleSymbol _module; + readonly IIkvmReflectionTypeSymbol _type; + + IndexRangeDictionary _table = new(); + ReaderWriterLockSlim? _lock; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + public IkvmReflectionEventTable(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol module, IIkvmReflectionTypeSymbol type) + { + _context = context ?? throw new ArgumentNullException(nameof(context)); + _module = module ?? throw new ArgumentNullException(nameof(module)); + _type = type ?? throw new ArgumentNullException(nameof(type)); + } + + /// + /// Gets or creates the cached for the type by event. + /// + /// + /// + public IIkvmReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) + { + if (@event is null) + throw new ArgumentNullException(nameof(@event)); + if (@event.Module.MetadataToken != _module.MetadataToken) + throw new ArgumentException(nameof(@event)); + + // create lock on demand + if (_lock == null) + Interlocked.CompareExchange(ref _lock, new ReaderWriterLockSlim(), null); + + using (_lock.CreateUpgradeableReadLock()) + { + var row = MetadataTokens.GetRowNumber(MetadataTokens.EventDefinitionHandle(@event.MetadataToken)); + if (_table[row] == null) + using (_lock.CreateWriteLock()) + return _table[row] ??= new IkvmReflectionEventSymbol(_context, _module, _type, @event); + else + return _table[row] ?? throw new InvalidOperationException(); + } + } + + /// + /// Gets or creates the cached for the type by event. + /// + /// + /// + public IIkvmReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event) + { + if (@event is null) + throw new ArgumentNullException(nameof(@event)); + if (@event.Module.MetadataToken != _module.MetadataToken) + throw new ArgumentException(nameof(@event)); + + // create lock on demand + if (_lock == null) + Interlocked.CompareExchange(ref _lock, new ReaderWriterLockSlim(), null); + + using (_lock.CreateUpgradeableReadLock()) + { + var row = MetadataTokens.GetRowNumber(MetadataTokens.EventDefinitionHandle(@event.GetEventToken().Token)); + if (_table[row] == null) + using (_lock.CreateWriteLock()) + return (IIkvmReflectionEventSymbolBuilder)(_table[row] ??= new IkvmReflectionEventSymbolBuilder(_context, (IIkvmReflectionModuleSymbolBuilder)_module, (IIkvmReflectionTypeSymbolBuilder)_type, @event)); + else + return (IIkvmReflectionEventSymbolBuilder?)_table[row] ?? throw new InvalidOperationException(); + } + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionFieldTable.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionFieldTable.cs new file mode 100644 index 000000000..9158d9d19 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionFieldTable.cs @@ -0,0 +1,80 @@ +using System; +using System.Reflection.Metadata.Ecma335; +using System.Threading; + +using IKVM.CoreLib.Collections; +using IKVM.CoreLib.Symbols.IkvmReflection.Emit; +using IKVM.CoreLib.Threading; +using IKVM.Reflection; +using IKVM.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + struct IkvmReflectionFieldTable + { + + readonly IkvmReflectionSymbolContext _context; + readonly IIkvmReflectionModuleSymbol _module; + readonly IIkvmReflectionTypeSymbol? _type; + + IndexRangeDictionary _table = new(); + ReaderWriterLockSlim? _lock; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + public IkvmReflectionFieldTable(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol module, IIkvmReflectionTypeSymbol? type) + { + _context = context ?? throw new ArgumentNullException(nameof(context)); + _module = module ?? throw new ArgumentNullException(nameof(module)); + _type = type; + } + + /// + /// Gets or creates the cached for the type by field. + /// + /// + /// + public IIkvmReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) + { + if (field is null) + throw new ArgumentNullException(nameof(field)); + if (field.Module.MetadataToken != _module.MetadataToken) + throw new ArgumentException(nameof(field)); + + // create lock on demand + if (_lock == null) + Interlocked.CompareExchange(ref _lock, new ReaderWriterLockSlim(), null); + + using (_lock.CreateUpgradeableReadLock()) + { + var row = MetadataTokens.GetRowNumber(MetadataTokens.FieldDefinitionHandle(field.MetadataToken)); + if (_table[row] == null) + using (_lock.CreateWriteLock()) + if (field is FieldBuilder builder) + return _table[row] ??= new IkvmReflectionFieldSymbolBuilder(_context, (IIkvmReflectionModuleSymbolBuilder)_module, (IIkvmReflectionTypeSymbolBuilder?)_type, builder); + else + return _table[row] ??= new IkvmReflectionFieldSymbol(_context, _module, _type, field); + else + return _table[row] ?? throw new InvalidOperationException(); + } + } + + /// + /// Gets or creates the cached for the type by field. + /// + /// + /// + public IIkvmReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field) + { + return (IIkvmReflectionFieldSymbolBuilder)GetOrCreateFieldSymbol((FieldInfo)field); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionGenericTypeParameterSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionGenericTypeParameterSymbol.cs index a685c97dc..ec027dd93 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionGenericTypeParameterSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionGenericTypeParameterSymbol.cs @@ -11,25 +11,25 @@ namespace IKVM.CoreLib.Symbols.IkvmReflection class IkvmReflectionGenericTypeParameterSymbol : IkvmReflectionMemberSymbol, IIkvmReflectionTypeSymbol { - readonly IIkvmReflectionMethodSymbol? _resolvingMethod; + readonly IIkvmReflectionMemberSymbol _resolvingMember; readonly Type _type; - IkvmReflectionTypeImpl _impl; + + IkvmReflectionTypeSpecTable _specTable; /// /// Initializes a new instance. /// /// /// - /// - /// + /// /// /// - public IkvmReflectionGenericTypeParameterSymbol(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol resolvingModule, IIkvmReflectionTypeSymbol? resolvingType, IIkvmReflectionMethodSymbol? resolvingMethod, Type type) : - base(context, resolvingModule, resolvingType) + public IkvmReflectionGenericTypeParameterSymbol(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol resolvingModule, IIkvmReflectionMemberSymbol resolvingMember, Type type) : + base(context, resolvingModule, resolvingMember as IIkvmReflectionTypeSymbol) { - _resolvingMethod = resolvingMethod; + _resolvingMember = resolvingMember ?? throw new ArgumentNullException(nameof(resolvingMember)); _type = type ?? throw new ArgumentNullException(nameof(type)); - _impl = new IkvmReflectionTypeImpl(this); + _specTable = new IkvmReflectionTypeSpecTable(); } /// @@ -41,526 +41,612 @@ public IkvmReflectionGenericTypeParameterSymbol(IkvmReflectionSymbolContext cont /// /// Gets the method base that declares this type parameter. /// - public IIkvmReflectionMethodBaseSymbol? ResolvingMethodBase => _resolvingMethod; + public IIkvmReflectionMemberSymbol? ResolvingMemberSymbol => _resolvingMember; + + #region IIkvmReflectionSymbol + + /// + [return: NotNullIfNotNull(nameof(type))] + public override IIkvmReflectionTypeSymbol? ResolveTypeSymbol(Type? type) + { + if (type == _type) + return this; + else + return base.ResolveTypeSymbol(type); + } + + #endregion + + #region IIkvmReflectionTypeSymbol + + /// + public IIkvmReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method) + { + throw new NotSupportedException(); + } + + /// + public IIkvmReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) + { + throw new NotSupportedException(); + } + + /// + public IIkvmReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) + { + throw new NotSupportedException(); + } + + /// + public IIkvmReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) + { + throw new NotSupportedException(); + } + + /// + public IIkvmReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) + { + throw new NotSupportedException(); + } + + /// + public IIkvmReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) + { + throw new NotSupportedException(); + } + + /// + public IIkvmReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type type) + { + throw new NotSupportedException(); + } + + /// + public IIkvmReflectionTypeSymbol GetOrCreateSZArrayTypeSymbol() + { + return _specTable.GetOrCreateSZArrayTypeSymbol(); + } + + /// + public IIkvmReflectionTypeSymbol GetOrCreateArrayTypeSymbol(int rank) + { + return _specTable.GetOrCreateArrayTypeSymbol(rank); + } + + /// + public IIkvmReflectionTypeSymbol GetOrCreatePointerTypeSymbol() + { + return _specTable.GetOrCreatePointerTypeSymbol(); + } + + /// + public IIkvmReflectionTypeSymbol GetOrCreateByRefTypeSymbol() + { + return _specTable.GetOrCreateByRefTypeSymbol(); + } + + /// + public IIkvmReflectionTypeSymbol GetOrCreateGenericTypeSymbol(Type[] genericTypeDefinition) + { + return _specTable.GetOrCreateGenericTypeSymbol(genericTypeDefinition); + } + + #endregion #region ITypeSymbol /// - public System.Reflection.TypeAttributes Attributes => _impl.Attributes; + public IAssemblySymbol Assembly => ResolveAssemblySymbol(UnderlyingType.Assembly); /// - public IAssemblySymbol Assembly => _impl.Assembly; + public string? AssemblyQualifiedName => UnderlyingType.AssemblyQualifiedName; /// - public IMethodBaseSymbol? DeclaringMethod => _impl.DeclaringMethod; + public System.Reflection.TypeAttributes Attributes => (System.Reflection.TypeAttributes)UnderlyingType.Attributes; /// - public string? AssemblyQualifiedName => _impl.AssemblyQualifiedName; + public ITypeSymbol? BaseType => ResolveTypeSymbol(UnderlyingType.BaseType); /// - public string? FullName => _impl.FullName; + public bool ContainsGenericParameters => UnderlyingType.ContainsGenericParameters; /// - public string? Namespace => _impl.Namespace; + public IMethodBaseSymbol? DeclaringMethod => ResolveMethodBaseSymbol(UnderlyingType.DeclaringMethod); /// - public TypeCode TypeCode => _impl.TypeCode; + public string? FullName => UnderlyingType.FullName; /// - public ITypeSymbol? BaseType => _impl.BaseType; + public string? Namespace => UnderlyingType.Namespace; /// - public bool ContainsGenericParameters => _impl.ContainsGenericParameters; + public System.Reflection.GenericParameterAttributes GenericParameterAttributes => (System.Reflection.GenericParameterAttributes)UnderlyingType.GenericParameterAttributes; /// - public System.Reflection.GenericParameterAttributes GenericParameterAttributes => _impl.GenericParameterAttributes; + public int GenericParameterPosition => UnderlyingType.GenericParameterPosition; /// - public int GenericParameterPosition => _impl.GenericParameterPosition; + public ITypeSymbol[] GenericTypeArguments => ResolveTypeSymbols(UnderlyingType.GenericTypeArguments); /// - public ITypeSymbol[] GenericTypeArguments => _impl.GenericTypeArguments; + public bool HasElementType => UnderlyingType.HasElementType; /// - public bool IsConstructedGenericType => _impl.IsConstructedGenericType; + public TypeCode TypeCode => Type.GetTypeCode(UnderlyingType); /// - public bool IsGenericType => _impl.IsGenericType; + public bool IsAbstract => UnderlyingType.IsAbstract; /// - public bool IsGenericTypeDefinition => _impl.IsGenericTypeDefinition; + public bool IsSZArray => UnderlyingType.IsSZArray; /// - public bool IsGenericParameter => _impl.IsGenericParameter; + public bool IsArray => UnderlyingType.IsArray; /// - public bool IsAutoLayout => _impl.IsAutoLayout; + public bool IsAutoLayout => UnderlyingType.IsAutoLayout; /// - public bool IsExplicitLayout => _impl.IsExplicitLayout; + public bool IsExplicitLayout => UnderlyingType.IsExplicitLayout; /// - public bool IsLayoutSequential => _impl.IsLayoutSequential; + public bool IsByRef => UnderlyingType.IsByRef; /// - public bool HasElementType => _impl.HasElementType; + public bool IsClass => UnderlyingType.IsClass; /// - public bool IsClass => _impl.IsClass; + public bool IsEnum => UnderlyingType.IsEnum; /// - public bool IsValueType => _impl.IsValueType; + public bool IsInterface => UnderlyingType.IsInterface; /// - public bool IsInterface => _impl.IsInterface; + public bool IsConstructedGenericType => UnderlyingType.IsConstructedGenericType; /// - public bool IsPrimitive => _impl.IsPrimitive; + public bool IsGenericParameter => UnderlyingType.IsGenericParameter; /// - public bool IsSZArray => _impl.IsSZArray; + public bool IsGenericType => UnderlyingType.IsGenericType; /// - public bool IsArray => _impl.IsArray; + public bool IsGenericTypeDefinition => UnderlyingType.IsGenericTypeDefinition; /// - public bool IsEnum => _impl.IsEnum; + public bool IsLayoutSequential => UnderlyingType.IsLayoutSequential; /// - public bool IsPointer => _impl.IsPointer; + public bool IsNested => UnderlyingType.IsNested; /// - public bool IsFunctionPointer => _impl.IsFunctionPointer; + public bool IsNestedAssembly => UnderlyingType.IsNestedAssembly; /// - public bool IsUnmanagedFunctionPointer => _impl.IsUnmanagedFunctionPointer; + public bool IsNestedFamANDAssem => UnderlyingType.IsNestedFamANDAssem; /// - public bool IsByRef => _impl.IsByRef; + public bool IsNestedFamORAssem => UnderlyingType.IsNestedFamORAssem; /// - public bool IsAbstract => _impl.IsAbstract; + public bool IsNestedFamily => UnderlyingType.IsNestedFamily; /// - public bool IsSealed => _impl.IsSealed; + public bool IsNestedPrivate => UnderlyingType.IsNestedPrivate; /// - public bool IsVisible => _impl.IsVisible; + public bool IsNestedPublic => UnderlyingType.IsNestedPublic; /// - public bool IsPublic => _impl.IsPublic; + public bool IsNotPublic => UnderlyingType.IsNotPublic; /// - public bool IsNotPublic => _impl.IsNotPublic; + public bool IsPointer => UnderlyingType.IsPointer; /// - public bool IsNested => _impl.IsNested; + public bool IsFunctionPointer => UnderlyingType.IsFunctionPointer; /// - public bool IsNestedAssembly => _impl.IsNestedAssembly; + public bool IsUnmanagedFunctionPointer => UnderlyingType.IsUnmanagedFunctionPointer; /// - public bool IsNestedFamANDAssem => _impl.IsNestedFamANDAssem; + public bool IsPrimitive => UnderlyingType.IsPrimitive; /// - public bool IsNestedFamily => _impl.IsNestedFamily; + public bool IsPublic => UnderlyingType.IsPublic; /// - public bool IsNestedFamORAssem => _impl.IsNestedFamORAssem; + public bool IsSealed => UnderlyingType.IsSealed; /// - public bool IsNestedPrivate => _impl.IsNestedPrivate; + public bool IsSerializable => UnderlyingType.IsSerializable; /// - public bool IsNestedPublic => _impl.IsNestedPublic; + public bool IsValueType => UnderlyingType.IsValueType; /// - public bool IsSerializable => _impl.IsSerializable; + public bool IsVisible => UnderlyingType.IsVisible; /// - public bool IsSignatureType => _impl.IsSignatureType; + public bool IsSignatureType => throw new NotImplementedException(); /// - public bool IsSpecialName => _impl.IsSpecialName; + public bool IsSpecialName => UnderlyingType.IsSpecialName; /// - public IConstructorSymbol? TypeInitializer => throw new NotImplementedException(); + public IConstructorSymbol? TypeInitializer => ResolveConstructorSymbol(UnderlyingType.TypeInitializer); /// public int GetArrayRank() { - return _impl.GetArrayRank(); + return UnderlyingType.GetArrayRank(); } /// - public IMemberSymbol[] GetDefaultMembers() + public IConstructorSymbol? GetConstructor(System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) { - return _impl.GetDefaultMembers(); + return ResolveConstructorSymbol(UnderlyingType.GetConstructor((BindingFlags)bindingAttr, binder: null, types.Unpack(), modifiers: null)); } /// - public ITypeSymbol? GetElementType() + public IConstructorSymbol? GetConstructor(ITypeSymbol[] types) { - return _impl.GetElementType(); + return ResolveConstructorSymbol(UnderlyingType.GetConstructor(types.Unpack())); } /// - public string? GetEnumName(object value) + public IConstructorSymbol[] GetConstructors() { - return _impl.GetEnumName(value); + return ResolveConstructorSymbols(UnderlyingType.GetConstructors()); } /// - public string[] GetEnumNames() + public IConstructorSymbol[] GetConstructors(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetEnumNames(); + return ResolveConstructorSymbols(UnderlyingType.GetConstructors((BindingFlags)bindingAttr)); } /// - public ITypeSymbol GetEnumUnderlyingType() + public IMemberSymbol[] GetDefaultMembers() { - return _impl.GetEnumUnderlyingType(); + return ResolveMemberSymbols(UnderlyingType.GetDefaultMembers()); } /// - public ITypeSymbol[] GetGenericArguments() + public ITypeSymbol? GetElementType() { - return _impl.GetGenericArguments(); + return ResolveTypeSymbol(UnderlyingType.GetElementType()); } /// - public ITypeSymbol[] GetGenericParameterConstraints() + public string? GetEnumName(object value) { - return _impl.GetGenericParameterConstraints(); + return UnderlyingType.GetEnumName(value); } /// - public ITypeSymbol GetGenericTypeDefinition() + public string[] GetEnumNames() { - return _impl.GetGenericTypeDefinition(); + return UnderlyingType.GetEnumNames(); } /// - public ITypeSymbol? GetInterface(string name) + public ITypeSymbol GetEnumUnderlyingType() { - return _impl.GetInterface(name); + return ResolveTypeSymbol(UnderlyingType.GetEnumUnderlyingType()); } /// - public ITypeSymbol? GetInterface(string name, bool ignoreCase) + public Array GetEnumValues() { - return _impl.GetInterface(name, ignoreCase); + return UnderlyingType.GetEnumValues(); } /// - public ITypeSymbol[] GetInterfaces(bool inherit = true) + public IEventSymbol? GetEvent(string name) { - return _impl.GetInterfaces(inherit); + return ResolveEventSymbol(UnderlyingType.GetEvent(name)); } /// - public InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) + public IEventSymbol? GetEvent(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetInterfaceMap(interfaceType); + return ResolveEventSymbol(UnderlyingType.GetEvent(name, (BindingFlags)bindingAttr)); } /// - public IMemberSymbol[] GetMember(string name) + public IEventSymbol[] GetEvents() { - return _impl.GetMember(name); + return ResolveEventSymbols(UnderlyingType.GetEvents()); } /// - public IMemberSymbol[] GetMember(string name, System.Reflection.BindingFlags bindingAttr) + public IEventSymbol[] GetEvents(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMember(name, bindingAttr); + return ResolveEventSymbols(UnderlyingType.GetEvents((BindingFlags)bindingAttr)); } /// - public IMemberSymbol[] GetMember(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) + public IFieldSymbol? GetField(string name) { - return _impl.GetMember(name, type, bindingAttr); + return ResolveFieldSymbol(UnderlyingType.GetField(name)); } /// - public IMemberSymbol[] GetMembers() + public IFieldSymbol? GetField(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMembers(); + return ResolveFieldSymbol(UnderlyingType.GetField(name, (BindingFlags)bindingAttr)); } /// - public IMemberSymbol[] GetMembers(System.Reflection.BindingFlags bindingAttr) + public IFieldSymbol[] GetFields() { - return _impl.GetMembers(bindingAttr); + return ResolveFieldSymbols(UnderlyingType.GetFields()); } - public IConstructorSymbol? GetConstructor(ITypeSymbol[] types) + /// + public IFieldSymbol[] GetFields(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetConstructor(types); + return ResolveFieldSymbols(UnderlyingType.GetFields((BindingFlags)bindingAttr)); } /// - public IConstructorSymbol? GetConstructor(System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) + public ITypeSymbol[] GetGenericArguments() { - return _impl.GetConstructor(bindingAttr, types); + return ResolveTypeSymbols(UnderlyingType.GetGenericArguments()); } /// - public IConstructorSymbol[] GetConstructors() + public ITypeSymbol[] GetGenericParameterConstraints() { - return _impl.GetConstructors(); + return ResolveTypeSymbols(UnderlyingType.GetGenericParameterConstraints()); } /// - public IConstructorSymbol[] GetConstructors(System.Reflection.BindingFlags bindingAttr) + public ITypeSymbol GetGenericTypeDefinition() { - return _impl.GetConstructors(bindingAttr); + return ResolveTypeSymbol(UnderlyingType.GetGenericTypeDefinition()); } /// - public IFieldSymbol? GetField(string name) + public ITypeSymbol? GetInterface(string name) { - return _impl.GetField(name); + return ResolveTypeSymbol(UnderlyingType.GetInterface(name)); } /// - public IFieldSymbol? GetField(string name, System.Reflection.BindingFlags bindingAttr) + public ITypeSymbol? GetInterface(string name, bool ignoreCase) { - return _impl.GetField(name, bindingAttr); + return ResolveTypeSymbol(UnderlyingType.GetInterface(name, ignoreCase)); } /// - public IFieldSymbol[] GetFields() + public InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) { - return _impl.GetFields(); + return ResolveInterfaceMapping(UnderlyingType.GetInterfaceMap(interfaceType.Unpack())); } /// - public IFieldSymbol[] GetFields(System.Reflection.BindingFlags bindingAttr) + public ITypeSymbol[] GetInterfaces(bool inherit = true) { - return _impl.GetFields(bindingAttr); + if (inherit) + return ResolveTypeSymbols(UnderlyingType.GetInterfaces()); + else + throw new NotImplementedException(); } /// - public IMethodSymbol? GetMethod(string name) + public IMemberSymbol[] GetMember(string name) { - return _impl.GetMethod(name); + return ResolveMemberSymbols(UnderlyingType.GetMember(name)); } /// - public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) + public IMemberSymbol[] GetMember(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMethod(name, types); + return ResolveMemberSymbols(UnderlyingType.GetMember(name, (BindingFlags)bindingAttr)); } /// - public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr) + public IMemberSymbol[] GetMember(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMethod(name, bindingAttr); + return ResolveMemberSymbols(UnderlyingType.GetMember(name, (MemberTypes)type, (BindingFlags)bindingAttr)); } /// - public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) + public IMemberSymbol[] GetMembers(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMethod(name, bindingAttr, types); + return ResolveMemberSymbols(UnderlyingType.GetMembers((BindingFlags)bindingAttr)); } /// - public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + public IMemberSymbol[] GetMembers() { - return _impl.GetMethod(name, bindingAttr, callConvention, types, modifiers); + return ResolveMemberSymbols(UnderlyingType.GetMembers()); } /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMethod(name, genericParameterCount, bindingAttr, callConvention, types, modifiers); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr)); } /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) { - return _impl.GetMethod(name, genericParameterCount, bindingAttr, types, modifiers); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, types.Unpack())); } /// - public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) { - return _impl.GetMethod(name, bindingAttr, types, modifiers); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), null)); } /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name) { - return _impl.GetMethod(name, genericParameterCount, types, modifiers); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name)); } /// - public IMethodSymbol[] GetMethods() + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return _impl.GetMethods(); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, (CallingConventions)callConvention, types.Unpack(), modifiers?.Unpack())); } /// - public IMethodSymbol[] GetMethods(System.Reflection.BindingFlags bindingAttr) + public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return _impl.GetMethods(bindingAttr); + throw new NotImplementedException(); } /// - public IPropertySymbol? GetProperty(string name) + public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return _impl.GetProperty(name); + throw new NotImplementedException(); } /// - public IPropertySymbol? GetProperty(string name, System.Reflection.BindingFlags bindingAttr) + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return _impl.GetProperty(name, bindingAttr); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), modifiers?.Unpack())); } /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol[] types) + public IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return _impl.GetProperty(name, types); + throw new NotImplementedException(); } /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types) + public IMethodSymbol[] GetMethods(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetProperty(name, returnType, types); + return ResolveMethodSymbols(UnderlyingType.GetMethods((BindingFlags)bindingAttr)); } /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) + public IMethodSymbol[] GetMethods() { - return _impl.GetProperty(name, returnType); + return ResolveMethodSymbols(UnderlyingType.GetMethods()); } /// - public IPropertySymbol[] GetProperties() + public ITypeSymbol? GetNestedType(string name) { - return _impl.GetProperties(); + return ResolveTypeSymbol(UnderlyingType.GetNestedType(name)); } /// - public IPropertySymbol[] GetProperties(System.Reflection.BindingFlags bindingAttr) + public ITypeSymbol? GetNestedType(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetProperties(bindingAttr); + return ResolveTypeSymbol(UnderlyingType.GetNestedType(name, (BindingFlags)bindingAttr)); } /// - public IEventSymbol? GetEvent(string name) + public ITypeSymbol[] GetNestedTypes() { - return _impl.GetEvent(name); + return ResolveTypeSymbols(UnderlyingType.GetNestedTypes()); } /// - public IEventSymbol? GetEvent(string name, System.Reflection.BindingFlags bindingAttr) + public ITypeSymbol[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetEvent(name, bindingAttr); + return ResolveTypeSymbols(UnderlyingType.GetNestedTypes((BindingFlags)bindingAttr)); } /// - public IEventSymbol[] GetEvents() + public IPropertySymbol[] GetProperties() { - return _impl.GetEvents(); + return ResolvePropertySymbols(UnderlyingType.GetProperties()); } /// - public IEventSymbol[] GetEvents(System.Reflection.BindingFlags bindingAttr) + public IPropertySymbol[] GetProperties(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetEvents(bindingAttr); + return ResolvePropertySymbols(UnderlyingType.GetProperties((BindingFlags)bindingAttr)); } /// - public ITypeSymbol? GetNestedType(string name) + public IPropertySymbol? GetProperty(string name, ITypeSymbol[] types) { - return _impl.GetNestedType(name); + return ResolvePropertySymbol(UnderlyingType.GetProperty(name, types.Unpack())); } /// - public ITypeSymbol? GetNestedType(string name, System.Reflection.BindingFlags bindingAttr) + public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types) { - return _impl.GetNestedType(name, bindingAttr); + return ResolvePropertySymbol(UnderlyingType.GetProperty(name, returnType?.Unpack(), types.Unpack())); } /// - public ITypeSymbol[] GetNestedTypes() + public IPropertySymbol? GetProperty(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetNestedTypes(); + return ResolvePropertySymbol(UnderlyingType.GetProperty(name, (BindingFlags)bindingAttr)); } /// - public ITypeSymbol[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr) + public IPropertySymbol? GetProperty(string name) { - return _impl.GetNestedTypes(); + return ResolvePropertySymbol(UnderlyingType.GetProperty(name)); } /// - public bool IsAssignableFrom(ITypeSymbol? c) + public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) { - return _impl.IsAssignableFrom(c); + return ResolvePropertySymbol(UnderlyingType.GetProperty(name, returnType?.Unpack())); } /// - public bool IsSubclassOf(ITypeSymbol c) + public bool IsAssignableFrom(ITypeSymbol? c) { - return _impl.IsSubclassOf(c); + return UnderlyingType.IsAssignableFrom(c?.Unpack()); } /// public bool IsEnumDefined(object value) { - return _impl.IsEnumDefined(value); + return UnderlyingType.IsEnumDefined(value); + } + + /// + public bool IsSubclassOf(ITypeSymbol c) + { + return UnderlyingType.IsSubclassOf(c.Unpack()); } /// public ITypeSymbol MakeArrayType() { - return _impl.MakeArrayType(); + return ResolveTypeSymbol(UnderlyingType.MakeArrayType()); } /// public ITypeSymbol MakeArrayType(int rank) { - return _impl.MakeArrayType(rank); + return ResolveTypeSymbol(UnderlyingType.MakeArrayType(rank)); } /// - public ITypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments) + public ITypeSymbol MakeByRefType() { - return _impl.MakeGenericType(typeArguments); + return ResolveTypeSymbol(UnderlyingType.MakeByRefType()); } /// public ITypeSymbol MakePointerType() { - return _impl.MakePointerType(); + return ResolveTypeSymbol(UnderlyingType.MakePointerType()); } /// - public ITypeSymbol MakeByRefType() + public ITypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments) { - return _impl.MakeByRefType(); + return ResolveTypeSymbol(UnderlyingType.MakeGenericType(typeArguments.Unpack())); } #endregion - /// - /// Resolves the symbol for the specified type. - /// - /// - /// - [return: NotNullIfNotNull(nameof(type))] - public override IIkvmReflectionTypeSymbol? ResolveTypeSymbol(Type? type) - { - if (type == _type) - return this; - else - return base.ResolveTypeSymbol(type); - } - } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionGenericTypeParameterTable.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionGenericTypeParameterTable.cs new file mode 100644 index 000000000..7caf5453c --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionGenericTypeParameterTable.cs @@ -0,0 +1,82 @@ +using System; +using System.Threading; + +using IKVM.CoreLib.Collections; +using IKVM.CoreLib.Symbols.IkvmReflection.Emit; +using IKVM.CoreLib.Threading; +using IKVM.Reflection.Emit; + +using Type = IKVM.Reflection.Type; + +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + struct IkvmReflectionGenericTypeParameterTable + { + + readonly IkvmReflectionSymbolContext _context; + readonly IIkvmReflectionModuleSymbol _module; + readonly IIkvmReflectionMemberSymbol _member; + + IndexRangeDictionary _table = new(); + ReaderWriterLockSlim? _lock; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + public IkvmReflectionGenericTypeParameterTable(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol module, IIkvmReflectionMemberSymbol member) + { + _context = context ?? throw new ArgumentNullException(nameof(context)); + _module = module ?? throw new ArgumentNullException(nameof(module)); + _member = member; + } + + /// + /// Gets or creates the cached for the module by type. + /// + /// + /// + public IIkvmReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type genericTypeParameter) + { + if (genericTypeParameter is null) + throw new ArgumentNullException(nameof(genericTypeParameter)); + if (genericTypeParameter.Module.MetadataToken != _module.MetadataToken) + throw new ArgumentException(nameof(genericTypeParameter)); + + // create lock on demand + if (_lock == null) + Interlocked.CompareExchange(ref _lock, new ReaderWriterLockSlim(), null); + + using (_lock.CreateUpgradeableReadLock()) + { + var pos = genericTypeParameter.GenericParameterPosition; + if (_table[pos] == null) + using (_lock.CreateWriteLock()) + if (genericTypeParameter is GenericTypeParameterBuilder builder) + return _table[pos] ??= new IkvmReflectionGenericTypeParameterSymbolBuilder(_context, (IIkvmReflectionModuleSymbolBuilder)_module, (IIkvmReflectionMemberSymbolBuilder)_member, builder); + else + return _table[pos] ??= new IkvmReflectionGenericTypeParameterSymbol(_context, _module, _member, genericTypeParameter); + else + { + return _table[pos] ?? throw new InvalidOperationException(); + } + } + } + + /// + /// Gets or creates the cached for the module. + /// + /// + /// + public IIkvmReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeParameterSymbol(GenericTypeParameterBuilder genericTypeParameter) + { + return (IIkvmReflectionGenericTypeParameterSymbolBuilder)GetOrCreateGenericTypeParameterSymbol((Type)genericTypeParameter); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs index 22ed03a6c..69abb7189 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; @@ -48,49 +47,6 @@ public IkvmReflectionMemberSymbol(IkvmReflectionSymbolContext context, IIkvmRefl /// public IIkvmReflectionTypeSymbol? ResolvingType => _resolvingType; - #region IMemberSymbol - - /// - public virtual IModuleSymbol Module => ResolveModuleSymbol(UnderlyingMember.Module)!; - - /// - public virtual ITypeSymbol? DeclaringType => ResolveTypeSymbol(UnderlyingMember.DeclaringType)!; - - /// - public virtual System.Reflection.MemberTypes MemberType => (System.Reflection.MemberTypes)UnderlyingMember.MemberType; - - /// - public virtual int MetadataToken => UnderlyingMember.MetadataToken; - - /// - public virtual string Name => UnderlyingMember.Name; - - /// - public virtual CustomAttribute[] GetCustomAttributes(bool inherit = false) - { - return ResolveCustomAttributes(UnderlyingMember.__GetCustomAttributes(null, inherit))!; - } - - /// - public virtual CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) - { - return ResolveCustomAttributes(UnderlyingMember.__GetCustomAttributes(attributeType.Unpack(), inherit)); - } - - /// - public virtual CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) - { - return ResolveCustomAttribute(UnderlyingMember.__GetCustomAttributes(attributeType.Unpack(), inherit).FirstOrDefault()); - } - - /// - public virtual bool IsDefined(ITypeSymbol attributeType, bool inherit = false) - { - return UnderlyingMember.IsDefined(attributeType.Unpack(), inherit); - } - - #endregion - /// [return: NotNullIfNotNull(nameof(type))] public override IIkvmReflectionTypeSymbol? ResolveTypeSymbol(Type? type) @@ -126,19 +82,6 @@ public virtual bool IsDefined(ITypeSymbol attributeType, bool inherit = false) return base.ResolveConstructorSymbol(ctor); } - /// - [return: NotNullIfNotNull(nameof(ctor))] - public override IIkvmReflectionConstructorSymbolBuilder ResolveConstructorSymbol(ConstructorBuilder ctor) - { - if (ctor is null) - throw new ArgumentNullException(nameof(ctor)); - - if (ctor.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateConstructorSymbol(ctor); - - return base.ResolveConstructorSymbol(ctor); - } - /// [return: NotNullIfNotNull(nameof(method))] public override IIkvmReflectionMethodSymbol? ResolveMethodSymbol(MethodInfo? method) @@ -155,19 +98,6 @@ public override IIkvmReflectionConstructorSymbolBuilder ResolveConstructorSymbol return base.ResolveMethodSymbol(method); } - /// - [return: NotNullIfNotNull(nameof(method))] - public override IIkvmReflectionMethodSymbolBuilder ResolveMethodSymbol(MethodBuilder method) - { - if (method is null) - throw new ArgumentNullException(nameof(method)); - - if (method.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateMethodSymbol(method); - - return base.ResolveMethodSymbol(method); - } - /// [return: NotNullIfNotNull(nameof(field))] public override IIkvmReflectionFieldSymbol? ResolveFieldSymbol(FieldInfo? field) @@ -184,19 +114,6 @@ public override IIkvmReflectionMethodSymbolBuilder ResolveMethodSymbol(MethodBui return base.ResolveFieldSymbol(field); } - /// - [return: NotNullIfNotNull(nameof(field))] - public override IIkvmReflectionFieldSymbolBuilder ResolveFieldSymbol(FieldBuilder field) - { - if (field is null) - throw new ArgumentNullException(nameof(field)); - - if (field.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateFieldSymbol(field); - - return base.ResolveFieldSymbol(field); - } - /// [return: NotNullIfNotNull(nameof(property))] public override IIkvmReflectionPropertySymbol? ResolvePropertySymbol(PropertyInfo? property) @@ -213,19 +130,6 @@ public override IIkvmReflectionFieldSymbolBuilder ResolveFieldSymbol(FieldBuilde return base.ResolvePropertySymbol(property); } - /// - [return: NotNullIfNotNull(nameof(property))] - public override IIkvmReflectionPropertySymbolBuilder ResolvePropertySymbol(PropertyBuilder property) - { - if (property is null) - throw new ArgumentNullException(nameof(property)); - - if (property.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreatePropertySymbol(property); - - return base.ResolvePropertySymbol(property); - } - /// [return: NotNullIfNotNull(nameof(@event))] public override IIkvmReflectionEventSymbol? ResolveEventSymbol(EventInfo? @event) @@ -242,19 +146,6 @@ public override IIkvmReflectionPropertySymbolBuilder ResolvePropertySymbol(Prope return base.ResolveEventSymbol(@event); } - /// - [return: NotNullIfNotNull(nameof(@event))] - public override IIkvmReflectionEventSymbolBuilder ResolveEventSymbol(EventBuilder @event) - { - if (@event is null) - throw new ArgumentNullException(nameof(@event)); - - if (@event.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateEventSymbol(@event); - - return base.ResolveEventSymbol(@event); - } - /// [return: NotNullIfNotNull(nameof(parameter))] public override IIkvmReflectionParameterSymbol? ResolveParameterSymbol(ParameterInfo? parameter) @@ -268,19 +159,49 @@ public override IIkvmReflectionEventSymbolBuilder ResolveEventSymbol(EventBuilde return base.ResolveParameterSymbol(parameter); } + #region IMemberSymbol + /// - [return: NotNullIfNotNull(nameof(parameter))] - public override IIkvmReflectionParameterSymbolBuilder ResolveParameterSymbol(ParameterBuilder parameter) + public virtual IModuleSymbol Module => ResolveModuleSymbol(UnderlyingMember.Module)!; + + /// + public virtual ITypeSymbol? DeclaringType => ResolveTypeSymbol(UnderlyingMember.DeclaringType)!; + + /// + public virtual System.Reflection.MemberTypes MemberType => (System.Reflection.MemberTypes)UnderlyingMember.MemberType; + + /// + public virtual int MetadataToken => UnderlyingMember.MetadataToken; + + /// + public virtual string Name => UnderlyingMember.Name; + + /// + public virtual CustomAttribute[] GetCustomAttributes(bool inherit = false) { - if (parameter is null) - throw new ArgumentNullException(nameof(parameter)); + return ResolveCustomAttributes(UnderlyingMember.__GetCustomAttributes(null, inherit))!; + } - if (parameter.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateParameterSymbol(parameter); + /// + public virtual CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) + { + return ResolveCustomAttributes(UnderlyingMember.__GetCustomAttributes(attributeType.Unpack(), inherit)); + } - return base.ResolveParameterSymbol(parameter); + /// + public virtual CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) + { + return ResolveCustomAttribute(UnderlyingMember.__GetCustomAttributes(attributeType.Unpack(), inherit).FirstOrDefault()); } + /// + public virtual bool IsDefined(ITypeSymbol attributeType, bool inherit = false) + { + return UnderlyingMember.IsDefined(attributeType.Unpack(), inherit); + } + + #endregion + } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodBaseSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodBaseSymbol.cs index 3e5a0a836..9e3d71d81 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodBaseSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodBaseSymbol.cs @@ -6,6 +6,8 @@ namespace IKVM.CoreLib.Symbols.IkvmReflection abstract class IkvmReflectionMethodBaseSymbol : IkvmReflectionMemberSymbol, IIkvmReflectionMethodBaseSymbol { + IkvmReflectionParameterTable _parameterTable; + /// /// Initializes a new instance. /// @@ -15,9 +17,19 @@ abstract class IkvmReflectionMethodBaseSymbol : IkvmReflectionMemberSymbol, IIkv public IkvmReflectionMethodBaseSymbol(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol resolvingModule, IIkvmReflectionTypeSymbol? resolvingType) : base(context, resolvingModule, resolvingType) { + _parameterTable = new IkvmReflectionParameterTable(context, resolvingModule, this); + } + #region IIkvmReflectionMethodBaseSymbol + + /// + public IIkvmReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) + { + return _parameterTable.GetOrCreateParameterSymbol(parameter); } + #endregion + #region IMethodBaseSymbol /// diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodSpecTable.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodSpecTable.cs new file mode 100644 index 000000000..1a94625e7 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodSpecTable.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Concurrent; +using System.Threading; + +using Type = IKVM.Reflection.Type; + +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + struct IkvmReflectionMethodSpecTable + { + + readonly IkvmReflectionSymbolContext _context; + readonly IIkvmReflectionModuleSymbol _module; + readonly IIkvmReflectionTypeSymbol _type; + readonly IIkvmReflectionMethodSymbol _method; + + ConcurrentDictionary? _genericMethodSymbols; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + /// + public IkvmReflectionMethodSpecTable(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol module, IIkvmReflectionTypeSymbol type, IIkvmReflectionMethodSymbol method) + { + _context = context ?? throw new ArgumentNullException(nameof(context)); + _module = module ?? throw new ArgumentNullException(nameof(module)); + _type = type ?? throw new ArgumentNullException(nameof(type)); + _method = method ?? throw new ArgumentNullException(nameof(method)); + } + + /// + /// Gets or creates a representing a specialized generic of this method. + /// + /// + /// + public IIkvmReflectionMethodSymbol GetOrCreateGenericMethodSymbol(Type[] genericTypeArguments) + { + if (genericTypeArguments is null) + throw new ArgumentNullException(nameof(genericTypeArguments)); + + if (_method.IsGenericMethodDefinition == false) + throw new InvalidOperationException(); + + if (_genericMethodSymbols == null) + Interlocked.CompareExchange(ref _genericMethodSymbols, new(TypeSymbolListEqualityComparer.Instance), null); + + return _genericMethodSymbols.GetOrAdd(_module.ResolveTypeSymbols(genericTypeArguments), CreateGenericMethodSymbol); + } + + /// + /// Creates a new representing a specialized generic of this type. + /// + /// + /// + readonly IIkvmReflectionMethodSymbol CreateGenericMethodSymbol(IIkvmReflectionTypeSymbol[] genericTypeArguments) + { + return new IkvmReflectionMethodSymbol(_context, _module, _type, _method.UnderlyingMethod.MakeGenericMethod(genericTypeArguments.Unpack())); + } + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodSymbol.cs index 54dc46ff7..e0c8b8e3e 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodSymbol.cs @@ -2,6 +2,8 @@ using IKVM.Reflection; +using Type = IKVM.Reflection.Type; + namespace IKVM.CoreLib.Symbols.IkvmReflection { @@ -10,6 +12,8 @@ class IkvmReflectionMethodSymbol : IkvmReflectionMethodBaseSymbol, IIkvmReflecti readonly MethodInfo _method; + IkvmReflectionGenericTypeParameterTable _genericTypeParameterTable; + /// /// Initializes a new instance. /// @@ -21,6 +25,7 @@ public IkvmReflectionMethodSymbol(IkvmReflectionSymbolContext context, IIkvmRefl base(context, module, type) { _method = method ?? throw new ArgumentNullException(nameof(method)); + _genericTypeParameterTable = new IkvmReflectionGenericTypeParameterTable(context, module, this); } /// @@ -29,6 +34,16 @@ public IkvmReflectionMethodSymbol(IkvmReflectionSymbolContext context, IIkvmRefl /// public override MethodBase UnderlyingMethodBase => UnderlyingMethod; + #region IIkvmReflectionMethodSymbol + + /// + public IIkvmReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type genericTypeParameter) + { + return _genericTypeParameterTable.GetOrCreateGenericTypeParameterSymbol(genericTypeParameter); + } + + #endregion + #region IMethodSymbol /// diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodTable.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodTable.cs new file mode 100644 index 000000000..cd1781c83 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodTable.cs @@ -0,0 +1,157 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Reflection.Metadata.Ecma335; +using System.Threading; + +using IKVM.CoreLib.Collections; +using IKVM.CoreLib.Symbols.IkvmReflection.Emit; +using IKVM.CoreLib.Threading; +using IKVM.Reflection; +using IKVM.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + struct IkvmReflectionMethodTable + { + + readonly IkvmReflectionSymbolContext _context; + readonly IIkvmReflectionModuleSymbol _module; + readonly IIkvmReflectionTypeSymbol? _type; + + IndexRangeDictionary _table = new(); + ReaderWriterLockSlim? _lock; + + ConcurrentDictionary? _byName; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + public IkvmReflectionMethodTable(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol module, IIkvmReflectionTypeSymbol? type) + { + _context = context ?? throw new ArgumentNullException(nameof(context)); + _module = module ?? throw new ArgumentNullException(nameof(module)); + _type = type; + } + + /// + /// Gets or creates the cached for the type by method. + /// + /// + /// + public IIkvmReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method) + { + if (method is null) + throw new ArgumentNullException(nameof(method)); + if (method.Module.MetadataToken != _module.MetadataToken) + throw new ArgumentException(nameof(method)); + if (method is MethodInfo m_ && m_.IsMethodDefinition() == false) + throw new ArgumentException(nameof(method)); + + var row = MetadataTokens.GetRowNumber(MetadataTokens.MethodDefinitionHandle(method.MetadataToken)); + if (row == 0) + { + // we fall back to lookup by name if there is no valid metadata token + if (_byName == null) + Interlocked.CompareExchange(ref _byName, new(), null); + + var context_ = _context; + var module_ = _module; + var type_ = _type; + var method_ = method; + return _byName.GetOrAdd(method.ToString() ?? throw new InvalidOperationException(), _ => CreateMethodBaseSymbol(context_, module_, type_, method_)); + } + + // create lock on demand + if (_lock == null) + Interlocked.CompareExchange(ref _lock, new(), null); + + using (_lock.CreateUpgradeableReadLock()) + { + if (_table[row] == null) + using (_lock.CreateWriteLock()) + return _table[row] ??= CreateMethodBaseSymbol(_context, _module, _type, method); + + return _table[row] ?? throw new InvalidOperationException(); + } + } + + /// + /// Creates a new symbol. + /// + /// + /// + /// + static IIkvmReflectionMethodBaseSymbol CreateMethodBaseSymbol(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol module, IIkvmReflectionTypeSymbol? type, MethodBase method) + { + if (method is ConstructorInfo c) + { + if (type == null) + throw new InvalidOperationException(); + + if (method is ConstructorBuilder builder) + return new IkvmReflectionConstructorSymbolBuilder(context, (IIkvmReflectionModuleSymbolBuilder)module, (IIkvmReflectionTypeSymbolBuilder)type, builder); + else + return new IkvmReflectionConstructorSymbol(context, module, type, c); + } + else if (method is MethodInfo m) + { + if (method is MethodBuilder builder) + return new IkvmReflectionMethodSymbolBuilder(context, (IIkvmReflectionModuleSymbolBuilder)module, (IIkvmReflectionTypeSymbolBuilder?)type, builder); + else + return new IkvmReflectionMethodSymbol(context, module, type, m); + } + else + { + throw new InvalidOperationException(); + } + } + + /// + /// Gets or creates the cached for the type by method. + /// + /// + /// + public IIkvmReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) + { + return (IIkvmReflectionConstructorSymbol)GetOrCreateMethodBaseSymbol(ctor); + } + + /// + /// Gets or creates the cached for the type by method. + /// + /// + /// + public IIkvmReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor) + { + return (IIkvmReflectionConstructorSymbolBuilder)GetOrCreateMethodBaseSymbol(ctor); + } + + /// + /// Gets or creates the cached for the type by method. + /// + /// + /// + public IIkvmReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) + { + return (IIkvmReflectionMethodSymbol)GetOrCreateMethodBaseSymbol(method); + } + + /// + /// Gets or creates the cached for the type by method. + /// + /// + /// + public IIkvmReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method) + { + return (IIkvmReflectionMethodSymbolBuilder)GetOrCreateMethodBaseSymbol(method); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleMetadata.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleMetadata.cs deleted file mode 100644 index 1d9b0a3e2..000000000 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleMetadata.cs +++ /dev/null @@ -1,480 +0,0 @@ -using System; -using System.Reflection.Metadata.Ecma335; -using System.Threading; - -using IKVM.CoreLib.Collections; -using IKVM.CoreLib.Symbols.IkvmReflection.Emit; -using IKVM.CoreLib.Threading; -using IKVM.Reflection; -using IKVM.Reflection.Emit; - -using Type = IKVM.Reflection.Type; - -namespace IKVM.CoreLib.Symbols.IkvmReflection -{ - - /// - /// Provides the metadata resolution implementation for a module. - /// - struct IkvmReflectionModuleMetadata - { - - /// - /// Returns true if the given is a TypeDef. That is, not a modified or substituted or generic parameter type. - /// - /// - /// - static bool IsTypeDefinition(Type type) - { - return type.HasElementType == false && type.IsConstructedGenericType == false && type.IsGenericParameter == false; - } - - const int MAX_CAPACITY = 65536 * 2; - - readonly IIkvmReflectionModuleSymbol _symbol; - - IndexRangeDictionary _typeSymbols = new(maxCapacity: MAX_CAPACITY); - ReaderWriterLockSlim? _typeLock; - - IndexRangeDictionary _methodSymbols = new(maxCapacity: MAX_CAPACITY); - ReaderWriterLockSlim? _methodLock; - - IndexRangeDictionary _fieldSymbols = new(maxCapacity: MAX_CAPACITY); - ReaderWriterLockSlim? _fieldLock; - - IndexRangeDictionary _propertySymbols = new(maxCapacity: MAX_CAPACITY); - ReaderWriterLockSlim? _propertyLock; - - IndexRangeDictionary _eventSymbols = new(maxCapacity: MAX_CAPACITY); - ReaderWriterLockSlim? _eventLock; - - IndexRangeDictionary _parameterSymbols = new(maxCapacity: MAX_CAPACITY); - ReaderWriterLockSlim? _parameterLock; - - IndexRangeDictionary _genericParameterSymbols = new(maxCapacity: MAX_CAPACITY); - ReaderWriterLockSlim? _genericParameterLock; - - /// - /// Initializes a new instance. - /// - /// - /// - public IkvmReflectionModuleMetadata(IIkvmReflectionModuleSymbol symbol) - { - _symbol = symbol ?? throw new ArgumentNullException(nameof(symbol)); - } - - /// - /// Gets or creates the cached for the module by type. - /// - /// - /// - public IIkvmReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) - { - if (type is null) - throw new ArgumentNullException(nameof(type)); - if (type.Module.MetadataToken != _symbol.MetadataToken) - throw new ArgumentException(nameof(type)); - - // type is a generic parameter (GenericParam) - if (type.IsGenericParameter) - return GetOrCreateGenericTypeParameterSymbol(type); - - // type is not a type definition (TypeDef) - if (IsTypeDefinition(type) == false) - return GetOrCreateTypeSymbolForSpecification(type); - - // create lock on demand - if (_typeLock == null) - Interlocked.CompareExchange(ref _typeLock, new ReaderWriterLockSlim(), null); - - using (_typeLock.CreateUpgradeableReadLock()) - { - var row = MetadataTokens.GetRowNumber(MetadataTokens.TypeDefinitionHandle(type.MetadataToken)); - if (_typeSymbols[row] == null) - using (_typeLock.CreateWriteLock()) - if (type is TypeBuilder builder) - return _typeSymbols[row] ??= new IkvmReflectionTypeSymbolBuilder(_symbol.Context, _symbol, builder); - else - return _typeSymbols[row] ??= new IkvmReflectionTypeSymbol(_symbol.Context, _symbol, type); - else - return _typeSymbols[row] ?? throw new InvalidOperationException(); - } - } - - - /// - /// Gets or creates the cached for the module by type. - /// - /// - /// - public IIkvmReflectionTypeSymbolBuilder GetOrCreateTypeSymbol(TypeBuilder type) - { - return (IIkvmReflectionTypeSymbolBuilder)GetOrCreateTypeSymbol((Type)type); - } - - /// - /// Gets or creates a for the specification type: array, pointer, generic, etc. - /// - /// - /// - /// - /// - IIkvmReflectionTypeSymbol GetOrCreateTypeSymbolForSpecification(Type type) - { - if (type is null) - throw new ArgumentNullException(nameof(type)); - if (type.Module.MetadataToken != _symbol.MetadataToken) - throw new ArgumentException(nameof(type)); - - if (type.GetElementType() is { } elementType) - { - var elementTypeSymbol = _symbol.ResolveTypeSymbol(elementType)!; - - // handles both SZ arrays and normal arrays - if (type.IsArray) - return (IIkvmReflectionTypeSymbol)elementTypeSymbol.MakeArrayType(type.GetArrayRank()); - - if (type.IsPointer) - return (IIkvmReflectionTypeSymbol)elementTypeSymbol.MakePointerType(); - - if (type.IsByRef) - return (IIkvmReflectionTypeSymbol)elementTypeSymbol.MakeByRefType(); - - throw new InvalidOperationException(); - } - - if (type.IsGenericType) - { - var definitionTypeSymbol = _symbol.GetOrCreateTypeSymbol(type.GetGenericTypeDefinition()); - return (IIkvmReflectionTypeSymbol)definitionTypeSymbol.MakeGenericType(definitionTypeSymbol.ResolveTypeSymbols(type.GetGenericArguments())!); - } - - throw new InvalidOperationException(); - } - - /// - /// Gets or creates the cached for the type by method. - /// - /// - /// - public IIkvmReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method) - { - if (method is null) - throw new ArgumentNullException(nameof(method)); - if (method.Module.MetadataToken != _symbol.MetadataToken) - throw new ArgumentException(nameof(method)); - - // create lock on demand - if (_methodLock == null) - Interlocked.CompareExchange(ref _methodLock, new ReaderWriterLockSlim(), null); - - using (_methodLock.CreateUpgradeableReadLock()) - { - var row = MetadataTokens.GetRowNumber(MetadataTokens.MethodDefinitionHandle(method.MetadataToken)); - if (_methodSymbols[row] == null) - { - using (_methodLock.CreateWriteLock()) - { - if (method is ConstructorInfo c) - { - if (method is ConstructorBuilder builder) - return _methodSymbols[row] ??= new IkvmReflectionConstructorSymbolBuilder(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(c.DeclaringType!), builder); - else - return _methodSymbols[row] ??= new IkvmReflectionConstructorSymbol(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(c.DeclaringType!), c); - } - else if (method is MethodInfo m) - { - if (method is MethodBuilder builder) - return _methodSymbols[row] ??= new IkvmReflectionMethodSymbolBuilder(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(method.DeclaringType), builder); - else - return _methodSymbols[row] ??= new IkvmReflectionMethodSymbol(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(method.DeclaringType), m); - } - else - { - throw new InvalidOperationException(); - } - } - } - else - { - return _methodSymbols[row] ?? throw new InvalidOperationException(); - } - } - } - - /// - /// Gets or creates the cached for the type by ctor. - /// - /// - /// - public IIkvmReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) - { - return (IIkvmReflectionConstructorSymbol)GetOrCreateMethodBaseSymbol(ctor); - } - - /// - /// Gets or creates the cached for the type by ctor. - /// - /// - /// - public IIkvmReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor) - { - return (IIkvmReflectionConstructorSymbolBuilder)GetOrCreateConstructorSymbol((ConstructorInfo)ctor); - } - - /// - /// Gets or creates the cached for the type by method. - /// - /// - /// - public IIkvmReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) - { - return (IIkvmReflectionMethodSymbol)GetOrCreateMethodBaseSymbol(method); - } - - /// - /// Gets or creates the cached for the type by method. - /// - /// - /// - public IIkvmReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method) - { - return (IIkvmReflectionMethodSymbolBuilder)GetOrCreateMethodBaseSymbol((MethodInfo)method); - } - - /// - /// Gets or creates the cached for the type by field. - /// - /// - /// - public IIkvmReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) - { - if (field is null) - throw new ArgumentNullException(nameof(field)); - if (field.Module.MetadataToken != _symbol.MetadataToken) - throw new ArgumentException(nameof(field)); - - // create lock on demand - if (_fieldLock == null) - Interlocked.CompareExchange(ref _fieldLock, new ReaderWriterLockSlim(), null); - - using (_fieldLock.CreateUpgradeableReadLock()) - { - var row = MetadataTokens.GetRowNumber(MetadataTokens.FieldDefinitionHandle(field.MetadataToken)); - if (_fieldSymbols[row] == null) - using (_fieldLock.CreateWriteLock()) - if (field is FieldBuilder builder) - return _fieldSymbols[row] ??= new IkvmReflectionFieldSymbolBuilder(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(field.DeclaringType), builder); - else - return _fieldSymbols[row] ??= new IkvmReflectionFieldSymbol(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(field.DeclaringType), field); - else - return _fieldSymbols[row] ?? throw new InvalidOperationException(); - } - } - - /// - /// Gets or creates the cached for the type by method. - /// - /// - /// - public IIkvmReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field) - { - return (IIkvmReflectionFieldSymbolBuilder)GetOrCreateFieldSymbol((FieldInfo)field); - } - - /// - /// Gets or creates the cached for the type by property. - /// - /// - /// - public IIkvmReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) - { - if (property is null) - throw new ArgumentNullException(nameof(property)); - if (property.Module.MetadataToken != _symbol.MetadataToken) - throw new ArgumentException(nameof(property)); - - // create lock on demand - if (_propertyLock == null) - Interlocked.CompareExchange(ref _propertyLock, new ReaderWriterLockSlim(), null); - - using (_propertyLock.CreateUpgradeableReadLock()) - { - var row = MetadataTokens.GetRowNumber(MetadataTokens.PropertyDefinitionHandle(property.MetadataToken)); - if (_propertySymbols[row] == null) - using (_propertyLock.CreateWriteLock()) - if (property is PropertyBuilder builder) - return _propertySymbols[row] ??= new IkvmReflectionPropertySymbolBuilder(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(property.DeclaringType!), builder); - else - return _propertySymbols[row] ??= new IkvmReflectionPropertySymbol(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(property.DeclaringType!), property); - else - return _propertySymbols[row] ?? throw new InvalidOperationException(); - } - } - - - /// - /// Gets or creates the cached for the type by property. - /// - /// - /// - public IIkvmReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property) - { - return (IIkvmReflectionPropertySymbolBuilder)GetOrCreatePropertySymbol((PropertyInfo)property); - } - - /// - /// Gets or creates the cached for the type by event. - /// - /// - /// - public IIkvmReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) - { - if (@event is null) - throw new ArgumentNullException(nameof(@event)); - if (@event.Module.MetadataToken != _symbol.MetadataToken) - throw new ArgumentException(nameof(@event)); - - // create lock on demand - if (_eventLock == null) - Interlocked.CompareExchange(ref _eventLock, new ReaderWriterLockSlim(), null); - - using (_eventLock.CreateUpgradeableReadLock()) - { - var row = MetadataTokens.GetRowNumber(MetadataTokens.EventDefinitionHandle(@event.MetadataToken)); - if (_eventSymbols[row] == null) - using (_eventLock.CreateWriteLock()) - return _eventSymbols[row] ??= new IkvmReflectionEventSymbol(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(@event.DeclaringType!), @event); - else - return _eventSymbols[row] ?? throw new InvalidOperationException(); - } - } - - /// - /// Gets or creates the cached for the type by event. - /// - /// - /// - public IIkvmReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event) - { - if (@event is null) - throw new ArgumentNullException(nameof(@event)); - if (@event.Module.MetadataToken != _symbol.MetadataToken) - throw new ArgumentException(nameof(@event)); - - // create lock on demand - if (_eventLock == null) - Interlocked.CompareExchange(ref _eventLock, new ReaderWriterLockSlim(), null); - - using (_eventLock.CreateUpgradeableReadLock()) - { - var row = MetadataTokens.GetRowNumber(MetadataTokens.EventDefinitionHandle(@event.GetEventToken().Token)); - if (_eventSymbols[row] == null) - using (_eventLock.CreateWriteLock()) - return (IIkvmReflectionEventSymbolBuilder)(_eventSymbols[row] ??= new IkvmReflectionEventSymbolBuilder(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(@event.DeclaringType), @event)); - else - return (IIkvmReflectionEventSymbolBuilder?)_eventSymbols[row] ?? throw new InvalidOperationException(); - } - } - - /// - /// Gets or creates the cached for the type by method. - /// - /// - /// - public IIkvmReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) - { - if (parameter is null) - throw new ArgumentNullException(nameof(parameter)); - if (parameter.Member.Module.MetadataToken != _symbol.MetadataToken) - throw new ArgumentException(nameof(parameter)); - - // create lock on demand - if (_parameterLock == null) - Interlocked.CompareExchange(ref _parameterLock, new ReaderWriterLockSlim(), null); - - using (_parameterLock.CreateUpgradeableReadLock()) - { - var position = parameter.Position; - if (_parameterSymbols[position] == null) - using (_parameterLock.CreateWriteLock()) - return _parameterSymbols[position] ??= new IkvmReflectionParameterSymbol(_symbol.Context, _symbol, _symbol.ResolveMethodBaseSymbol((MethodBase)parameter.Member), parameter); - else - return _parameterSymbols[position] ?? throw new InvalidOperationException(); - } - } - - /// - /// Gets or creates the cached for the type by method. - /// - /// - /// - public IIkvmReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter) - { - if (parameter is null) - throw new ArgumentNullException(nameof(parameter)); - if (parameter.Module.MetadataToken != _symbol.MetadataToken) - throw new ArgumentException(nameof(parameter)); - - // create lock on demand - if (_parameterLock == null) - Interlocked.CompareExchange(ref _parameterLock, new ReaderWriterLockSlim(), null); - - using (_parameterLock.CreateUpgradeableReadLock()) - { - var position = parameter.Position; - if (_parameterSymbols[position] == null) - using (_parameterLock.CreateWriteLock()) - return (IIkvmReflectionParameterSymbolBuilder)(_parameterSymbols[position] ??= new IkvmReflectionParameterSymbolBuilder(_symbol.Context, _symbol, _symbol.ResolveMethodSymbol(parameter.Method), parameter)); - else - return (IIkvmReflectionParameterSymbolBuilder?)_parameterSymbols[position] ?? throw new InvalidOperationException(); - } - } - - /// - /// Gets or creates the cached for the module by type. - /// - /// - /// - IIkvmReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type genericParameterType) - { - if (genericParameterType is null) - throw new ArgumentNullException(nameof(genericParameterType)); - if (genericParameterType.Module.MetadataToken != _symbol.MetadataToken) - throw new ArgumentException(nameof(genericParameterType)); - - // create lock on demand - if (_genericParameterLock == null) - Interlocked.CompareExchange(ref _genericParameterLock, new ReaderWriterLockSlim(), null); - - using (_genericParameterLock.CreateUpgradeableReadLock()) - { - var hnd = MetadataTokens.GenericParameterHandle(genericParameterType.MetadataToken); - var row = MetadataTokens.GetRowNumber(hnd); - if (_genericParameterSymbols[row] == null) - using (_genericParameterLock.CreateWriteLock()) - if (genericParameterType is GenericTypeParameterBuilder builder) - return _genericParameterSymbols[row] ??= new IkvmReflectionGenericTypeParameterSymbolBuilder(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(genericParameterType.DeclaringType), _symbol.ResolveMethodSymbol((MethodInfo?)genericParameterType.DeclaringMethod), builder); - else - return _genericParameterSymbols[row] ??= new IkvmReflectionGenericTypeParameterSymbol(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(genericParameterType.DeclaringType), _symbol.ResolveMethodSymbol((MethodInfo?)genericParameterType.DeclaringMethod), genericParameterType); - else - { - return _genericParameterSymbols[row] ?? throw new InvalidOperationException(); - } - } - } - - /// - /// Gets or creates the cached for the module. - /// - /// - /// - IIkvmReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeParameterSymbol(GenericTypeParameterBuilder genericParameterType) - { - return (IIkvmReflectionGenericTypeParameterSymbolBuilder)GetOrCreateGenericTypeParameterSymbol((Type)genericParameterType); - } - - } - -} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs index 94913c88f..1775a2692 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs @@ -1,9 +1,7 @@ using System; using System.Linq; -using IKVM.CoreLib.Symbols.IkvmReflection.Emit; using IKVM.Reflection; -using IKVM.Reflection.Emit; using Type = IKVM.Reflection.Type; @@ -18,7 +16,10 @@ class IkvmReflectionModuleSymbol : IkvmReflectionSymbol, IIkvmReflectionModuleSy readonly IIkvmReflectionAssemblySymbol _resolvingAssembly; readonly Module _module; - IkvmReflectionModuleMetadata _impl; + + IkvmReflectionTypeTable _typeTable; + IkvmReflectionMethodTable _methodTable; + IkvmReflectionFieldTable _fieldTable; /// /// Initializes a new instance. @@ -32,7 +33,10 @@ public IkvmReflectionModuleSymbol(IkvmReflectionSymbolContext context, IIkvmRefl { _resolvingAssembly = resolvingAssembly ?? throw new ArgumentNullException(nameof(resolvingAssembly)); _module = module ?? throw new ArgumentNullException(nameof(module)); - _impl = new IkvmReflectionModuleMetadata(this); + + _typeTable = new IkvmReflectionTypeTable(context, this, null); + _methodTable = new IkvmReflectionMethodTable(context, this, null); + _fieldTable = new IkvmReflectionFieldTable(context, this, null); } /// @@ -231,89 +235,88 @@ public bool IsDefined(ITypeSymbol attributeType, bool inherit = false) #endregion + #region IIkvmReflectionModuleSymbol + /// public IIkvmReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) { - return _impl.GetOrCreateTypeSymbol(type); - } + if (type.IsTypeDefinition()) + return _typeTable.GetOrCreateTypeSymbol(type); + else if (type.IsGenericType) + return ResolveTypeSymbol(type.GetGenericTypeDefinition()).GetOrCreateGenericTypeSymbol(type.GetGenericArguments()); + else if (type.IsSZArray) + return ResolveTypeSymbol(type.GetElementType()).GetOrCreateSZArrayTypeSymbol(); + else if (type.IsArray) + return ResolveTypeSymbol(type.GetElementType()).GetOrCreateArrayTypeSymbol(type.GetArrayRank()); + else if (type.IsPointer) + return ResolveTypeSymbol(type.GetElementType()).GetOrCreatePointerTypeSymbol(); + else if (type.IsByRef) + return ResolveTypeSymbol(type.GetElementType()).GetOrCreateByRefTypeSymbol(); + else if (type.IsGenericParameter && type.DeclaringMethod is MethodInfo dm) + return ResolveMethodSymbol(dm).GetOrCreateGenericTypeParameterSymbol(type); + else if (type.IsGenericParameter && type.DeclaringType is Type t) + return ResolveTypeSymbol(t).GetOrCreateGenericTypeParameterSymbol(type); - /// - public IIkvmReflectionTypeSymbolBuilder GetOrCreateTypeSymbol(TypeBuilder type) - { - return _impl.GetOrCreateTypeSymbol(type); + throw new InvalidOperationException(); } /// - public IIkvmReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) + public IIkvmReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method) { - return _impl.GetOrCreateConstructorSymbol(ctor); + if (method.DeclaringType is { } dt) + return ResolveTypeSymbol(dt).GetOrCreateMethodBaseSymbol(method); + else + return _methodTable.GetOrCreateMethodBaseSymbol(method); } /// - public IIkvmReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor) + public IIkvmReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) { - return _impl.GetOrCreateConstructorSymbol(ctor); + return ResolveTypeSymbol(ctor.DeclaringType).GetOrCreateConstructorSymbol(ctor); } /// public IIkvmReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) { - return _impl.GetOrCreateMethodSymbol(method); - } - - /// - public IIkvmReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method) - { - return _impl.GetOrCreateMethodSymbol(method); + if (method.DeclaringType is { } dt) + return ResolveTypeSymbol(dt).GetOrCreateMethodSymbol(method); + else + return _methodTable.GetOrCreateMethodSymbol(method); } /// public IIkvmReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) { - return _impl.GetOrCreateFieldSymbol(field); - } - - /// - public IIkvmReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field) - { - return _impl.GetOrCreateFieldSymbol(field); + if (field.DeclaringType is { } dt) + return ResolveTypeSymbol(dt).GetOrCreateFieldSymbol(field); + else + return _fieldTable.GetOrCreateFieldSymbol(field); } /// public IIkvmReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) { - return _impl.GetOrCreatePropertySymbol(property); - } - - /// - public IIkvmReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property) - { - return _impl.GetOrCreatePropertySymbol(property); + return ResolveTypeSymbol(property.DeclaringType).GetOrCreatePropertySymbol(property); } /// public IIkvmReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) { - return _impl.GetOrCreateEventSymbol(@event); - } - - /// - public IIkvmReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event) - { - return _impl.GetOrCreateEventSymbol(@event); + return ResolveTypeSymbol(@event.DeclaringType).GetOrCreateEventSymbol(@event); } /// public IIkvmReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) { - return _impl.GetOrCreateParameterSymbol(parameter); + return ResolveMemberSymbol(parameter.Member) switch + { + IIkvmReflectionMethodBaseSymbol method => method.GetOrCreateParameterSymbol(parameter), + IIkvmReflectionPropertySymbol property => property.GetOrCreateParameterSymbol(parameter), + _ => throw new InvalidOperationException(), + }; } - /// - public IIkvmReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter) - { - return _impl.GetOrCreateParameterSymbol(parameter); - } + #endregion } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblyMetadata.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleTable.cs similarity index 59% rename from src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblyMetadata.cs rename to src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleTable.cs index 11dfb7115..bb0407174 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblyMetadata.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleTable.cs @@ -11,30 +11,31 @@ namespace IKVM.CoreLib.Symbols.IkvmReflection { - struct IkvmReflectionAssemblyMetadata + struct IkvmReflectionModuleTable { - readonly IIkvmReflectionAssemblySymbol _symbol; + readonly IkvmReflectionSymbolContext _context; + readonly IIkvmReflectionAssemblySymbol _assembly; - IndexRangeDictionary _moduleSymbols = new(initialCapacity: 1, maxCapacity: 32); + IndexRangeDictionary _moduleSymbols = new(); ReaderWriterLockSlim? _moduleLock; /// /// Initializes a new instance. /// - /// + /// /// - public IkvmReflectionAssemblyMetadata(IIkvmReflectionAssemblySymbol symbol) + public IkvmReflectionModuleTable(IkvmReflectionSymbolContext context, IIkvmReflectionAssemblySymbol assembly) { - _symbol = symbol ?? throw new ArgumentNullException(nameof(symbol)); + _context = context ?? throw new ArgumentNullException(nameof(context)); + _assembly = assembly ?? throw new ArgumentNullException(nameof(assembly)); } /// - /// Gets or creates the cached for the module. + /// Gets or creates the cached for the module. /// /// /// - /// public IIkvmReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) { if (module is null) @@ -50,14 +51,24 @@ public IIkvmReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) if (_moduleSymbols[row] == null) using (_moduleLock.CreateWriteLock()) if (module is ModuleBuilder builder) - return _moduleSymbols[row] = new IkvmReflectionModuleSymbolBuilder(_symbol.Context, _symbol, builder); + return _moduleSymbols[row] = new IkvmReflectionModuleSymbolBuilder(_context, _assembly, builder); else - return _moduleSymbols[row] = new IkvmReflectionModuleSymbol(_symbol.Context, _symbol, module); + return _moduleSymbols[row] = new IkvmReflectionModuleSymbol(_context, _assembly, module); else return _moduleSymbols[row] ?? throw new InvalidOperationException(); } } + /// + /// Gets or creates the cached for the module. + /// + /// + /// + public IIkvmReflectionModuleSymbolBuilder GetOrCreateModuleSymbol(ModuleBuilder module) + { + return (IIkvmReflectionModuleSymbolBuilder)GetOrCreateModuleSymbol((Module)module); + } + } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterSymbol.cs index 58440f6c3..d23d83939 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterSymbol.cs @@ -10,7 +10,7 @@ class IkvmReflectionParameterSymbol : IkvmReflectionSymbol, IIkvmReflectionParam { readonly IIkvmReflectionModuleSymbol _resolvingModule; - readonly IIkvmReflectionMethodBaseSymbol _resolvingMethod; + readonly IIkvmReflectionMemberSymbol _resolvingMember; readonly ParameterInfo _parameter; /// @@ -18,13 +18,13 @@ class IkvmReflectionParameterSymbol : IkvmReflectionSymbol, IIkvmReflectionParam /// /// /// - /// + /// /// - public IkvmReflectionParameterSymbol(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol resolvingModule, IIkvmReflectionMethodBaseSymbol resolvingMethod, ParameterInfo parameter) : + public IkvmReflectionParameterSymbol(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol resolvingModule, IIkvmReflectionMemberSymbol? resolvingMember, ParameterInfo parameter) : base(context) { _resolvingModule = resolvingModule ?? throw new ArgumentNullException(nameof(resolvingModule)); - _resolvingMethod = resolvingMethod ?? throw new ArgumentNullException(nameof(resolvingMethod)); + _resolvingMember = resolvingMember ?? throw new ArgumentNullException(nameof(resolvingMember)); _parameter = parameter ?? throw new ArgumentNullException(nameof(parameter)); } @@ -32,7 +32,7 @@ public IkvmReflectionParameterSymbol(IkvmReflectionSymbolContext context, IIkvmR public IIkvmReflectionModuleSymbol ResolvingModule => _resolvingModule; /// - public IIkvmReflectionMethodBaseSymbol ResolvingMethod => _resolvingMethod; + public IIkvmReflectionMemberSymbol ResolvingMember => _resolvingMember; /// public ParameterInfo UnderlyingParameter => _parameter; diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterTable.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterTable.cs new file mode 100644 index 000000000..452c861a4 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterTable.cs @@ -0,0 +1,94 @@ +using System; +using System.Threading; + +using IKVM.CoreLib.Collections; +using IKVM.CoreLib.Symbols.IkvmReflection.Emit; +using IKVM.CoreLib.Threading; +using IKVM.Reflection; +using IKVM.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + struct IkvmReflectionParameterTable + { + + readonly IkvmReflectionSymbolContext _context; + readonly IIkvmReflectionModuleSymbol _module; + readonly IIkvmReflectionMemberSymbol _member; + + IndexRangeDictionary _table = new(); + ReaderWriterLockSlim? _lock; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + /// + public IkvmReflectionParameterTable(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol module, IIkvmReflectionMemberSymbol member) + { + _context = context ?? throw new ArgumentNullException(nameof(context)); + _module = module ?? throw new ArgumentNullException(nameof(module)); + _member = member ?? throw new ArgumentNullException(nameof(member)); + } + + /// + /// Gets or creates the cached for the type by method. + /// + /// + /// + public IIkvmReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) + { + if (parameter is null) + throw new ArgumentNullException(nameof(parameter)); + if (parameter.Member.Module.MetadataToken != _module.MetadataToken) + throw new ArgumentException(nameof(parameter)); + + // create lock on demand + if (_lock == null) + Interlocked.CompareExchange(ref _lock, new ReaderWriterLockSlim(), null); + + using (_lock.CreateUpgradeableReadLock()) + { + var position = parameter.Position; + if (_table[position] == null) + using (_lock.CreateWriteLock()) + return _table[position] ??= new IkvmReflectionParameterSymbol(_context, _module, _member, parameter); + + return _table[position] ?? throw new InvalidOperationException(); + } + } + + /// + /// Gets or creates the cached for the type by method. + /// + /// + /// + public IIkvmReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter) + { + if (parameter is null) + throw new ArgumentNullException(nameof(parameter)); + if (parameter.Module.MetadataToken != _module.MetadataToken) + throw new ArgumentException(nameof(parameter)); + + // create lock on demand + if (_lock == null) + Interlocked.CompareExchange(ref _lock, new ReaderWriterLockSlim(), null); + + using (_lock.CreateUpgradeableReadLock()) + { + var position = parameter.Position; + if (_table[position] == null) + using (_lock.CreateWriteLock()) + return (IIkvmReflectionParameterSymbolBuilder)(_table[position] ??= new IkvmReflectionParameterSymbolBuilder(_context, _module, (IIkvmReflectionMethodBaseSymbol)_member, parameter)); + + return (IIkvmReflectionParameterSymbolBuilder?)_table[position] ?? throw new InvalidOperationException(); + } + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionPropertySymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionPropertySymbol.cs index 96b8eb358..6a6031854 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionPropertySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionPropertySymbol.cs @@ -10,6 +10,8 @@ class IkvmReflectionPropertySymbol : IkvmReflectionMemberSymbol, IIkvmReflection readonly PropertyInfo _property; + IkvmReflectionParameterTable _parameterTable; + /// /// Initializes a new instance. /// @@ -21,6 +23,7 @@ public IkvmReflectionPropertySymbol(IkvmReflectionSymbolContext context, IIkvmRe base(context, module, type) { _property = property ?? throw new ArgumentNullException(nameof(property)); + _parameterTable = new IkvmReflectionParameterTable(context, module, this); } /// @@ -29,6 +32,18 @@ public IkvmReflectionPropertySymbol(IkvmReflectionSymbolContext context, IIkvmRe /// public override MemberInfo UnderlyingMember => UnderlyingProperty; + #region IIkvmReflectionPropertySymbol + + /// + public IIkvmReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) + { + return _parameterTable.GetOrCreateParameterSymbol(parameter); + } + + #endregion + + #region IPropertySymbol + /// public System.Reflection.PropertyAttributes Attributes => (System.Reflection.PropertyAttributes)UnderlyingProperty.Attributes; @@ -116,6 +131,8 @@ public ITypeSymbol[] GetRequiredCustomModifiers() return ResolveTypeSymbols(UnderlyingProperty.GetRequiredCustomModifiers()); } + #endregion + } } \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionPropertyTable.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionPropertyTable.cs new file mode 100644 index 000000000..6718e0898 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionPropertyTable.cs @@ -0,0 +1,80 @@ +using System; +using System.Reflection.Metadata.Ecma335; +using System.Threading; + +using IKVM.CoreLib.Collections; +using IKVM.CoreLib.Symbols.IkvmReflection.Emit; +using IKVM.CoreLib.Threading; +using IKVM.Reflection; +using IKVM.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + struct IkvmReflectionPropertyTable + { + + readonly IkvmReflectionSymbolContext _context; + readonly IIkvmReflectionModuleSymbol _module; + readonly IIkvmReflectionTypeSymbol _type; + + IndexRangeDictionary _table = new(); + ReaderWriterLockSlim? _lock; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + public IkvmReflectionPropertyTable(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol module, IIkvmReflectionTypeSymbol type) + { + _context = context ?? throw new ArgumentNullException(nameof(context)); + _module = module ?? throw new ArgumentNullException(nameof(module)); + _type = type ?? throw new ArgumentNullException(nameof(type)); + } + + /// + /// Gets or creates the cached for the type by property. + /// + /// + /// + public IIkvmReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) + { + if (property is null) + throw new ArgumentNullException(nameof(property)); + if (property.Module.MetadataToken != _module.MetadataToken) + throw new ArgumentException(nameof(property)); + + // create lock on demand + if (_lock == null) + Interlocked.CompareExchange(ref _lock, new ReaderWriterLockSlim(), null); + + using (_lock.CreateUpgradeableReadLock()) + { + var row = MetadataTokens.GetRowNumber(MetadataTokens.PropertyDefinitionHandle(property.MetadataToken)); + if (_table[row] == null) + using (_lock.CreateWriteLock()) + if (property is PropertyBuilder builder) + return _table[row] ??= new IkvmReflectionPropertySymbolBuilder(_context, (IIkvmReflectionModuleSymbolBuilder)_module, (IIkvmReflectionTypeSymbolBuilder)_type, builder); + else + return _table[row] ??= new IkvmReflectionPropertySymbol(_context, _module, _type, property); + else + return _table[row] ?? throw new InvalidOperationException(); + } + } + + /// + /// Gets or creates the cached for the type by property. + /// + /// + /// + public IIkvmReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property) + { + return (IIkvmReflectionPropertySymbolBuilder)GetOrCreatePropertySymbol((PropertyInfo)property); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs index 393b98db4..7d1eb10de 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs @@ -430,11 +430,7 @@ public virtual IIkvmReflectionParameterSymbolBuilder ResolveParameterSymbol(Para return a; } - /// - /// Transforms a custom set of custom attribute data records to a symbol record. - /// - /// - /// + /// public virtual IEnumerable ResolveCustomAttributes(IEnumerable attributes) { if (attributes is null) @@ -448,11 +444,7 @@ public virtual IEnumerable ResolveCustomAttributes(IEnumerable< return a.ToArray(); } - /// - /// Transforms a custom attribute data record to a symbol record. - /// - /// - /// + /// [return: NotNullIfNotNull(nameof(customAttributeData))] public virtual CustomAttribute? ResolveCustomAttribute(CustomAttributeData? customAttributeData) { @@ -466,11 +458,7 @@ public virtual IEnumerable ResolveCustomAttributes(IEnumerable< ResolveCustomAttributeNamedArguments(customAttributeData.NamedArguments)); } - /// - /// Transforms a list of values into symbols. - /// - /// - /// + /// public ImmutableArray ResolveCustomAttributeTypedArguments(IList args) { if (args is null) @@ -485,11 +473,7 @@ public ImmutableArray ResolveCustomAttributeTypedA return a.ToImmutableArray(); } - /// - /// Transforms a values into a symbol. - /// - /// - /// + /// public CustomAttributeTypedArgument ResolveCustomAttributeTypedArgument(IKVM.Reflection.CustomAttributeTypedArgument arg) { return new CustomAttributeTypedArgument( @@ -497,11 +481,7 @@ public CustomAttributeTypedArgument ResolveCustomAttributeTypedArgument(IKVM.Ref ResolveCustomAttributeTypedValue(arg.Value)); } - /// - /// Transforms the type as appropriate. - /// - /// - /// + /// public object? ResolveCustomAttributeTypedValue(object? value) { return value switch @@ -511,11 +491,7 @@ public CustomAttributeTypedArgument ResolveCustomAttributeTypedArgument(IKVM.Ref }; } - /// - /// Transforms a list of values into symbols. - /// - /// - /// + /// public ImmutableArray ResolveCustomAttributeNamedArguments(IList args) { if (args is null) @@ -530,11 +506,7 @@ public ImmutableArray ResolveCustomAttributeNamedA return ImmutableArray.Create(a); } - /// - /// Transforms a values into a symbol. - /// - /// - /// + /// public CustomAttributeNamedArgument ResolveCustomAttributeNamedArgument(IKVM.Reflection.CustomAttributeNamedArgument arg) { return new CustomAttributeNamedArgument( @@ -544,6 +516,15 @@ public CustomAttributeNamedArgument ResolveCustomAttributeNamedArgument(IKVM.Ref ResolveCustomAttributeTypedArgument(arg.TypedValue)); } + /// + public InterfaceMapping ResolveInterfaceMapping(IKVM.Reflection.InterfaceMapping mapping) + { + return new InterfaceMapping( + ResolveMethodSymbols(mapping.InterfaceMethods), + ResolveTypeSymbol(mapping.InterfaceType), + ResolveMethodSymbols(mapping.TargetMethods), + ResolveTypeSymbol(mapping.TargetType)); + } } } \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolContext.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolContext.cs index 8268ab17b..d623f2d1c 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolContext.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolContext.cs @@ -18,15 +18,45 @@ namespace IKVM.CoreLib.Symbols.IkvmReflection class IkvmReflectionSymbolContext : ISymbolContext { + readonly Universe _universe; readonly ConcurrentDictionary> _symbolByName = new(); readonly ConditionalWeakTable _symbolByAssembly = new(); /// /// Initializes a new instance. /// - public IkvmReflectionSymbolContext() + /// + public IkvmReflectionSymbolContext(Universe universe) { + _universe = universe ?? throw new ArgumentNullException(nameof(universe)); + } + + /// + /// Defines a dynamic assembly that has the specified name and access rights. + /// + /// + /// + /// + public IAssemblySymbolBuilder DefineAssembly(System.Reflection.AssemblyName name, System.Reflection.Emit.AssemblyBuilderAccess access) + { + if (name is null) + throw new ArgumentNullException(nameof(name)); + return GetOrCreateAssemblySymbol(_universe.DefineDynamicAssembly(name.Unpack(), (AssemblyBuilderAccess)access)); + } + + /// + /// Defines a dynamic assembly that has the specified name and access rights. + /// + /// + /// + /// + public IAssemblySymbolBuilder DefineAssembly(System.Reflection.AssemblyName name, System.Reflection.Emit.AssemblyBuilderAccess access, ICustomAttributeBuilder[]? assemblyAttributes) + { + if (name is null) + throw new ArgumentNullException(nameof(name)); + + return GetOrCreateAssemblySymbol(_universe.DefineDynamicAssembly(name.Unpack(), (AssemblyBuilderAccess)access, assemblyAttributes?.Unpack())); } /// @@ -110,7 +140,7 @@ public IIkvmReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) /// public IIkvmReflectionModuleSymbolBuilder GetOrCreateModuleSymbol(ModuleBuilder module) { - return GetOrCreateAssemblySymbol(module.Assembly).GetOrCreateModuleSymbol(module); + return GetOrCreateAssemblySymbol((AssemblyBuilder)module.Assembly).GetOrCreateModuleSymbol(module); } /// @@ -133,7 +163,20 @@ public IIkvmReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) /// public IIkvmReflectionTypeSymbolBuilder GetOrCreateTypeSymbol(TypeBuilder type) { - return GetOrCreateModuleSymbol(type.Module).GetOrCreateTypeSymbol(type); + return GetOrCreateModuleSymbol((ModuleBuilder)type.Module).GetOrCreateTypeSymbol(type); + } + + /// + /// Gets or creates a for the specified . + /// + /// + /// + public IIkvmReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method) + { + if (method is ConstructorInfo ctor) + return GetOrCreateConstructorSymbol(ctor); + else + return GetOrCreateMethodSymbol((MethodInfo)method); } /// @@ -156,7 +199,7 @@ public IIkvmReflectionConstructorSymbol GetOrCreateConstructorSymbol(Constructor /// public IIkvmReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor) { - return GetOrCreateModuleSymbol(ctor.Module).GetOrCreateConstructorSymbol(ctor); + return GetOrCreateModuleSymbol((ModuleBuilder)ctor.Module).GetOrCreateConstructorSymbol(ctor); } /// @@ -179,7 +222,7 @@ public IIkvmReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) /// public IIkvmReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method) { - return GetOrCreateModuleSymbol(method.Module).GetOrCreateMethodSymbol(method); + return GetOrCreateModuleSymbol((ModuleBuilder)method.Module).GetOrCreateMethodSymbol(method); } /// @@ -199,7 +242,7 @@ public IIkvmReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo p /// public IIkvmReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter) { - return GetOrCreateModuleSymbol(parameter.Module).GetOrCreateParameterSymbol(parameter); + return GetOrCreateModuleSymbol((ModuleBuilder)parameter.Module).GetOrCreateParameterSymbol(parameter); } /// @@ -222,7 +265,7 @@ public IIkvmReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) /// public IIkvmReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field) { - return GetOrCreateModuleSymbol(field.Module).GetOrCreateFieldSymbol(field); + return GetOrCreateModuleSymbol((ModuleBuilder)field.Module).GetOrCreateFieldSymbol(field); } /// @@ -245,7 +288,7 @@ public IIkvmReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo prop /// public IIkvmReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property) { - return GetOrCreateModuleSymbol(property.Module).GetOrCreatePropertySymbol(property); + return GetOrCreateModuleSymbol((ModuleBuilder)property.Module).GetOrCreatePropertySymbol(property); } /// @@ -255,7 +298,10 @@ public IIkvmReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBu /// public IIkvmReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) { - return GetOrCreateModuleSymbol(@event.Module).GetOrCreateEventSymbol(@event); + if (@event is EventBuilder builder) + return GetOrCreateEventSymbol(builder); + else + return GetOrCreateModuleSymbol(@event.Module).GetOrCreateEventSymbol(@event); } /// @@ -265,7 +311,17 @@ public IIkvmReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) /// public IIkvmReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event) { - return GetOrCreateModuleSymbol(@event.Module).GetOrCreateEventSymbol(@event); + return GetOrCreateModuleSymbol((ModuleBuilder)@event.Module).GetOrCreateEventSymbol(@event); + } + + /// + /// Gets or creates a for the specified . + /// + /// + /// + public IIkvmReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeParameterSymbol(GenericTypeParameterBuilder genericTypeParameter) + { + return GetOrCreateModuleSymbol((ModuleBuilder)genericTypeParameter.Module).GetOrCreateGenericTypeParameterSymbol(genericTypeParameter); } /// diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeImpl.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeImpl.cs deleted file mode 100644 index e3b7d7fa9..000000000 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeImpl.cs +++ /dev/null @@ -1,587 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Threading; - -using IKVM.Reflection; - -using Type = IKVM.Reflection.Type; - -namespace IKVM.CoreLib.Symbols.IkvmReflection -{ - - /// - /// Provides common operations against a . - /// - struct IkvmReflectionTypeImpl - { - - readonly IIkvmReflectionTypeSymbol _symbol; - - IkvmReflectionTypeSymbol?[]? _asArray; - IkvmReflectionTypeSymbol? _asSZArray; - IkvmReflectionTypeSymbol? _asPointer; - IkvmReflectionTypeSymbol? _asByRef; - ConcurrentDictionary? _genericTypeSymbols; - - /// - /// Initializes a new instance. - /// - /// - /// - public IkvmReflectionTypeImpl(IIkvmReflectionTypeSymbol symbol) - { - _symbol = symbol ?? throw new ArgumentNullException(nameof(symbol)); - } - - /// - /// Gets or creates the cached for the generic parameter type. - /// - /// - /// - public IIkvmReflectionTypeSymbol GetOrCreateGenericTypeSymbol(ITypeSymbol[] genericTypeArguments) - { - if (genericTypeArguments is null) - throw new ArgumentNullException(nameof(genericTypeArguments)); - - if (_symbol.UnderlyingType.IsGenericTypeDefinition == false) - throw new InvalidOperationException(); - - if (_genericTypeSymbols == null) - Interlocked.CompareExchange(ref _genericTypeSymbols, new ConcurrentDictionary(TypeSymbolListEqualityComparer.Instance), null); - - var __symbol = _symbol; - return _genericTypeSymbols.GetOrAdd(genericTypeArguments, _ => new IkvmReflectionTypeSymbol(__symbol.Context, __symbol.ResolvingModule, __symbol.UnderlyingType.MakeGenericType(genericTypeArguments.Unpack()))); - } - - /// - public readonly IAssemblySymbol Assembly => _symbol.ResolveAssemblySymbol(_symbol.UnderlyingType.Assembly); - - /// - public readonly string? AssemblyQualifiedName => _symbol.UnderlyingType.AssemblyQualifiedName; - - /// - public readonly System.Reflection.TypeAttributes Attributes => (System.Reflection.TypeAttributes)_symbol.UnderlyingType.Attributes; - - /// - public readonly ITypeSymbol? BaseType => _symbol.ResolveTypeSymbol(_symbol.UnderlyingType.BaseType); - - /// - public readonly bool ContainsGenericParameters => _symbol.UnderlyingType.ContainsGenericParameters; - - /// - public readonly IMethodBaseSymbol? DeclaringMethod => _symbol.ResolveMethodBaseSymbol(_symbol.UnderlyingType.DeclaringMethod); - - /// - public readonly string? FullName => _symbol.UnderlyingType.FullName; - - /// - public readonly string? Namespace => _symbol.UnderlyingType.Namespace; - - /// - public readonly System.Reflection.GenericParameterAttributes GenericParameterAttributes => (System.Reflection.GenericParameterAttributes)_symbol.UnderlyingType.GenericParameterAttributes; - - /// - public readonly int GenericParameterPosition => _symbol.UnderlyingType.GenericParameterPosition; - - /// - public readonly ITypeSymbol[] GenericTypeArguments => _symbol.ResolveTypeSymbols(_symbol.UnderlyingType.GenericTypeArguments); - - /// - public readonly bool HasElementType => _symbol.UnderlyingType.HasElementType; - - /// - public readonly TypeCode TypeCode => Type.GetTypeCode(_symbol.UnderlyingType); - - /// - public readonly bool IsAbstract => _symbol.UnderlyingType.IsAbstract; - - /// - public readonly bool IsSZArray => _symbol.UnderlyingType.IsSZArray; - - /// - public readonly bool IsArray => _symbol.UnderlyingType.IsArray; - - /// - public readonly bool IsAutoLayout => _symbol.UnderlyingType.IsAutoLayout; - - /// - public readonly bool IsExplicitLayout => _symbol.UnderlyingType.IsExplicitLayout; - - /// - public readonly bool IsByRef => _symbol.UnderlyingType.IsByRef; - - /// - public readonly bool IsClass => _symbol.UnderlyingType.IsClass; - - /// - public readonly bool IsEnum => _symbol.UnderlyingType.IsEnum; - - /// - public readonly bool IsInterface => _symbol.UnderlyingType.IsInterface; - - /// - public readonly bool IsConstructedGenericType => _symbol.UnderlyingType.IsConstructedGenericType; - - /// - public readonly bool IsGenericParameter => _symbol.UnderlyingType.IsGenericParameter; - - /// - public readonly bool IsGenericType => _symbol.UnderlyingType.IsGenericType; - - /// - public readonly bool IsGenericTypeDefinition => _symbol.UnderlyingType.IsGenericTypeDefinition; - - /// - public readonly bool IsLayoutSequential => _symbol.UnderlyingType.IsLayoutSequential; - - /// - public readonly bool IsNested => _symbol.UnderlyingType.IsNested; - - /// - public readonly bool IsNestedAssembly => _symbol.UnderlyingType.IsNestedAssembly; - - /// - public readonly bool IsNestedFamANDAssem => _symbol.UnderlyingType.IsNestedFamANDAssem; - - /// - public readonly bool IsNestedFamORAssem => _symbol.UnderlyingType.IsNestedFamORAssem; - - /// - public readonly bool IsNestedFamily => _symbol.UnderlyingType.IsNestedFamily; - - /// - public readonly bool IsNestedPrivate => _symbol.UnderlyingType.IsNestedPrivate; - - /// - public readonly bool IsNestedPublic => _symbol.UnderlyingType.IsNestedPublic; - - /// - public readonly bool IsNotPublic => _symbol.UnderlyingType.IsNotPublic; - - /// - public readonly bool IsPointer => _symbol.UnderlyingType.IsPointer; - - /// - public readonly bool IsFunctionPointer => _symbol.UnderlyingType.IsFunctionPointer; - - /// - public readonly bool IsUnmanagedFunctionPointer => _symbol.UnderlyingType.IsUnmanagedFunctionPointer; - - /// - public readonly bool IsPrimitive => _symbol.UnderlyingType.IsPrimitive; - - /// - public readonly bool IsPublic => _symbol.UnderlyingType.IsPublic; - - /// - public readonly bool IsSealed => _symbol.UnderlyingType.IsSealed; - - /// - public readonly bool IsSerializable => _symbol.UnderlyingType.IsSerializable; - - /// - public readonly bool IsValueType => _symbol.UnderlyingType.IsValueType; - - /// - public readonly bool IsVisible => _symbol.UnderlyingType.IsVisible; - - /// - public readonly bool IsSignatureType => throw new NotImplementedException(); - - /// - public readonly bool IsSpecialName => _symbol.UnderlyingType.IsSpecialName; - - /// - public readonly IConstructorSymbol? TypeInitializer => _symbol.ResolveConstructorSymbol(_symbol.UnderlyingType.TypeInitializer); - - /// - public readonly int GetArrayRank() - { - return _symbol.UnderlyingType.GetArrayRank(); - } - - /// - public readonly IConstructorSymbol? GetConstructor(System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) - { - return _symbol.ResolveConstructorSymbol(_symbol.UnderlyingType.GetConstructor((BindingFlags)bindingAttr, binder: null, types.Unpack(), modifiers: null)); - } - - /// - public readonly IConstructorSymbol? GetConstructor(ITypeSymbol[] types) - { - return _symbol.ResolveConstructorSymbol(_symbol.UnderlyingType.GetConstructor(types.Unpack())); - } - - /// - public readonly IConstructorSymbol[] GetConstructors() - { - return _symbol.ResolveConstructorSymbols(_symbol.UnderlyingType.GetConstructors()); - } - - /// - public readonly IConstructorSymbol[] GetConstructors(System.Reflection.BindingFlags bindingAttr) - { - return _symbol.ResolveConstructorSymbols(_symbol.UnderlyingType.GetConstructors((BindingFlags)bindingAttr)); - } - - /// - public readonly IMemberSymbol[] GetDefaultMembers() - { - return _symbol.ResolveMemberSymbols(_symbol.UnderlyingType.GetDefaultMembers()); - } - - /// - public readonly ITypeSymbol? GetElementType() - { - return _symbol.ResolveTypeSymbol(_symbol.UnderlyingType.GetElementType()); - } - - /// - public readonly string? GetEnumName(object value) - { - return _symbol.UnderlyingType.GetEnumName(value); - } - - /// - public readonly string[] GetEnumNames() - { - return _symbol.UnderlyingType.GetEnumNames(); - } - - /// - public readonly ITypeSymbol GetEnumUnderlyingType() - { - return _symbol.ResolveTypeSymbol(_symbol.UnderlyingType.GetEnumUnderlyingType()); - } - - /// - public readonly Array GetEnumValues() - { - return _symbol.UnderlyingType.GetEnumValues(); - } - - /// - public readonly IEventSymbol? GetEvent(string name) - { - return _symbol.ResolveEventSymbol(_symbol.UnderlyingType.GetEvent(name)); - } - - /// - public readonly IEventSymbol? GetEvent(string name, System.Reflection.BindingFlags bindingAttr) - { - return _symbol.ResolveEventSymbol(_symbol.UnderlyingType.GetEvent(name, (BindingFlags)bindingAttr)); - } - - /// - public readonly IEventSymbol[] GetEvents() - { - return _symbol.ResolveEventSymbols(_symbol.UnderlyingType.GetEvents()); - } - - /// - public readonly IEventSymbol[] GetEvents(System.Reflection.BindingFlags bindingAttr) - { - return _symbol.ResolveEventSymbols(_symbol.UnderlyingType.GetEvents((BindingFlags)bindingAttr)); - } - - /// - public readonly IFieldSymbol? GetField(string name) - { - return _symbol.ResolveFieldSymbol(_symbol.UnderlyingType.GetField(name)); - } - - /// - public readonly IFieldSymbol? GetField(string name, System.Reflection.BindingFlags bindingAttr) - { - return _symbol.ResolveFieldSymbol(_symbol.UnderlyingType.GetField(name, (BindingFlags)bindingAttr)); - } - - /// - public readonly IFieldSymbol[] GetFields() - { - return _symbol.ResolveFieldSymbols(_symbol.UnderlyingType.GetFields()); - } - - /// - public readonly IFieldSymbol[] GetFields(System.Reflection.BindingFlags bindingAttr) - { - return _symbol.ResolveFieldSymbols(_symbol.UnderlyingType.GetFields((BindingFlags)bindingAttr)); - } - - /// - public readonly ITypeSymbol[] GetGenericArguments() - { - return _symbol.ResolveTypeSymbols(_symbol.UnderlyingType.GetGenericArguments()); - } - - /// - public readonly ITypeSymbol[] GetGenericParameterConstraints() - { - return _symbol.ResolveTypeSymbols(_symbol.UnderlyingType.GetGenericParameterConstraints()); - } - - /// - public readonly ITypeSymbol GetGenericTypeDefinition() - { - return _symbol.ResolveTypeSymbol(_symbol.UnderlyingType.GetGenericTypeDefinition()); - } - - /// - public readonly ITypeSymbol? GetInterface(string name) - { - return _symbol.ResolveTypeSymbol(_symbol.UnderlyingType.GetInterface(name)); - } - - /// - public readonly ITypeSymbol? GetInterface(string name, bool ignoreCase) - { - return _symbol.ResolveTypeSymbol(_symbol.UnderlyingType.GetInterface(name, ignoreCase)); - } - - /// - public readonly InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) - { - throw new NotImplementedException(); - } - - /// - public readonly ITypeSymbol[] GetInterfaces(bool inherit = true) - { - if (inherit) - return _symbol.ResolveTypeSymbols(_symbol.UnderlyingType.GetInterfaces()); - else - throw new NotImplementedException(); - } - - /// - public readonly IMemberSymbol[] GetMember(string name) - { - return _symbol.ResolveMemberSymbols(_symbol.UnderlyingType.GetMember(name)); - } - - /// - public readonly IMemberSymbol[] GetMember(string name, System.Reflection.BindingFlags bindingAttr) - { - return _symbol.ResolveMemberSymbols(_symbol.UnderlyingType.GetMember(name, (BindingFlags)bindingAttr)); - } - - /// - public readonly IMemberSymbol[] GetMember(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) - { - return _symbol.ResolveMemberSymbols(_symbol.UnderlyingType.GetMember(name, (MemberTypes)type, (BindingFlags)bindingAttr)); - } - - /// - public readonly IMemberSymbol[] GetMembers(System.Reflection.BindingFlags bindingAttr) - { - return _symbol.ResolveMemberSymbols(_symbol.UnderlyingType.GetMembers((BindingFlags)bindingAttr)); - } - - /// - public readonly IMemberSymbol[] GetMembers() - { - return _symbol.ResolveMemberSymbols(_symbol.UnderlyingType.GetMembers()); - } - - /// - public readonly IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr) - { - return _symbol.ResolveMethodSymbol(_symbol.UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr)); - } - - /// - public readonly IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) - { - return _symbol.ResolveMethodSymbol(_symbol.UnderlyingType.GetMethod(name, types.Unpack())); - } - - /// - public readonly IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) - { - return _symbol.ResolveMethodSymbol(_symbol.UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), null)); - } - - /// - public readonly IMethodSymbol? GetMethod(string name) - { - return _symbol.ResolveMethodSymbol(_symbol.UnderlyingType.GetMethod(name)); - } - - /// - public readonly IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) - { - return _symbol.ResolveMethodSymbol(_symbol.UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, (CallingConventions)callConvention, types.Unpack(), modifiers?.Unpack())); - } - - /// - public readonly IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) - { - throw new NotImplementedException(); - } - - /// - public readonly IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) - { - throw new NotImplementedException(); - } - - /// - public readonly IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) - { - return _symbol.ResolveMethodSymbol(_symbol.UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), modifiers?.Unpack())); - } - - /// - public readonly IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) - { - throw new NotImplementedException(); - } - - /// - public readonly IMethodSymbol[] GetMethods(System.Reflection.BindingFlags bindingAttr) - { - return _symbol.ResolveMethodSymbols(_symbol.UnderlyingType.GetMethods((BindingFlags)bindingAttr)); - } - - /// - public readonly IMethodSymbol[] GetMethods() - { - return _symbol.ResolveMethodSymbols(_symbol.UnderlyingType.GetMethods()); - } - - /// - public readonly ITypeSymbol? GetNestedType(string name) - { - return _symbol.ResolveTypeSymbol(_symbol.UnderlyingType.GetNestedType(name)); - } - - /// - public readonly ITypeSymbol? GetNestedType(string name, System.Reflection.BindingFlags bindingAttr) - { - return _symbol.ResolveTypeSymbol(_symbol.UnderlyingType.GetNestedType(name, (BindingFlags)bindingAttr)); - } - - /// - public readonly ITypeSymbol[] GetNestedTypes() - { - return _symbol.ResolveTypeSymbols(_symbol.UnderlyingType.GetNestedTypes()); - } - - /// - public readonly ITypeSymbol[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr) - { - return _symbol.ResolveTypeSymbols(_symbol.UnderlyingType.GetNestedTypes((BindingFlags)bindingAttr)); - } - - /// - public readonly IPropertySymbol[] GetProperties() - { - return _symbol.ResolvePropertySymbols(_symbol.UnderlyingType.GetProperties()); - } - - /// - public readonly IPropertySymbol[] GetProperties(System.Reflection.BindingFlags bindingAttr) - { - return _symbol.ResolvePropertySymbols(_symbol.UnderlyingType.GetProperties((BindingFlags)bindingAttr)); - } - - /// - public readonly IPropertySymbol? GetProperty(string name, ITypeSymbol[] types) - { - return _symbol.ResolvePropertySymbol(_symbol.UnderlyingType.GetProperty(name, types.Unpack())); - } - - /// - public readonly IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types) - { - return _symbol.ResolvePropertySymbol(_symbol.UnderlyingType.GetProperty(name, returnType?.Unpack(), types.Unpack())); - } - - /// - public readonly IPropertySymbol? GetProperty(string name, System.Reflection.BindingFlags bindingAttr) - { - return _symbol.ResolvePropertySymbol(_symbol.UnderlyingType.GetProperty(name, (BindingFlags)bindingAttr)); - } - - /// - public readonly IPropertySymbol? GetProperty(string name) - { - return _symbol.ResolvePropertySymbol(_symbol.UnderlyingType.GetProperty(name)); - } - - /// - public readonly IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) - { - return _symbol.ResolvePropertySymbol(_symbol.UnderlyingType.GetProperty(name, returnType?.Unpack())); - } - - /// - public readonly bool IsAssignableFrom(ITypeSymbol? c) - { - return _symbol.UnderlyingType.IsAssignableFrom(c?.Unpack()); - } - - /// - public readonly bool IsEnumDefined(object value) - { - return _symbol.UnderlyingType.IsEnumDefined(value); - } - - /// - public readonly bool IsSubclassOf(ITypeSymbol c) - { - return _symbol.UnderlyingType.IsSubclassOf(c.Unpack()); - } - - /// - public IIkvmReflectionTypeSymbol MakeArrayType() - { - if (_asSZArray == null) - Interlocked.CompareExchange(ref _asSZArray, new IkvmReflectionTypeSymbol(_symbol.Context, _symbol.ResolvingModule, _symbol.UnderlyingType.MakeArrayType()), null); - - return _asSZArray; - } - - /// - public IIkvmReflectionTypeSymbol MakeArrayType(int rank) - { - if (rank == 1) - return MakeArrayType(); - - if (_asArray == null) - Interlocked.CompareExchange(ref _asArray, new IkvmReflectionTypeSymbol?[32], null); - - ref var asArray = ref _asArray[rank]; - if (asArray == null) - Interlocked.CompareExchange(ref asArray, new IkvmReflectionTypeSymbol(_symbol.Context, _symbol.ResolvingModule, _symbol.UnderlyingType.MakeArrayType(rank)), null); - - return asArray; - } - - /// - public IIkvmReflectionTypeSymbol MakeByRefType() - { - if (_asByRef == null) - Interlocked.CompareExchange(ref _asByRef, new IkvmReflectionTypeSymbol(_symbol.Context, _symbol.ResolvingModule, _symbol.UnderlyingType.MakeByRefType()), null); - - return _asByRef; - } - - /// - public IIkvmReflectionTypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments) - { - return GetOrCreateGenericTypeSymbol(typeArguments); - } - - /// - public IIkvmReflectionTypeSymbol MakePointerType() - { - if (_asPointer == null) - Interlocked.CompareExchange(ref _asPointer, new IkvmReflectionTypeSymbol(_symbol.Context, _symbol.ResolvingModule, _symbol.UnderlyingType.MakePointerType()), null); - - return _asPointer; - } - - } - -} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSpecTable.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSpecTable.cs new file mode 100644 index 000000000..4a3de6e08 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSpecTable.cs @@ -0,0 +1,129 @@ +using System; +using System.Collections.Concurrent; +using System.Threading; + +using IKVM.CoreLib.Collections; +using IKVM.CoreLib.Threading; + +using Type = IKVM.Reflection.Type; + +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + struct IkvmReflectionTypeSpecTable + { + + readonly IkvmReflectionSymbolContext _context; + readonly IIkvmReflectionModuleSymbol _module; + readonly IIkvmReflectionTypeSymbol _elementType; + + IndexRangeDictionary _asArray; + ReaderWriterLockSlim? _asArrayLock; + IIkvmReflectionTypeSymbol? _asSZArray; + IIkvmReflectionTypeSymbol? _asPointer; + IIkvmReflectionTypeSymbol? _asByRef; + ConcurrentDictionary? _genericTypeSymbols; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + public IkvmReflectionTypeSpecTable(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol module, IIkvmReflectionTypeSymbol elementType) + { + _context = context ?? throw new ArgumentNullException(nameof(context)); + _module = module ?? throw new ArgumentNullException(nameof(module)); + _elementType = elementType ?? throw new ArgumentNullException(nameof(elementType)); + _asArray = new IndexRangeDictionary(); + } + + /// + /// Gets or creates a representing an Array of this type. + /// + /// + /// + /// + public IIkvmReflectionTypeSymbol GetOrCreateArrayTypeSymbol(int rank) + { + if (_asArrayLock == null) + Interlocked.CompareExchange(ref _asArrayLock, new(), null); + + using (_asArrayLock.CreateUpgradeableReadLock()) + { + if (_asArray[rank] == null) + using (_asArrayLock.CreateWriteLock()) + _asArray[rank] = new IkvmReflectionTypeSymbol(_context, _module, _elementType.UnderlyingType.MakeArrayType(rank)); + + return _asArray[rank] ?? throw new InvalidOperationException(); + } + } + + /// + /// Gets or creates a representing a SZArray of this type. + /// + /// + public IIkvmReflectionTypeSymbol GetOrCreateSZArrayTypeSymbol() + { + if (_asSZArray == null) + Interlocked.CompareExchange(ref _asSZArray, new IkvmReflectionTypeSymbol(_context, _module, _elementType.UnderlyingType.MakeArrayType()), null); + + return _asSZArray; + } + + /// + /// Gets or creates a representing a pointer of this type. + /// + /// + public IIkvmReflectionTypeSymbol GetOrCreatePointerTypeSymbol() + { + if (_asPointer == null) + Interlocked.CompareExchange(ref _asPointer, new IkvmReflectionTypeSymbol(_context, _module, _elementType.UnderlyingType.MakePointerType()), null); + + return _asPointer; + } + + /// + /// Gets or creates a representing a by-ref of this type. + /// + /// + public IIkvmReflectionTypeSymbol GetOrCreateByRefTypeSymbol() + { + if (_asByRef == null) + Interlocked.CompareExchange(ref _asByRef, new IkvmReflectionTypeSymbol(_context, _module, _elementType.UnderlyingType.MakePointerType()), null); + + return _asByRef; + } + + /// + /// Gets or creates a representing a specialized generic of this type. + /// + /// + /// + public IIkvmReflectionTypeSymbol GetOrCreateGenericTypeSymbol(Type[] genericTypeArguments) + { + if (genericTypeArguments is null) + throw new ArgumentNullException(nameof(genericTypeArguments)); + + if (_elementType.IsGenericTypeDefinition == false) + throw new InvalidOperationException(); + + if (_genericTypeSymbols == null) + Interlocked.CompareExchange(ref _genericTypeSymbols, new(TypeSymbolListEqualityComparer.Instance), null); + + return _genericTypeSymbols.GetOrAdd(_module.ResolveTypeSymbols(genericTypeArguments), CreateGenericTypeSymbol); + } + + /// + /// Creates a new representing a specialized generic of this type. + /// + /// + /// + readonly IIkvmReflectionTypeSymbol CreateGenericTypeSymbol(IIkvmReflectionTypeSymbol[] genericTypeArguments) + { + return new IkvmReflectionTypeSymbol(_context, _module, _elementType.UnderlyingType.MakeGenericType(genericTypeArguments.Unpack())); + } + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs index 99ef2c73c..cad0ca912 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs @@ -1,6 +1,8 @@ using System; using System.Diagnostics.CodeAnalysis; +using IKVM.Reflection; + using Type = IKVM.Reflection.Type; namespace IKVM.CoreLib.Symbols.IkvmReflection @@ -10,7 +12,13 @@ class IkvmReflectionTypeSymbol : IkvmReflectionMemberSymbol, IIkvmReflectionType { readonly Type _type; - IkvmReflectionTypeImpl _impl; + + IkvmReflectionMethodTable _methodTable; + IkvmReflectionFieldTable _fieldTable; + IkvmReflectionPropertyTable _propertyTable; + IkvmReflectionEventTable _eventTable; + IkvmReflectionGenericTypeParameterTable _genericTypeParameterTable; + IkvmReflectionTypeSpecTable _specTable; /// /// Initializes a new instance. @@ -22,7 +30,12 @@ public IkvmReflectionTypeSymbol(IkvmReflectionSymbolContext context, IIkvmReflec base(context, resolvingModule, null) { _type = type ?? throw new ArgumentNullException(nameof(type)); - _impl = new IkvmReflectionTypeImpl(this); + _methodTable = new IkvmReflectionMethodTable(context, resolvingModule, this); + _fieldTable = new IkvmReflectionFieldTable(context, resolvingModule, this); + _propertyTable = new IkvmReflectionPropertyTable(context, resolvingModule, this); + _eventTable = new IkvmReflectionEventTable(context, resolvingModule, this); + _genericTypeParameterTable = new IkvmReflectionGenericTypeParameterTable(context, resolvingModule, this); + _specTable = new IkvmReflectionTypeSpecTable(context, resolvingModule, this); } /// @@ -31,11 +44,85 @@ public IkvmReflectionTypeSymbol(IkvmReflectionSymbolContext context, IIkvmReflec /// public override IKVM.Reflection.MemberInfo UnderlyingMember => UnderlyingType; - /// - /// Resolves the symbol for the specified type. - /// - /// - /// + #region IIkvmReflectionTypeSymbol + + /// + public IIkvmReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) + { + return _methodTable.GetOrCreateConstructorSymbol(ctor); + } + + /// + public IIkvmReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method) + { + return _methodTable.GetOrCreateMethodBaseSymbol(method); + } + + /// + public IIkvmReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) + { + return _methodTable.GetOrCreateMethodSymbol(method); + } + + /// + public IIkvmReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) + { + return _fieldTable.GetOrCreateFieldSymbol(field); + } + + /// + public IIkvmReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) + { + return _propertyTable.GetOrCreatePropertySymbol(property); + } + + /// + public IIkvmReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) + { + return _eventTable.GetOrCreateEventSymbol(@event); + } + + /// + public IIkvmReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type genericType) + { + return _genericTypeParameterTable.GetOrCreateGenericTypeParameterSymbol(genericType); + } + + /// + public IIkvmReflectionTypeSymbol GetOrCreateSZArrayTypeSymbol() + { + return _specTable.GetOrCreateSZArrayTypeSymbol(); + } + + /// + public IIkvmReflectionTypeSymbol GetOrCreateArrayTypeSymbol(int rank) + { + return _specTable.GetOrCreateArrayTypeSymbol(rank); + } + + /// + public IIkvmReflectionTypeSymbol GetOrCreatePointerTypeSymbol() + { + return _specTable.GetOrCreatePointerTypeSymbol(); + } + + /// + public IIkvmReflectionTypeSymbol GetOrCreateByRefTypeSymbol() + { + return _specTable.GetOrCreateByRefTypeSymbol(); + } + + /// + public IIkvmReflectionTypeSymbol GetOrCreateGenericTypeSymbol(Type[] genericTypeDefinition) + { + return _specTable.GetOrCreateGenericTypeSymbol(genericTypeDefinition); + } + + #endregion + + #region IIkvmReflectionSymbol + + /// [return: NotNullIfNotNull(nameof(type))] public override IIkvmReflectionTypeSymbol? ResolveTypeSymbol(Type? type) { @@ -45,506 +132,518 @@ public IkvmReflectionTypeSymbol(IkvmReflectionSymbolContext context, IIkvmReflec return base.ResolveTypeSymbol(type); } + #endregion + #region ITypeSymbol /// - public System.Reflection.TypeAttributes Attributes => _impl.Attributes; + public IAssemblySymbol Assembly => ResolveAssemblySymbol(UnderlyingType.Assembly); /// - public IAssemblySymbol Assembly => _impl.Assembly; + public string? AssemblyQualifiedName => UnderlyingType.AssemblyQualifiedName; /// - public IMethodBaseSymbol? DeclaringMethod => _impl.DeclaringMethod; + public System.Reflection.TypeAttributes Attributes => (System.Reflection.TypeAttributes)UnderlyingType.Attributes; /// - public string? AssemblyQualifiedName => _impl.AssemblyQualifiedName; + public ITypeSymbol? BaseType => ResolveTypeSymbol(UnderlyingType.BaseType); /// - public string? FullName => _impl.FullName; + public bool ContainsGenericParameters => UnderlyingType.ContainsGenericParameters; /// - public string? Namespace => _impl.Namespace; + public IMethodBaseSymbol? DeclaringMethod => ResolveMethodBaseSymbol(UnderlyingType.DeclaringMethod); /// - public TypeCode TypeCode => _impl.TypeCode; + public string? FullName => UnderlyingType.FullName; /// - public ITypeSymbol? BaseType => _impl.BaseType; + public string? Namespace => UnderlyingType.Namespace; /// - public bool ContainsGenericParameters => _impl.ContainsGenericParameters; + public System.Reflection.GenericParameterAttributes GenericParameterAttributes => (System.Reflection.GenericParameterAttributes)UnderlyingType.GenericParameterAttributes; /// - public System.Reflection.GenericParameterAttributes GenericParameterAttributes => _impl.GenericParameterAttributes; + public int GenericParameterPosition => UnderlyingType.GenericParameterPosition; /// - public int GenericParameterPosition => _impl.GenericParameterPosition; + public ITypeSymbol[] GenericTypeArguments => ResolveTypeSymbols(UnderlyingType.GenericTypeArguments); /// - public ITypeSymbol[] GenericTypeArguments => _impl.GenericTypeArguments; + public bool HasElementType => UnderlyingType.HasElementType; /// - public bool IsConstructedGenericType => _impl.IsConstructedGenericType; + public TypeCode TypeCode => Type.GetTypeCode(UnderlyingType); /// - public bool IsGenericType => _impl.IsGenericType; + public bool IsAbstract => UnderlyingType.IsAbstract; /// - public bool IsGenericTypeDefinition => _impl.IsGenericTypeDefinition; + public bool IsSZArray => UnderlyingType.IsSZArray; /// - public bool IsGenericParameter => _impl.IsGenericParameter; + public bool IsArray => UnderlyingType.IsArray; /// - public bool IsAutoLayout => _impl.IsAutoLayout; + public bool IsAutoLayout => UnderlyingType.IsAutoLayout; /// - public bool IsExplicitLayout => _impl.IsExplicitLayout; + public bool IsExplicitLayout => UnderlyingType.IsExplicitLayout; /// - public bool IsLayoutSequential => _impl.IsLayoutSequential; + public bool IsByRef => UnderlyingType.IsByRef; /// - public bool HasElementType => _impl.HasElementType; + public bool IsClass => UnderlyingType.IsClass; /// - public bool IsClass => _impl.IsClass; + public bool IsEnum => UnderlyingType.IsEnum; /// - public bool IsValueType => _impl.IsValueType; + public bool IsInterface => UnderlyingType.IsInterface; /// - public bool IsInterface => _impl.IsInterface; + public bool IsConstructedGenericType => UnderlyingType.IsConstructedGenericType; /// - public bool IsPrimitive => _impl.IsPrimitive; + public bool IsGenericParameter => UnderlyingType.IsGenericParameter; /// - public bool IsSZArray => _impl.IsSZArray; + public bool IsGenericType => UnderlyingType.IsGenericType; /// - public bool IsArray => _impl.IsArray; + public bool IsGenericTypeDefinition => UnderlyingType.IsGenericTypeDefinition; /// - public bool IsEnum => _impl.IsEnum; + public bool IsLayoutSequential => UnderlyingType.IsLayoutSequential; /// - public bool IsPointer => _impl.IsPointer; + public bool IsNested => UnderlyingType.IsNested; /// - public bool IsFunctionPointer => _impl.IsFunctionPointer; + public bool IsNestedAssembly => UnderlyingType.IsNestedAssembly; /// - public bool IsUnmanagedFunctionPointer => _impl.IsUnmanagedFunctionPointer; + public bool IsNestedFamANDAssem => UnderlyingType.IsNestedFamANDAssem; /// - public bool IsByRef => _impl.IsByRef; + public bool IsNestedFamORAssem => UnderlyingType.IsNestedFamORAssem; /// - public bool IsAbstract => _impl.IsAbstract; + public bool IsNestedFamily => UnderlyingType.IsNestedFamily; /// - public bool IsSealed => _impl.IsSealed; + public bool IsNestedPrivate => UnderlyingType.IsNestedPrivate; /// - public bool IsVisible => _impl.IsVisible; + public bool IsNestedPublic => UnderlyingType.IsNestedPublic; /// - public bool IsPublic => _impl.IsPublic; + public bool IsNotPublic => UnderlyingType.IsNotPublic; /// - public bool IsNotPublic => _impl.IsNotPublic; + public bool IsPointer => UnderlyingType.IsPointer; /// - public bool IsNested => _impl.IsNested; + public bool IsFunctionPointer => UnderlyingType.IsFunctionPointer; /// - public bool IsNestedAssembly => _impl.IsNestedAssembly; + public bool IsUnmanagedFunctionPointer => UnderlyingType.IsUnmanagedFunctionPointer; /// - public bool IsNestedFamANDAssem => _impl.IsNestedFamANDAssem; + public bool IsPrimitive => UnderlyingType.IsPrimitive; /// - public bool IsNestedFamily => _impl.IsNestedFamily; + public bool IsPublic => UnderlyingType.IsPublic; /// - public bool IsNestedFamORAssem => _impl.IsNestedFamORAssem; + public bool IsSealed => UnderlyingType.IsSealed; /// - public bool IsNestedPrivate => _impl.IsNestedPrivate; + public bool IsSerializable => UnderlyingType.IsSerializable; /// - public bool IsNestedPublic => _impl.IsNestedPublic; + public bool IsValueType => UnderlyingType.IsValueType; /// - public bool IsSerializable => _impl.IsSerializable; + public bool IsVisible => UnderlyingType.IsVisible; /// - public bool IsSignatureType => _impl.IsSignatureType; + public bool IsSignatureType => throw new NotImplementedException(); /// - public bool IsSpecialName => _impl.IsSpecialName; + public bool IsSpecialName => UnderlyingType.IsSpecialName; /// - public IConstructorSymbol? TypeInitializer => throw new NotImplementedException(); + public IConstructorSymbol? TypeInitializer => ResolveConstructorSymbol(UnderlyingType.TypeInitializer); /// public int GetArrayRank() { - return _impl.GetArrayRank(); + return UnderlyingType.GetArrayRank(); } /// - public IMemberSymbol[] GetDefaultMembers() + public IConstructorSymbol? GetConstructor(System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) { - return _impl.GetDefaultMembers(); + return ResolveConstructorSymbol(UnderlyingType.GetConstructor((BindingFlags)bindingAttr, binder: null, types.Unpack(), modifiers: null)); } /// - public ITypeSymbol? GetElementType() + public IConstructorSymbol? GetConstructor(ITypeSymbol[] types) { - return _impl.GetElementType(); + return ResolveConstructorSymbol(UnderlyingType.GetConstructor(types.Unpack())); } /// - public string? GetEnumName(object value) + public IConstructorSymbol[] GetConstructors() { - return _impl.GetEnumName(value); + return ResolveConstructorSymbols(UnderlyingType.GetConstructors()); } /// - public string[] GetEnumNames() + public IConstructorSymbol[] GetConstructors(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetEnumNames(); + return ResolveConstructorSymbols(UnderlyingType.GetConstructors((BindingFlags)bindingAttr)); } /// - public ITypeSymbol GetEnumUnderlyingType() + public IMemberSymbol[] GetDefaultMembers() { - return _impl.GetEnumUnderlyingType(); + return ResolveMemberSymbols(UnderlyingType.GetDefaultMembers()); } /// - public ITypeSymbol[] GetGenericArguments() + public ITypeSymbol? GetElementType() { - return _impl.GetGenericArguments(); + return ResolveTypeSymbol(UnderlyingType.GetElementType()); } /// - public ITypeSymbol[] GetGenericParameterConstraints() + public string? GetEnumName(object value) { - return _impl.GetGenericParameterConstraints(); + return UnderlyingType.GetEnumName(value); } /// - public ITypeSymbol GetGenericTypeDefinition() + public string[] GetEnumNames() { - return _impl.GetGenericTypeDefinition(); + return UnderlyingType.GetEnumNames(); } /// - public ITypeSymbol? GetInterface(string name) + public ITypeSymbol GetEnumUnderlyingType() { - return _impl.GetInterface(name); + return ResolveTypeSymbol(UnderlyingType.GetEnumUnderlyingType()); } /// - public ITypeSymbol? GetInterface(string name, bool ignoreCase) + public Array GetEnumValues() { - return _impl.GetInterface(name, ignoreCase); + return UnderlyingType.GetEnumValues(); } /// - public ITypeSymbol[] GetInterfaces(bool inherit = true) + public IEventSymbol? GetEvent(string name) { - return _impl.GetInterfaces(inherit); + return ResolveEventSymbol(UnderlyingType.GetEvent(name)); } /// - public InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) + public IEventSymbol? GetEvent(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetInterfaceMap(interfaceType); + return ResolveEventSymbol(UnderlyingType.GetEvent(name, (BindingFlags)bindingAttr)); } /// - public IMemberSymbol[] GetMember(string name) + public IEventSymbol[] GetEvents() { - return _impl.GetMember(name); + return ResolveEventSymbols(UnderlyingType.GetEvents()); } /// - public IMemberSymbol[] GetMember(string name, System.Reflection.BindingFlags bindingAttr) + public IEventSymbol[] GetEvents(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMember(name, bindingAttr); + return ResolveEventSymbols(UnderlyingType.GetEvents((BindingFlags)bindingAttr)); } /// - public IMemberSymbol[] GetMember(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) + public IFieldSymbol? GetField(string name) { - return _impl.GetMember(name, type, bindingAttr); + return ResolveFieldSymbol(UnderlyingType.GetField(name)); } /// - public IMemberSymbol[] GetMembers() + public IFieldSymbol? GetField(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMembers(); + return ResolveFieldSymbol(UnderlyingType.GetField(name, (BindingFlags)bindingAttr)); } /// - public IMemberSymbol[] GetMembers(System.Reflection.BindingFlags bindingAttr) + public IFieldSymbol[] GetFields() { - return _impl.GetMembers(bindingAttr); + return ResolveFieldSymbols(UnderlyingType.GetFields()); } - public IConstructorSymbol? GetConstructor(ITypeSymbol[] types) + /// + public IFieldSymbol[] GetFields(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetConstructor(types); + return ResolveFieldSymbols(UnderlyingType.GetFields((BindingFlags)bindingAttr)); } /// - public IConstructorSymbol? GetConstructor(System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) + public ITypeSymbol[] GetGenericArguments() { - return _impl.GetConstructor(bindingAttr, types); + return ResolveTypeSymbols(UnderlyingType.GetGenericArguments()); } /// - public IConstructorSymbol[] GetConstructors() + public ITypeSymbol[] GetGenericParameterConstraints() { - return _impl.GetConstructors(); + return ResolveTypeSymbols(UnderlyingType.GetGenericParameterConstraints()); } /// - public IConstructorSymbol[] GetConstructors(System.Reflection.BindingFlags bindingAttr) + public ITypeSymbol GetGenericTypeDefinition() { - return _impl.GetConstructors(bindingAttr); + return ResolveTypeSymbol(UnderlyingType.GetGenericTypeDefinition()); } /// - public IFieldSymbol? GetField(string name) + public ITypeSymbol? GetInterface(string name) { - return _impl.GetField(name); + return ResolveTypeSymbol(UnderlyingType.GetInterface(name)); } /// - public IFieldSymbol? GetField(string name, System.Reflection.BindingFlags bindingAttr) + public ITypeSymbol? GetInterface(string name, bool ignoreCase) { - return _impl.GetField(name, bindingAttr); + return ResolveTypeSymbol(UnderlyingType.GetInterface(name, ignoreCase)); } /// - public IFieldSymbol[] GetFields() + public InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) { - return _impl.GetFields(); + return ResolveInterfaceMapping(UnderlyingType.GetInterfaceMap(interfaceType.Unpack())); } /// - public IFieldSymbol[] GetFields(System.Reflection.BindingFlags bindingAttr) + public ITypeSymbol[] GetInterfaces(bool inherit = true) { - return _impl.GetFields(bindingAttr); + if (inherit) + return ResolveTypeSymbols(UnderlyingType.GetInterfaces()); + else + throw new NotImplementedException(); } /// - public IMethodSymbol? GetMethod(string name) + public IMemberSymbol[] GetMember(string name) { - return _impl.GetMethod(name); + return ResolveMemberSymbols(UnderlyingType.GetMember(name)); } /// - public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) + public IMemberSymbol[] GetMember(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMethod(name, types); + return ResolveMemberSymbols(UnderlyingType.GetMember(name, (BindingFlags)bindingAttr)); } /// - public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr) + public IMemberSymbol[] GetMember(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMethod(name, bindingAttr); + return ResolveMemberSymbols(UnderlyingType.GetMember(name, (MemberTypes)type, (BindingFlags)bindingAttr)); } /// - public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) + public IMemberSymbol[] GetMembers(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMethod(name, bindingAttr, types); + return ResolveMemberSymbols(UnderlyingType.GetMembers((BindingFlags)bindingAttr)); } /// - public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + public IMemberSymbol[] GetMembers() { - return _impl.GetMethod(name, bindingAttr, callConvention, types, modifiers); + return ResolveMemberSymbols(UnderlyingType.GetMembers()); } /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMethod(name, genericParameterCount, bindingAttr, callConvention, types, modifiers); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr)); } /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) { - return _impl.GetMethod(name, genericParameterCount, bindingAttr, types, modifiers); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, types.Unpack())); } /// - public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) { - return _impl.GetMethod(name, bindingAttr, types, modifiers); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), null)); } /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name) { - return _impl.GetMethod(name, genericParameterCount, types, modifiers); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name)); } /// - public IMethodSymbol[] GetMethods() + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return _impl.GetMethods(); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, (CallingConventions)callConvention, types.Unpack(), modifiers?.Unpack())); } /// - public IMethodSymbol[] GetMethods(System.Reflection.BindingFlags bindingAttr) + public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return _impl.GetMethods(bindingAttr); + throw new NotImplementedException(); } /// - public IPropertySymbol? GetProperty(string name) + public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return _impl.GetProperty(name); + throw new NotImplementedException(); } /// - public IPropertySymbol? GetProperty(string name, System.Reflection.BindingFlags bindingAttr) + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return _impl.GetProperty(name, bindingAttr); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), modifiers?.Unpack())); } /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol[] types) + public IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return _impl.GetProperty(name, types); + throw new NotImplementedException(); } /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types) + public IMethodSymbol[] GetMethods(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetProperty(name, returnType, types); + return ResolveMethodSymbols(UnderlyingType.GetMethods((BindingFlags)bindingAttr)); } /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) + public IMethodSymbol[] GetMethods() { - return _impl.GetProperty(name, returnType); + return ResolveMethodSymbols(UnderlyingType.GetMethods()); } /// - public IPropertySymbol[] GetProperties() + public ITypeSymbol? GetNestedType(string name) { - return _impl.GetProperties(); + return ResolveTypeSymbol(UnderlyingType.GetNestedType(name)); } /// - public IPropertySymbol[] GetProperties(System.Reflection.BindingFlags bindingAttr) + public ITypeSymbol? GetNestedType(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetProperties(bindingAttr); + return ResolveTypeSymbol(UnderlyingType.GetNestedType(name, (BindingFlags)bindingAttr)); } /// - public IEventSymbol? GetEvent(string name) + public ITypeSymbol[] GetNestedTypes() { - return _impl.GetEvent(name); + return ResolveTypeSymbols(UnderlyingType.GetNestedTypes()); } /// - public IEventSymbol? GetEvent(string name, System.Reflection.BindingFlags bindingAttr) + public ITypeSymbol[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetEvent(name, bindingAttr); + return ResolveTypeSymbols(UnderlyingType.GetNestedTypes((BindingFlags)bindingAttr)); } /// - public IEventSymbol[] GetEvents() + public IPropertySymbol[] GetProperties() { - return _impl.GetEvents(); + return ResolvePropertySymbols(UnderlyingType.GetProperties()); } /// - public IEventSymbol[] GetEvents(System.Reflection.BindingFlags bindingAttr) + public IPropertySymbol[] GetProperties(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetEvents(bindingAttr); + return ResolvePropertySymbols(UnderlyingType.GetProperties((BindingFlags)bindingAttr)); } /// - public ITypeSymbol? GetNestedType(string name) + public IPropertySymbol? GetProperty(string name, ITypeSymbol[] types) { - return _impl.GetNestedType(name); + return ResolvePropertySymbol(UnderlyingType.GetProperty(name, types.Unpack())); } /// - public ITypeSymbol? GetNestedType(string name, System.Reflection.BindingFlags bindingAttr) + public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types) { - return _impl.GetNestedType(name, bindingAttr); + return ResolvePropertySymbol(UnderlyingType.GetProperty(name, returnType?.Unpack(), types.Unpack())); } /// - public ITypeSymbol[] GetNestedTypes() + public IPropertySymbol? GetProperty(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetNestedTypes(); + return ResolvePropertySymbol(UnderlyingType.GetProperty(name, (BindingFlags)bindingAttr)); } /// - public ITypeSymbol[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr) + public IPropertySymbol? GetProperty(string name) { - return _impl.GetNestedTypes(); + return ResolvePropertySymbol(UnderlyingType.GetProperty(name)); } /// - public bool IsAssignableFrom(ITypeSymbol? c) + public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) { - return _impl.IsAssignableFrom(c); + return ResolvePropertySymbol(UnderlyingType.GetProperty(name, returnType?.Unpack())); } /// - public bool IsSubclassOf(ITypeSymbol c) + public bool IsAssignableFrom(ITypeSymbol? c) { - return _impl.IsSubclassOf(c); + return UnderlyingType.IsAssignableFrom(c?.Unpack()); } /// public bool IsEnumDefined(object value) { - return _impl.IsEnumDefined(value); + return UnderlyingType.IsEnumDefined(value); + } + + /// + public bool IsSubclassOf(ITypeSymbol c) + { + return UnderlyingType.IsSubclassOf(c.Unpack()); } /// public ITypeSymbol MakeArrayType() { - return _impl.MakeArrayType(); + return ResolveTypeSymbol(UnderlyingType.MakeArrayType()); } /// public ITypeSymbol MakeArrayType(int rank) { - return _impl.MakeArrayType(rank); + return ResolveTypeSymbol(UnderlyingType.MakeArrayType(rank)); } /// - public ITypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments) + public ITypeSymbol MakeByRefType() { - return _impl.MakeGenericType(typeArguments); + return ResolveTypeSymbol(UnderlyingType.MakeByRefType()); } /// public ITypeSymbol MakePointerType() { - return _impl.MakePointerType(); + return ResolveTypeSymbol(UnderlyingType.MakePointerType()); } /// - public ITypeSymbol MakeByRefType() + public ITypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments) { - return _impl.MakeByRefType(); + return ResolveTypeSymbol(UnderlyingType.MakeGenericType(typeArguments.Unpack())); } #endregion diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeTable.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeTable.cs new file mode 100644 index 000000000..d089438c7 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeTable.cs @@ -0,0 +1,76 @@ +using System; +using System.Reflection.Metadata.Ecma335; +using System.Threading; + +using IKVM.CoreLib.Collections; +using IKVM.CoreLib.Symbols.IkvmReflection.Emit; +using IKVM.CoreLib.Threading; +using IKVM.Reflection.Emit; + +using Type = IKVM.Reflection.Type; + +namespace IKVM.CoreLib.Symbols.IkvmReflection +{ + + struct IkvmReflectionTypeTable + { + + readonly IkvmReflectionSymbolContext _context; + readonly IIkvmReflectionModuleSymbol _module; + readonly IIkvmReflectionTypeSymbol? _type; + + IndexRangeDictionary _table = new(); + ReaderWriterLockSlim? _lock; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + public IkvmReflectionTypeTable(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol module, IIkvmReflectionTypeSymbol? type) + { + _context = context ?? throw new ArgumentNullException(nameof(context)); + _module = module ?? throw new ArgumentNullException(nameof(module)); + _type = type; + } + + /// + /// Gets or creates the cached for the module by type. + /// + /// + /// + public IIkvmReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) + { + if (type is null) + throw new ArgumentNullException(nameof(type)); + if (type.Module.MetadataToken != _module.MetadataToken) + throw new ArgumentException(nameof(type)); + if (type.IsGenericParameter) + throw new ArgumentException(nameof(type)); + if (type.IsTypeDefinition() == false) + throw new ArgumentException(nameof(type)); + + // create lock on demand + if (_lock == null) + Interlocked.CompareExchange(ref _lock, new ReaderWriterLockSlim(), null); + + using (_lock.CreateUpgradeableReadLock()) + { + var row = MetadataTokens.GetRowNumber(MetadataTokens.TypeDefinitionHandle(type.MetadataToken)); + if (_table[row] == null) + using (_lock.CreateWriteLock()) + if (_table[row] == null) + if (type is TypeBuilder builder) + return _table[row] = new IkvmReflectionTypeSymbolBuilder(_context, (IIkvmReflectionModuleSymbolBuilder)_module, builder); + else + return _table[row] = new IkvmReflectionTypeSymbol(_context, _module, type); + + return _table[row] ?? throw new InvalidOperationException(); + } + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionUtil.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionUtil.cs index 0aa5322ab..5dbe9d794 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionUtil.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionUtil.cs @@ -1,6 +1,9 @@ using System; +using IKVM.CoreLib.Symbols.Emit; +using IKVM.CoreLib.Symbols.IkvmReflection.Emit; using IKVM.Reflection; +using IKVM.Reflection.Emit; using Type = IKVM.Reflection.Type; @@ -18,7 +21,7 @@ static class IkvmReflectionUtil /// /// /// - public static System.Reflection.AssemblyName ToAssemblyName(this AssemblyName n) + public static System.Reflection.AssemblyName Pack(this AssemblyName n) { return new System.Reflection.AssemblyName() { @@ -42,14 +45,58 @@ public static System.Reflection.AssemblyName ToAssemblyName(this AssemblyName n) /// /// /// - public static System.Reflection.AssemblyName[] ToAssemblyNames(this AssemblyName[] n) + public static System.Reflection.AssemblyName[] Pack(this AssemblyName[] n) { if (n.Length == 0) return []; var a = new System.Reflection.AssemblyName[n.Length]; for (int i = 0; i < n.Length; i++) - a[i] = n[i].ToAssemblyName(); + a[i] = n[i].Pack(); + + return a; + } + +#pragma warning disable SYSLIB0017 // Type or member is obsolete +#pragma warning disable SYSLIB0037 // Type or member is obsolete + + /// + /// Converts a to a . + /// + /// + /// + public static AssemblyName Unpack(this System.Reflection.AssemblyName n) + { + return new AssemblyName() + { + Name = n.Name, + Version = n.Version, + CultureInfo = n.CultureInfo, + CultureName = n.CultureName, + ProcessorArchitecture = (ProcessorArchitecture)n.ProcessorArchitecture, + Flags = (AssemblyNameFlags)n.Flags, + HashAlgorithm = (AssemblyHashAlgorithm)n.HashAlgorithm, + ContentType = (AssemblyContentType)n.ContentType, + VersionCompatibility = (AssemblyVersionCompatibility)n.VersionCompatibility, + }; + } + +#pragma warning restore SYSLIB0037 // Type or member is obsolete +#pragma warning restore SYSLIB0017 // Type or member is obsolete + + /// + /// Converts a set of to a set of . + /// + /// + /// + public static AssemblyName[] Unpack(this System.Reflection.AssemblyName[] n) + { + if (n.Length == 0) + return []; + + var a = new AssemblyName[n.Length]; + for (int i = 0; i < n.Length; i++) + a[i] = n[i].Unpack(); return a; } @@ -310,6 +357,93 @@ public static ParameterModifier[] Unpack(this System.Reflection.ParameterModifie return a; } + /// + /// Unpacks the . + /// + /// + /// + public static LocalBuilder Unpack(this ILocalBuilder builder) + { + return ((IkvmReflectionLocalBuilder)builder).UnderlyingLocalBuilder; + } + + /// + /// Unpacks the . + /// + /// + /// + public static Label Unpack(this ILabel label) + { + return ((IkvmReflectionLabel)label).UnderlyingLabel; + } + + /// + /// Unpacks the s. + /// + /// + /// + public static Label[] Unpack(this ILabel[] labels) + { + var a = new Label[labels.Length]; + for (int i = 0; i < labels.Length; i++) + a[i] = labels[i].Unpack(); + + return a; + } + + /// + /// Unpacks the . + /// + /// + /// + public static CustomAttributeBuilder Unpack(this ICustomAttributeBuilder customAttributes) + { + return ((IkvmReflectionCustomAttributeBuilder)customAttributes).UnderlyingBuilder; + } + + /// + /// Unpacks the s. + /// + /// + /// + public static CustomAttributeBuilder[] Unpack(this ICustomAttributeBuilder[] customAttributes) + { + if (customAttributes.Length == 0) + return []; + + var a = new CustomAttributeBuilder[customAttributes.Length]; + for (int i = 0; i < customAttributes.Length; i++) + a[i] = customAttributes[i].Unpack(); + + return a; + } + + /// + /// Returns true if the given type represents a type definition. + /// + /// + /// + public static bool IsTypeDefinition(this Type type) + { + if (type is null) + throw new ArgumentNullException(nameof(type)); + + return type.HasElementType == false && type.IsConstructedGenericType == false && type.IsGenericParameter == false; + } + + /// + /// Returns true if the given method represents a method definition. + /// + /// + /// + public static bool IsMethodDefinition(this MethodBase method) + { + if (method is null) + throw new ArgumentNullException(nameof(method)); + + return method.IsGenericMethod == false || (method.IsGenericMethod && method.IsGenericMethodDefinition == true); + } + } } diff --git a/src/IKVM.CoreLib/Symbols/InterfaceMapping.cs b/src/IKVM.CoreLib/Symbols/InterfaceMapping.cs index e2208e0e0..ebc5c438c 100644 --- a/src/IKVM.CoreLib/Symbols/InterfaceMapping.cs +++ b/src/IKVM.CoreLib/Symbols/InterfaceMapping.cs @@ -3,13 +3,13 @@ namespace IKVM.CoreLib.Symbols { - readonly struct InterfaceMapping + readonly struct InterfaceMapping(IMethodSymbol[] InterfaceMethods, ITypeSymbol InterfaceType, IMethodSymbol[] TargetMethods, ITypeSymbol TargetType) { - public readonly ImmutableArray InterfaceMethods; - public readonly ITypeSymbol InterfaceType; - public readonly ImmutableArray TargetMethods; - public readonly ITypeSymbol TargetType; + public readonly IMethodSymbol[] InterfaceMethods = InterfaceMethods; + public readonly ITypeSymbol InterfaceType = InterfaceType; + public readonly IMethodSymbol[] TargetMethods = TargetMethods; + public readonly ITypeSymbol TargetType = TargetType; } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionConstructorSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionConstructorSymbolBuilder.cs index e9692b2c9..1dcb3c58d 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionConstructorSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionConstructorSymbolBuilder.cs @@ -13,6 +13,8 @@ class ReflectionConstructorSymbolBuilder : ReflectionMethodBaseSymbolBuilder, IR ConstructorBuilder? _builder; ConstructorInfo _ctor; + ReflectionILGenerator? _il; + /// /// Initializes a new instance. /// @@ -54,13 +56,13 @@ public IParameterSymbolBuilder DefineParameter(int iSequence, ParameterAttribute /// public IILGenerator GetILGenerator() { - throw new NotImplementedException(); + return _il ??= new ReflectionILGenerator(Context, UnderlyingConstructorBuilder.GetILGenerator()); } /// public IILGenerator GetILGenerator(int streamSize) { - throw new NotImplementedException(); + return _il ??= new ReflectionILGenerator(Context, UnderlyingConstructorBuilder.GetILGenerator(streamSize)); } /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionILGenerator.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionILGenerator.cs new file mode 100644 index 000000000..ee009451e --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionILGenerator.cs @@ -0,0 +1,265 @@ +using System; +using System.Diagnostics.SymbolStore; +using System.Reflection; +using System.Reflection.Emit; +using System.Runtime.InteropServices; + +using IKVM.CoreLib.Symbols.Emit; + +namespace IKVM.CoreLib.Symbols.Reflection.Emit +{ + + class ReflectionILGenerator : IILGenerator + { + + readonly ReflectionSymbolContext _context; + readonly ILGenerator _il; + + /// + /// Initializes a new instance. + /// + /// + public ReflectionILGenerator(ReflectionSymbolContext context, ILGenerator il) + { + _context = context ?? throw new ArgumentNullException(nameof(context)); + _il = il ?? throw new ArgumentNullException(nameof(il)); + } + + /// + public int ILOffset => _il.ILOffset; + + /// + public void BeginCatchBlock(ITypeSymbol? exceptionType) + { + _il.BeginCatchBlock(exceptionType?.Unpack()!); + + } + + /// + public void BeginExceptFilterBlock() + { + _il.BeginExceptFilterBlock(); + } + + /// + public ILabel BeginExceptionBlock() + { + return new ReflectionLabel(_il.BeginExceptionBlock()); + } + + /// + public void BeginFaultBlock() + { + _il.BeginFaultBlock(); + } + + /// + public void BeginFinallyBlock() + { + _il.BeginFinallyBlock(); + } + + /// + public void BeginScope() + { + _il.BeginScope(); + } + + /// + public ILocalBuilder DeclareLocal(ITypeSymbol localType, bool pinned) + { + return new ReflectionLocalBuilder(_context, _il.DeclareLocal(localType.Unpack(), pinned)); + } + + /// + public ILocalBuilder DeclareLocal(ITypeSymbol localType) + { + return new ReflectionLocalBuilder(_context, _il.DeclareLocal(localType.Unpack())); + } + + /// + public ILabel DefineLabel() + { + return new ReflectionLabel(_il.DefineLabel()); + } + + /// + public void Emit(OpCode opcode, ILocalBuilder local) + { + _il.Emit(opcode, local.Unpack()); + } + + /// + public void Emit(OpCode opcode, ITypeSymbol cls) + { + _il.Emit(opcode, cls.Unpack()); + } + + /// + public void Emit(OpCode opcode, string str) + { + _il.Emit(opcode, str); + } + + /// + public void Emit(OpCode opcode, float arg) + { + _il.Emit(opcode, arg); + } + + /// + public void Emit(OpCode opcode, sbyte arg) + { + _il.Emit(opcode, arg); + } + + /// + public void Emit(OpCode opcode, IMethodSymbol meth) + { + _il.Emit(opcode, meth.Unpack()); + } + + /// + public void Emit(OpCode opcode, ISignatureHelper signature) + { + throw new NotImplementedException(); + //_il.Emit(opcode, signature.Unpack()); + } + + /// + public void Emit(OpCode opcode, ILabel[] labels) + { + _il.Emit(opcode, labels.Unpack()); + } + + /// + public void Emit(OpCode opcode, IFieldSymbol field) + { + _il.Emit(opcode, field.Unpack()); + } + + /// + public void Emit(OpCode opcode, IConstructorSymbol con) + { + _il.Emit(opcode, con.Unpack()); + } + + /// + public void Emit(OpCode opcode, long arg) + { + _il.Emit(opcode, arg); + } + + /// + public void Emit(OpCode opcode, int arg) + { + _il.Emit(opcode, arg); + } + + /// + public void Emit(OpCode opcode, short arg) + { + _il.Emit(opcode, arg); + } + + /// + public void Emit(OpCode opcode, double arg) + { + _il.Emit(opcode, arg); + } + + /// + public void Emit(OpCode opcode, byte arg) + { + _il.Emit(opcode, arg); + } + + /// + public void Emit(OpCode opcode) + { + _il.Emit(opcode); + } + + /// + public void Emit(OpCode opcode, ILabel label) + { + _il.Emit(opcode, label.Unpack()); + } + + /// + public void EmitCall(OpCode opcode, IMethodSymbol methodInfo, ITypeSymbol[]? optionalParameterTypes) + { + _il.EmitCall(opcode, methodInfo.Unpack(), optionalParameterTypes?.Unpack()); + } + + /// + public void EmitCalli(OpCode opcode, CallingConvention unmanagedCallConv, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes) + { + _il.EmitCalli(opcode, unmanagedCallConv, returnType?.Unpack(), parameterTypes?.Unpack()); + } + + /// + public void EmitCalli(OpCode opcode, CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes, ITypeSymbol[]? optionalParameterTypes) + { + _il.EmitCalli(opcode, callingConvention, returnType?.Unpack(), parameterTypes?.Unpack(), optionalParameterTypes?.Unpack()); + } + + /// + public void EmitWriteLine(string value) + { + _il.EmitWriteLine(value); + } + + /// + public void EmitWriteLine(IFieldSymbol fld) + { + _il.EmitWriteLine(fld.Unpack()); + } + + /// + public void EmitWriteLine(ILocalBuilder localBuilder) + { + _il.EmitWriteLine(localBuilder.Unpack()); + } + + /// + public void EndExceptionBlock() + { + _il.EndExceptionBlock(); + } + + /// + public void EndScope() + { + _il.EndScope(); + } + + /// + public void MarkLabel(ILabel loc) + { + _il.MarkLabel(loc.Unpack()); + } + + /// + public void MarkSequencePoint(ISymbolDocumentWriter document, int startLine, int startColumn, int endLine, int endColumn) + { +#if NETFRAMEWORK + _il.MarkSequencePoint(document, startLine, startColumn, endLine, endColumn); +#endif + } + + /// + public void ThrowException(ITypeSymbol excType) + { + _il.ThrowException(excType.Unpack()); + } + + /// + public void UsingNamespace(string usingNamespace) + { + _il.UsingNamespace(usingNamespace); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionLabel.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionLabel.cs new file mode 100644 index 000000000..df05eb7ed --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionLabel.cs @@ -0,0 +1,29 @@ +using System.Reflection.Emit; + +using IKVM.CoreLib.Symbols.Emit; + +namespace IKVM.CoreLib.Symbols.Reflection.Emit +{ + + class ReflectionLabel : ILabel + { + + readonly Label _label; + + /// + /// Initializes a new instance. + /// + /// + public ReflectionLabel(Label label) + { + _label = label; + } + + /// + /// Gets the underlying . + /// + public Label UnderlyingLabel => _label; + + } + +} \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionLocalBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionLocalBuilder.cs new file mode 100644 index 000000000..136ce59cf --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionLocalBuilder.cs @@ -0,0 +1,59 @@ +using System; +using System.Reflection.Emit; + +using IKVM.CoreLib.Symbols.Emit; + +namespace IKVM.CoreLib.Symbols.Reflection.Emit +{ + + class ReflectionLocalBuilder : ILocalBuilder + { + + readonly ReflectionSymbolContext _context; + readonly LocalBuilder _builder; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + public ReflectionLocalBuilder(ReflectionSymbolContext context, LocalBuilder builder) + { + _context = context ?? throw new ArgumentNullException(nameof(context)); + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + } + + /// + /// Gets the underlying . + /// + public LocalBuilder UnderlyingLocalBuilder => _builder; + + /// + public bool IsPinned => _builder.IsPinned; + + /// + public int LocalIndex => _builder.LocalIndex; + + /// + public ITypeSymbol LocalType => _context.GetOrCreateTypeSymbol(_builder.LocalType); + + /// + public void SetLocalSymInfo(string name) + { +#if NETFRAMEWORK + _builder.SetLocalSymInfo(name); +#endif + } + + /// + public void SetLocalSymInfo(string name, int startOffset, int endOffset) + { +#if NETFRAMEWORK + _builder.SetLocalSymInfo(name, startOffset, endOffset); +#endif + } + + } + +} \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs index e0c2fb3e8..7fba722c5 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs @@ -13,6 +13,8 @@ class ReflectionMethodSymbolBuilder : ReflectionMethodBaseSymbolBuilder, IReflec MethodBuilder? _builder; MethodInfo _method; + ReflectionILGenerator? _il; + /// /// Initializes a new instance. /// @@ -68,7 +70,7 @@ public IGenericTypeParameterSymbolBuilder[] DefineGenericParameters(params strin var l = UnderlyingMethodBuilder.DefineGenericParameters(names); var a = new IGenericTypeParameterSymbolBuilder[l.Length]; for (int i = 0; i < l.Length; i++) - a[i] = new ReflectionGenericTypeParameterSymbolBuilder(Context, ResolvingModule, ResolvingType, this, l[i]); + a[i] = (IGenericTypeParameterSymbolBuilder)ResolveTypeSymbol(l[i]); return a; } @@ -76,17 +78,19 @@ public IGenericTypeParameterSymbolBuilder[] DefineGenericParameters(params strin /// public IParameterSymbolBuilder DefineParameter(int position, ParameterAttributes attributes, string? strParamName) { - return new ReflectionParameterSymbolBuilder(Context, ResolvingModule, this, UnderlyingMethodBuilder.DefineParameter(position, attributes, strParamName)); + return ResolveParameterSymbol(UnderlyingMethodBuilder.DefineParameter(position, attributes, strParamName)); } + /// public IILGenerator GetILGenerator() { - throw new NotImplementedException(); + return _il ??= new ReflectionILGenerator(Context, UnderlyingMethodBuilder.GetILGenerator()); } - public IILGenerator GetILGenerator(int size) + /// + public IILGenerator GetILGenerator(int streamSize) { - throw new NotImplementedException(); + return _il ??= new ReflectionILGenerator(Context, UnderlyingMethodBuilder.GetILGenerator(streamSize)); } /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionModuleSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionModuleSymbolBuilder.cs index 3a64b5df3..e5e338755 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionModuleSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionModuleSymbolBuilder.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics.SymbolStore; using System.Linq; using System.Reflection; using System.Reflection.Emit; @@ -42,6 +43,16 @@ public ReflectionModuleSymbolBuilder(ReflectionSymbolContext context, IReflectio #region IModuleSymbolBuilder + /// + public ISymbolDocumentWriter? DefineDocument(string url, Guid language, Guid languageVendor, Guid documentType) + { +#if NETFRAMEWORK + return UnderlyingModuleBuilder.DefineDocument(url, language, languageVendor, documentType); +#else + return null; +#endif + } + /// public ITypeSymbolBuilder DefineType(string name) { @@ -96,7 +107,7 @@ public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) UnderlyingModuleBuilder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); } - #endregion +#endregion #region IModuleSymbol diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs index 27eb44852..51a6db7e6 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs @@ -130,7 +130,7 @@ public IMethodSymbolBuilder DefineMethod(string name, MethodAttributes attribute } /// - public void DefineMethodOverride(IMethodSymbolBuilder methodInfoBody, IMethodSymbol methodInfoDeclaration) + public void DefineMethodOverride(IMethodSymbol methodInfoBody, IMethodSymbol methodInfoDeclaration) { UnderlyingTypeBuilder.DefineMethodOverride(methodInfoBody.Unpack(), methodInfoDeclaration.Unpack()); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionSymbol.cs index 7db22745b..1ee1657d8 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionSymbol.cs @@ -330,6 +330,13 @@ interface IReflectionSymbol : ISymbol /// CustomAttributeNamedArgument ResolveCustomAttributeNamedArgument(System.Reflection.CustomAttributeNamedArgument arg); + /// + /// Transforms a into a symbol type. + /// + /// + /// + InterfaceMapping ResolveInterfaceMapping(System.Reflection.InterfaceMapping arg); + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblyMetadata.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblyMetadata.cs index 7ba66dc3e..c63ae5145 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblyMetadata.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblyMetadata.cs @@ -17,7 +17,7 @@ struct ReflectionAssemblyMetadata readonly IReflectionAssemblySymbol _symbol; - IndexRangeDictionary _moduleSymbols = new(initialCapacity: 1, maxCapacity: 32); + IndexRangeDictionary _moduleSymbols = new(maxCapacity: 32); ReaderWriterLockSlim? _moduleLock; /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs index bd247f2e7..60a8b9f32 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs @@ -14,8 +14,6 @@ namespace IKVM.CoreLib.Symbols.Reflection class ReflectionModuleSymbol : ReflectionSymbol, IReflectionModuleSymbol { - const BindingFlags DefaultBindingFlags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance; - readonly IReflectionAssemblySymbol _resolvingAssembly; readonly Module _module; ReflectionModuleMetadata _impl; diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbol.cs index bf9c87d3e..9c719dd28 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbol.cs @@ -428,11 +428,7 @@ public virtual IReflectionParameterSymbolBuilder ResolveParameterSymbol(Paramete return a; } - /// - /// Transforms a custom set of custom attribute data records to a symbol record. - /// - /// - /// + /// public virtual IEnumerable ResolveCustomAttributes(IEnumerable attributes) { if (attributes is null) @@ -446,11 +442,7 @@ public virtual IEnumerable ResolveCustomAttributes(IEnumerable< return a.ToArray(); } - /// - /// Transforms a custom attribute data record to a symbol record. - /// - /// - /// + /// [return: NotNullIfNotNull(nameof(customAttributeData))] public virtual CustomAttribute? ResolveCustomAttribute(CustomAttributeData? customAttributeData) { @@ -464,11 +456,7 @@ public virtual IEnumerable ResolveCustomAttributes(IEnumerable< ResolveCustomAttributeNamedArguments(customAttributeData.NamedArguments)); } - /// - /// Transforms a list of values into symbols. - /// - /// - /// + /// public ImmutableArray ResolveCustomAttributeTypedArguments(IList args) { if (args is null) @@ -483,11 +471,7 @@ public ImmutableArray ResolveCustomAttributeTypedA return a.ToImmutableArray(); } - /// - /// Transforms a values into a symbol. - /// - /// - /// + /// public CustomAttributeTypedArgument ResolveCustomAttributeTypedArgument(System.Reflection.CustomAttributeTypedArgument arg) { return new CustomAttributeTypedArgument( @@ -495,11 +479,7 @@ public CustomAttributeTypedArgument ResolveCustomAttributeTypedArgument(System.R ResolveCustomAttributeTypedValue(arg.Value)); } - /// - /// Transforms the type as appropriate. - /// - /// - /// + /// public object? ResolveCustomAttributeTypedValue(object? value) { return value switch @@ -509,11 +489,7 @@ public CustomAttributeTypedArgument ResolveCustomAttributeTypedArgument(System.R }; } - /// - /// Transforms a list of values into symbols. - /// - /// - /// + /// public ImmutableArray ResolveCustomAttributeNamedArguments(IList args) { if (args is null) @@ -528,11 +504,7 @@ public ImmutableArray ResolveCustomAttributeNamedA return ImmutableArray.Create(a); } - /// - /// Transforms a values into a symbol. - /// - /// - /// + /// public CustomAttributeNamedArgument ResolveCustomAttributeNamedArgument(System.Reflection.CustomAttributeNamedArgument arg) { return new CustomAttributeNamedArgument( @@ -542,6 +514,16 @@ public CustomAttributeNamedArgument ResolveCustomAttributeNamedArgument(System.R ResolveCustomAttributeTypedArgument(arg.TypedValue)); } + /// + public InterfaceMapping ResolveInterfaceMapping(System.Reflection.InterfaceMapping mapping) + { + return new InterfaceMapping( + ResolveMethodSymbols(mapping.InterfaceMethods), + ResolveTypeSymbol(mapping.InterfaceType), + ResolveMethodSymbols(mapping.TargetMethods), + ResolveTypeSymbol(mapping.TargetType)); + } + } } \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs index cbd65e7c9..cb05d82fa 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs @@ -28,6 +28,34 @@ public ReflectionSymbolContext() } + /// + /// Defines a dynamic assembly that has the specified name and access rights. + /// + /// + /// + /// + public IAssemblySymbolBuilder DefineAssembly(AssemblyName name, AssemblyBuilderAccess access) + { + if (name is null) + throw new ArgumentNullException(nameof(name)); + + return GetOrCreateAssemblySymbol(AssemblyBuilder.DefineDynamicAssembly(name, access)); + } + + /// + /// Defines a dynamic assembly that has the specified name and access rights. + /// + /// + /// + /// + public IAssemblySymbolBuilder DefineAssembly(AssemblyName name, AssemblyBuilderAccess access, ICustomAttributeBuilder[]? assemblyAttributes) + { + if (name is null) + throw new ArgumentNullException(nameof(name)); + + return GetOrCreateAssemblySymbol(AssemblyBuilder.DefineDynamicAssembly(name, access, assemblyAttributes?.Unpack())); + } + /// /// Gets or creates a indexed based on the assembly's name. /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeImpl.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeImpl.cs index e08a8a2c9..c7821414c 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeImpl.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeImpl.cs @@ -375,7 +375,7 @@ public readonly ITypeSymbol GetGenericTypeDefinition() /// public readonly InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) { - throw new NotImplementedException(); + return _symbol.ResolveInterfaceMapping(_symbol.UnderlyingType.GetInterfaceMap(interfaceType.Unpack())); } /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionUtil.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionUtil.cs index fd823ad8e..10f77d184 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionUtil.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionUtil.cs @@ -1,5 +1,9 @@ using System; using System.Reflection; +using System.Reflection.Emit; + +using IKVM.CoreLib.Symbols.Emit; +using IKVM.CoreLib.Symbols.Reflection.Emit; namespace IKVM.CoreLib.Symbols.Reflection { @@ -27,6 +31,9 @@ public static Module Unpack(this IModuleSymbol module) /// public static Module[] Unpack(this IModuleSymbol[] modules) { + if (modules.Length == 0) + return []; + var a = new Module[modules.Length]; for (int i = 0; i < modules.Length; i++) a[i] = modules[i].Unpack(); @@ -54,6 +61,9 @@ public static Type Unpack(this ITypeSymbol type) /// public static Type[] Unpack(this ITypeSymbol[] types) { + if (types.Length == 0) + return []; + var a = new Type[types.Length]; for (int i = 0; i < types.Length; i++) a[i] = types[i].Unpack(); @@ -68,6 +78,9 @@ public static Type[] Unpack(this ITypeSymbol[] types) /// public static Type[][] Unpack(this ITypeSymbol[][] types) { + if (types.Length == 0) + return []; + var a = new Type[types.Length][]; for (int i = 0; i < types.Length; i++) a[i] = types[i].Unpack(); @@ -95,6 +108,9 @@ public static MemberInfo Unpack(this IMemberSymbol member) /// public static MemberInfo[] Unpack(this IMemberSymbol[] members) { + if (members.Length == 0) + return []; + var a = new MemberInfo[members.Length]; for (int i = 0; i < members.Length; i++) a[i] = members[i].Unpack(); @@ -122,6 +138,9 @@ public static ConstructorInfo Unpack(this IConstructorSymbol ctor) /// public static ConstructorInfo[] Unpack(this IConstructorSymbol[] ctor) { + if (ctor.Length == 0) + return []; + var a = new ConstructorInfo[ctor.Length]; for (int i = 0; i < ctor.Length; i++) a[i] = ctor[i].Unpack(); @@ -149,6 +168,9 @@ public static MethodInfo Unpack(this IMethodSymbol ctor) /// public static MethodInfo[] Unpack(this IMethodSymbol[] ctor) { + if (ctor.Length == 0) + return []; + var a = new MethodInfo[ctor.Length]; for (int i = 0; i < ctor.Length; i++) a[i] = ctor[i].Unpack(); @@ -176,6 +198,9 @@ public static FieldInfo Unpack(this IFieldSymbol field) /// public static FieldInfo[] Unpack(this IFieldSymbol[] fields) { + if (fields.Length == 0) + return []; + var a = new FieldInfo[fields.Length]; for (int i = 0; i < fields.Length; i++) a[i] = fields[i].Unpack(); @@ -203,6 +228,9 @@ public static PropertyInfo Unpack(this IPropertySymbol property) /// public static PropertyInfo[] Unpack(this IPropertySymbol[] properties) { + if (properties.Length == 0) + return []; + var a = new PropertyInfo[properties.Length]; for (int i = 0; i < properties.Length; i++) a[i] = properties[i].Unpack(); @@ -210,6 +238,67 @@ public static PropertyInfo[] Unpack(this IPropertySymbol[] properties) return a; } + /// + /// Unpacks the . + /// + /// + /// + public static LocalBuilder Unpack(this ILocalBuilder builder) + { + return ((ReflectionLocalBuilder)builder).UnderlyingLocalBuilder; + } + + /// + /// Unpacks the . + /// + /// + /// + public static Label Unpack(this ILabel label) + { + return ((ReflectionLabel)label).UnderlyingLabel; + } + + /// + /// Unpacks the s. + /// + /// + /// + public static Label[] Unpack(this ILabel[] labels) + { + var a = new Label[labels.Length]; + for (int i = 0; i < labels.Length; i++) + a[i] = labels[i].Unpack(); + + return a; + } + + /// + /// Unpacks the . + /// + /// + /// + public static CustomAttributeBuilder Unpack(this ICustomAttributeBuilder customAttributes) + { + return ((ReflectionCustomAttributeBuilder)customAttributes).UnderlyingBuilder; + } + + /// + /// Unpacks the s. + /// + /// + /// + public static CustomAttributeBuilder[] Unpack(this ICustomAttributeBuilder[] customAttributes) + { + if (customAttributes.Length == 0) + return []; + + var a = new CustomAttributeBuilder[customAttributes.Length]; + for (int i = 0; i < customAttributes.Length; i++) + a[i] = customAttributes[i].Unpack(); + + return a; + } + } } diff --git a/src/IKVM.Reflection/Emit/ILGenerator.cs b/src/IKVM.Reflection/Emit/ILGenerator.cs index 146241b4b..5731f7edd 100644 --- a/src/IKVM.Reflection/Emit/ILGenerator.cs +++ b/src/IKVM.Reflection/Emit/ILGenerator.cs @@ -9,6 +9,7 @@ using System; using System.Buffers.Binary; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Contracts; using System.Diagnostics.SymbolStore; using System.Runtime.CompilerServices; @@ -940,6 +941,24 @@ public void Emit(OpCode opcode, LocalBuilder local) #endregion #region Exceptions + + public virtual void ThrowException(Type excType) + { + if (excType is null) + throw new ArgumentNullException(nameof(excType)); + + // TODO figure out how to load type here + //if (!excType.IsSubclassOf( typeof(Exception)) && excType != typeof(Exception)) + //throw new ArgumentException(nameof(excType)); + + var con = excType.GetConstructor(Type.EmptyTypes); + if (con == null) + throw new ArgumentException(nameof(excType)); + + Emit(OpCodes.Newobj, con); + Emit(OpCodes.Throw); + } + public Label BeginExceptionBlock() { // Begin an Exception block. Creating an Exception block records some information, diff --git a/src/IKVM.Reflection/MemberInfo.cs b/src/IKVM.Reflection/MemberInfo.cs index 83a45531f..2ac8d83e6 100644 --- a/src/IKVM.Reflection/MemberInfo.cs +++ b/src/IKVM.Reflection/MemberInfo.cs @@ -43,7 +43,9 @@ internal MemberInfo() } public abstract string Name { get; } + public abstract Type DeclaringType { get; } + public abstract MemberTypes MemberType { get; } public virtual Type ReflectedType diff --git a/src/IKVM.Reflection/Type.cs b/src/IKVM.Reflection/Type.cs index 38bea7747..5eecf0c1e 100644 --- a/src/IKVM.Reflection/Type.cs +++ b/src/IKVM.Reflection/Type.cs @@ -162,7 +162,7 @@ public virtual EventInfo[] __GetDeclaredEvents() { return Array.Empty(); } - + public virtual PropertyInfo[] __GetDeclaredProperties() { return Array.Empty(); diff --git a/src/IKVM.Runtime/AttributeHelper.cs b/src/IKVM.Runtime/AttributeHelper.cs index cf883ce9a..4979b0017 100644 --- a/src/IKVM.Runtime/AttributeHelper.cs +++ b/src/IKVM.Runtime/AttributeHelper.cs @@ -1020,7 +1020,7 @@ internal RemappedInterfaceMethodAttribute[] GetRemappedInterfaceMethods(ITypeSym internal RemappedTypeAttribute GetRemappedType(ITypeSymbol type) { foreach (var cad in type.GetCustomAttributes(TypeOfRemappedTypeAttribute)) - return new RemappedTypeAttribute((Type)cad.ConstructorArguments[0].Value); + return new RemappedTypeAttribute(((ITypeSymbol)cad.ConstructorArguments[0].Value).AsReflection()); return null; } @@ -1032,7 +1032,7 @@ internal RemappedClassAttribute[] GetRemappedClasses(IAssemblySymbol coreAssembl foreach (var cad in coreAssembly.GetCustomAttributes(TypeOfRemappedClassAttribute)) { var args = cad.ConstructorArguments; - attrs.Add(new RemappedClassAttribute((string)args[0].Value, (Type)args[1].Value)); + attrs.Add(new RemappedClassAttribute((string)args[0].Value, ((ITypeSymbol)args[1].Value).AsReflection())); } return attrs.ToArray(); diff --git a/src/IKVM.Runtime/CodeEmitter.cs b/src/IKVM.Runtime/CodeEmitter.cs index cf4cb20cb..b32b34ba9 100644 --- a/src/IKVM.Runtime/CodeEmitter.cs +++ b/src/IKVM.Runtime/CodeEmitter.cs @@ -23,20 +23,16 @@ Jeroen Frijters */ using System; using System.Collections.Generic; -using System.Runtime.InteropServices; -using System.Diagnostics.SymbolStore; using System.Diagnostics; +using System.Diagnostics.SymbolStore; +using System.Reflection; +using System.Reflection.Emit; +using System.Runtime.InteropServices; using IKVM.CoreLib.Symbols; using IKVM.CoreLib.Symbols.Emit; - -#if IMPORTER -using IKVM.Reflection; -using IKVM.Reflection.Emit; -#else -using System.Reflection; -using System.Reflection.Emit; -#endif +using IKVM.CoreLib.Symbols.Reflection; +using IKVM.CoreLib.Symbols.Reflection.Emit; namespace IKVM.Runtime { @@ -80,7 +76,7 @@ public CodeEmitterFactory(RuntimeContext context) /// public CodeEmitter Create(IMethodSymbolBuilder mb) { - return new CodeEmitter(context, mb.GetILGenerator(), context.Resolver.ResolveType(mb.DeclaringType)); + return new CodeEmitter(context, mb.GetILGenerator(), mb.DeclaringType); } #if IMPORTER == false @@ -92,7 +88,7 @@ public CodeEmitter Create(IMethodSymbolBuilder mb) /// public CodeEmitter Create(DynamicMethod dm) { - return new CodeEmitter(context, dm.GetILGenerator(), null); + return new CodeEmitter(context, new ReflectionILGenerator((ReflectionSymbolContext)context.Resolver.Symbols, dm.GetILGenerator()), null); } #endif @@ -2109,11 +2105,9 @@ internal void DumpMethod() } } - internal void DefineSymbolDocument(ModuleBuilder module, string url, Guid language, Guid languageVendor, Guid documentType) + internal void DefineSymbolDocument(IModuleSymbolBuilder module, string url, Guid language, Guid languageVendor, Guid documentType) { -#if NETFRAMEWORK || IMPORTER symbols = module.DefineDocument(url, language, languageVendor, documentType); -#endif } internal CodeEmitterLocal UnsafeAllocTempLocal(ITypeSymbol type) @@ -2427,7 +2421,7 @@ internal byte[] GetLineNumberTable() #if IMPORTER - internal void EmitLineNumberTable(MethodBuilder mb) + internal void EmitLineNumberTable(IMethodSymbolBuilder mb) { if (linenums != null) context.AttributeHelper.SetLineNumberTable(mb, linenums); diff --git a/src/IKVM.Runtime/CodeEmitterLocal.cs b/src/IKVM.Runtime/CodeEmitterLocal.cs index 6f9161b3a..bda872337 100644 --- a/src/IKVM.Runtime/CodeEmitterLocal.cs +++ b/src/IKVM.Runtime/CodeEmitterLocal.cs @@ -21,14 +21,10 @@ Jeroen Frijters jeroen@frijters.net */ -using IKVM.CoreLib.Symbols; - -#if IMPORTER -using IKVM.Reflection.Emit; -#else using System.Reflection.Emit; -#endif +using IKVM.CoreLib.Symbols; +using IKVM.CoreLib.Symbols.Emit; namespace IKVM.Runtime { @@ -38,7 +34,7 @@ sealed class CodeEmitterLocal private ITypeSymbol type; private string name; - private LocalBuilder local; + private ILocalBuilder local; internal CodeEmitterLocal(ITypeSymbol type) { @@ -60,22 +56,19 @@ internal int __LocalIndex get { return local == null ? 0xFFFF : local.LocalIndex; } } - internal void Emit(ILGenerator ilgen, OpCode opcode) + internal void Emit(IILGenerator ilgen, OpCode opcode) { // it's a temporary local that is only allocated on-demand - local ??= ilgen.DeclareLocal(type.AsReflection()); + local ??= ilgen.DeclareLocal(type); ilgen.Emit(opcode, local); } - internal void Declare(ILGenerator ilgen) + internal void Declare(IILGenerator ilgen) { - local = ilgen.DeclareLocal(type.AsReflection()); + local = ilgen.DeclareLocal(type); -#if NETFRAMEWORK || IMPORTER if (name != null) local.SetLocalSymInfo(name); -#endif - } } diff --git a/src/IKVM.Runtime/DynamicClassLoader.cs b/src/IKVM.Runtime/DynamicClassLoader.cs index c22efbdfa..8a82599a4 100644 --- a/src/IKVM.Runtime/DynamicClassLoader.cs +++ b/src/IKVM.Runtime/DynamicClassLoader.cs @@ -27,13 +27,11 @@ Jeroen Frijters using System.Runtime.Serialization; using System.Collections.Concurrent; -using static System.Diagnostics.DebuggableAttribute; using IKVM.CoreLib.Diagnostics; using IKVM.CoreLib.Symbols.Emit; using IKVM.CoreLib.Symbols; - - +using static System.Diagnostics.DebuggableAttribute; #if IMPORTER using IKVM.Reflection; @@ -106,7 +104,7 @@ Assembly Resolve(ConcurrentDictionary dict, string name try { type.Finish(); - return type.TypeAsTBD.Assembly; + return type.TypeAsTBD.Assembly.AsReflection(); } catch (RetargetableJavaException e) { @@ -135,7 +133,7 @@ public DynamicClassLoader GetOrCreate(RuntimeClassLoader loader) if (loader is RuntimeAssemblyClassLoader acl) { var name = acl.MainAssembly.GetName().Name + context.Options.DynamicAssemblySuffixAndPublicKey; - foreach (var attr in acl.MainAssembly.GetCustomAttributes()) + foreach (var attr in acl.MainAssembly.AsReflection().GetCustomAttributes()) { if (attr.AssemblyName == name) { @@ -201,7 +199,7 @@ internal sealed class DynamicClassLoader : RuntimeJavaTypeFactory { #if !IMPORTER - static AssemblyBuilder jniProxyAssemblyBuilder; + static IAssemblySymbolBuilder jniProxyAssemblyBuilder; #endif readonly RuntimeContext context; @@ -349,7 +347,7 @@ internal override ITypeSymbol DefineUnloadable(string name) type = unloadableContainer.DefineNestedType(TypeNameUtil.MangleNestedTypeName(name), System.Reflection.TypeAttributes.NestedPrivate | System.Reflection.TypeAttributes.Interface | System.Reflection.TypeAttributes.Abstract); unloadables.Add(name, type); - return type.Symbol; + return type; } } @@ -374,7 +372,7 @@ internal override ITypeSymbol DefineDelegate(int parameterCount, bool returnVoid names[names.Length - 1] = "R"; var genericParameters = tb.DefineGenericParameters(names); - var parameterTypes = genericParameters; + var parameterTypes = (ITypeSymbol[])genericParameters; if (!returnVoid) { parameterTypes = new ITypeSymbol[genericParameters.Length - 1]; @@ -388,8 +386,8 @@ internal override ITypeSymbol DefineDelegate(int parameterCount, bool returnVoid mb.SetImplementationFlags(System.Reflection.MethodImplAttributes.Runtime); tb.Complete(); - delegates[index] = tb.Symbol; - return tb.Symbol; + delegates[index] = tb; + return tb; } } @@ -422,17 +420,18 @@ internal void FinishAll() if (unloadableContainer != null) { - unloadableContainer.CreateType(); + unloadableContainer.Complete(); foreach (var tb in unloadables.Values) - tb.CreateType(); + tb.Complete(); } #if IMPORTER + if (proxiesContainer != null) { - proxiesContainer.CreateType(); + proxiesContainer.Complete(); foreach (var tb in proxies) - tb.CreateType(); + tb.Complete(); } #endif @@ -441,12 +440,11 @@ internal void FinishAll() #if !IMPORTER - internal static ModuleBuilder CreateJniProxyModuleBuilder() + internal static IModuleSymbolBuilder CreateJniProxyModuleBuilder(RuntimeContext context) { - AssemblyName name = new AssemblyName(); - name.Name = "jniproxy"; - jniProxyAssemblyBuilder = DefineDynamicAssembly(name, AssemblyBuilderAccess.Run, null); - return jniProxyAssemblyBuilder.DefineDynamicModule("jniproxy.dll"); + var name = new AssemblyName("jniproxy"); + jniProxyAssemblyBuilder = DefineDynamicAssembly(context, name, AssemblyBuilderAccess.Run, null); + return jniProxyAssemblyBuilder.DefineModule("jniproxy.dll"); } #endif @@ -515,26 +513,26 @@ private static SerializationInfo ToInfo(byte[] publicKey) #endif - public static ModuleBuilder CreateModuleBuilder(RuntimeContext context) + public static IModuleSymbolBuilder CreateModuleBuilder(RuntimeContext context) { AssemblyName name = new AssemblyName(); name.Name = "ikvm_dynamic_assembly__" + (uint)Environment.TickCount; return CreateModuleBuilder(context, name); } - public static ModuleBuilder CreateModuleBuilder(RuntimeContext context, AssemblyName name) + public static IModuleSymbolBuilder CreateModuleBuilder(RuntimeContext context, AssemblyName name) { var now = DateTime.Now; name.Version = new Version(now.Year, (now.Month * 100) + now.Day, (now.Hour * 100) + now.Minute, (now.Second * 1000) + now.Millisecond); - var attribs = new List(); - AssemblyBuilderAccess access = AssemblyBuilderAccess.Run; + var attribs = new List(); + var access = AssemblyBuilderAccess.Run; #if NETFRAMEWORK if (!AppDomain.CurrentDomain.IsFullyTrusted) - attribs.Add(new CustomAttributeBuilder(typeof(System.Security.SecurityTransparentAttribute).GetConstructor([]), [])); + attribs.Add(context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveCoreType(typeof(System.Security.SecurityTransparentAttribute).FullName).GetConstructor([]), [])); #endif - var assemblyBuilder = DefineDynamicAssembly(name, access, attribs); + var assemblyBuilder = DefineDynamicAssembly(context, name, access, attribs.ToArray()); context.AttributeHelper.SetRuntimeCompatibilityAttribute(assemblyBuilder); // determine debugging mode @@ -544,23 +542,15 @@ public static ModuleBuilder CreateModuleBuilder(RuntimeContext context, Assembly context.AttributeHelper.SetDebuggingModes(assemblyBuilder, debugMode); -#if NETFRAMEWORK - var moduleBuilder = assemblyBuilder.DefineDynamicModule(name.Name, JVM.EmitSymbols); -#else - var moduleBuilder = assemblyBuilder.DefineDynamicModule(name.Name); -#endif + var moduleBuilder = assemblyBuilder.DefineModule(name.Name, null, JVM.EmitSymbols); - moduleBuilder.SetCustomAttribute(new CustomAttributeBuilder(typeof(IKVM.Attributes.JavaModuleAttribute).GetConstructor([]), [])); + moduleBuilder.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveRuntimeType(typeof(IKVM.Attributes.JavaModuleAttribute).FullName).GetConstructor([]), [])); return moduleBuilder; } - static AssemblyBuilder DefineDynamicAssembly(AssemblyName name, AssemblyBuilderAccess access, IEnumerable assemblyAttributes) + static IAssemblySymbolBuilder DefineDynamicAssembly(RuntimeContext context, AssemblyName name, AssemblyBuilderAccess access, ICustomAttributeBuilder[] assemblyAttributes) { -#if NETFRAMEWORK - return AppDomain.CurrentDomain.DefineDynamicAssembly(name, access, null, true, assemblyAttributes); -#else - return AssemblyBuilder.DefineDynamicAssembly(name, access, assemblyAttributes); -#endif + return context.Resolver.Symbols.DefineAssembly(name, access, assemblyAttributes); } #endif diff --git a/src/IKVM.Runtime/ExceptionHelper.cs b/src/IKVM.Runtime/ExceptionHelper.cs index 1356850df..d9151e11a 100644 --- a/src/IKVM.Runtime/ExceptionHelper.cs +++ b/src/IKVM.Runtime/ExceptionHelper.cs @@ -30,8 +30,8 @@ Jeroen Frijters using System.Security; using IKVM.Attributes; +using IKVM.CoreLib.Symbols; -using IDictionary = System.Collections.IDictionary; using Interlocked = System.Threading.Interlocked; using MethodBase = System.Reflection.MethodBase; @@ -218,8 +218,8 @@ internal static void Append(ExceptionHelper exceptionHelper, List - /// Gets the associated with the specified type. + /// Gets the associated with the specified assembly. /// /// /// - IAssemblySymbol ResolveAssembly(Assembly assembly); + IAssemblySymbol? ResolveAssembly(Assembly? assembly); /// - /// Gets the associated with the specified type. + /// Gets the associated with the specified module. /// /// /// - IModuleSymbol ResolveModule(Module module); + IModuleSymbol? ResolveModule(Module? module); /// /// Gets the associated with the specified type. /// /// /// - ITypeSymbol ResolveType(Type type); + ITypeSymbol? ResolveType(Type? type); + + /// + /// Gets the associated with the specified method. + /// + /// + /// + IMethodBaseSymbol? ResolveMethodBase(MethodBase? type); + + /// + /// Gets the associated with the specified method. + /// + /// + /// + IConstructorSymbol? ResolveConstructor(ConstructorInfo? ctor); + + /// + /// Gets the associated with the specified method. + /// + /// + /// + IMethodSymbol? ResolveMethod(MethodInfo? method); } diff --git a/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Util.cs b/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Util.cs index 1fbc79ad5..98f7c118a 100644 --- a/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Util.cs +++ b/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Util.cs @@ -24,6 +24,8 @@ Jeroen Frijters using System; using IKVM.Attributes; +using IKVM.CoreLib.Symbols; +using IKVM.CoreLib.Symbols.Emit; using IKVM.Runtime; namespace IKVM.Java.Externs.ikvm.runtime @@ -48,19 +50,20 @@ internal static RuntimeJavaType GetTypeWrapperFromObject(RuntimeContext context, return ghostType; var t = o.GetType(); - if (t.IsPrimitive || context.ClassLoaderFactory.IsRemappedType(t) && !t.IsSealed) - return context.ManagedJavaTypeFactory.GetJavaTypeFromManagedType(t); + var ts = context.Resolver.ResolveType(t); + if (t.IsPrimitive || context.ClassLoaderFactory.IsRemappedType(ts) && !ts.IsSealed) + return context.ManagedJavaTypeFactory.GetJavaTypeFromManagedType(ts); for (; ; ) { // if GetWrapperFromType returns null (or if tw.IsAbstract), that // must mean that the Type of the object is an implementation helper class // (e.g. an AtomicReferenceFieldUpdater or ThreadLocal instrinsic subclass) - var tw = context.ClassLoaderFactory.GetJavaTypeFromType(t); + var tw = context.ClassLoaderFactory.GetJavaTypeFromType(ts); if (tw != null && (!tw.IsAbstract || tw.IsArray)) return tw; - t = t.BaseType; + ts = ts.BaseType; } } @@ -70,13 +73,14 @@ internal static RuntimeJavaType GetTypeWrapperFromObject(RuntimeContext context, throw new NotImplementedException(); #else var t = Type.GetTypeFromHandle(handle); - if (t.IsPrimitive || JVM.Context.ClassLoaderFactory.IsRemappedType(t) || t == typeof(void)) - return JVM.Context.ManagedJavaTypeFactory.GetJavaTypeFromManagedType(t).ClassObject; + var ts = JVM.Context.Resolver.ResolveType(t); + if (t.IsPrimitive || JVM.Context.ClassLoaderFactory.IsRemappedType(ts) || t == typeof(void)) + return JVM.Context.ManagedJavaTypeFactory.GetJavaTypeFromManagedType(ts).ClassObject; - if (!IsVisibleAsClass(t)) + if (!IsVisibleAsClass(ts)) return null; - var tw = JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(t); + var tw = JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(ts); if (tw != null) return tw.ClassObject; @@ -90,13 +94,14 @@ internal static RuntimeJavaType GetTypeWrapperFromObject(RuntimeContext context, throw new NotImplementedException(); #else var t = Type.GetTypeFromHandle(handle); - if (t.IsPrimitive || JVM.Context.ClassLoaderFactory.IsRemappedType(t) || t == typeof(void)) - return JVM.Context.ManagedJavaTypeFactory.GetJavaTypeFromManagedType(t).MakeArrayType(rank).ClassObject; + var ts = JVM.Context.Resolver.ResolveType(t); + if (ts.IsPrimitive || JVM.Context.ClassLoaderFactory.IsRemappedType(ts) || ts == typeof(void)) + return JVM.Context.ManagedJavaTypeFactory.GetJavaTypeFromManagedType(ts).MakeArrayType(rank).ClassObject; if (!IsVisibleAsClass(t)) return null; - var tw = JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(t); + var tw = JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(ts); if (tw != null) return tw.MakeArrayType(rank).ClassObject; @@ -109,20 +114,22 @@ internal static RuntimeJavaType GetTypeWrapperFromObject(RuntimeContext context, #if FIRST_PASS throw new NotImplementedException(); #else + var ts = JVM.Context.Resolver.ResolveType(type); + int rank = 0; - while (ReflectUtil.IsVector(type)) + while (ReflectUtil.IsVector(ts)) { - type = type.GetElementType(); + ts = ts.GetElementType(); rank++; } - if (type.DeclaringType != null && JVM.Context.AttributeHelper.IsGhostInterface(type.DeclaringType)) - type = type.DeclaringType; + if (ts.DeclaringType != null && JVM.Context.AttributeHelper.IsGhostInterface(ts.DeclaringType)) + ts = ts.DeclaringType; if (!IsVisibleAsClass(type)) return null; - var wrapper = JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(type); + var wrapper = JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(ts); if (wrapper == null) return null; @@ -133,25 +140,22 @@ internal static RuntimeJavaType GetTypeWrapperFromObject(RuntimeContext context, #endif } - private static bool IsVisibleAsClass(Type type) + private static bool IsVisibleAsClass(ITypeSymbol type) { while (type.HasElementType) { if (type.IsPointer || type.IsByRef) - { return false; - } + type = type.GetElementType(); } + if (type.ContainsGenericParameters && !type.IsGenericTypeDefinition) - { return false; - } - System.Reflection.Emit.TypeBuilder tb = type as System.Reflection.Emit.TypeBuilder; - if (tb != null && !tb.IsCreated()) - { + + if (type is ITypeSymbolBuilder tb && !tb.IsComplete) return false; - } + return true; } @@ -164,9 +168,9 @@ public static Type getInstanceTypeFromClass(global::java.lang.Class classObject) { var wrapper = RuntimeJavaType.FromClass(classObject); if (wrapper.IsRemapped && wrapper.IsFinal) - return wrapper.TypeAsTBD; + return wrapper.TypeAsTBD.AsReflection(); else - return wrapper.TypeAsBaseType; + return wrapper.TypeAsBaseType.AsReflection(); } /// @@ -180,9 +184,9 @@ public static Type getRuntimeTypeFromClass(global::java.lang.Class classObject) wrapper.Finish(); if (wrapper.IsRemapped && wrapper.IsFinal) - return wrapper.TypeAsTBD; + return wrapper.TypeAsTBD.AsReflection(); else - return wrapper.TypeAsBaseType; + return wrapper.TypeAsBaseType.AsReflection(); } [HideFromJava] diff --git a/src/IKVM.Runtime/Java/Externs/java/lang/Package.cs b/src/IKVM.Runtime/Java/Externs/java/lang/Package.cs index 57fbfbd9f..ce41e7611 100644 --- a/src/IKVM.Runtime/Java/Externs/java/lang/Package.cs +++ b/src/IKVM.Runtime/Java/Externs/java/lang/Package.cs @@ -32,7 +32,7 @@ Jeroen Frijters namespace IKVM.Java.Externs.java.lang { - static class Package + static class Package { static Dictionary systemPackages; diff --git a/src/IKVM.Runtime/Java/Externs/sun/misc/Unsafe.cs b/src/IKVM.Runtime/Java/Externs/sun/misc/Unsafe.cs index 229822b1d..621a5b980 100644 --- a/src/IKVM.Runtime/Java/Externs/sun/misc/Unsafe.cs +++ b/src/IKVM.Runtime/Java/Externs/sun/misc/Unsafe.cs @@ -2475,11 +2475,11 @@ static Delegate CreateCompareExchangeArrayDelegate(RuntimeJavaType tw) var e = Expression.Parameter(typeof(object)); return Expression.Lambda>( Expression.Call( - compareAndSwapArrayMethodInfo.MakeGenericMethod(tw.TypeAsTBD), - Expression.Convert(p, tw.MakeArrayType(1).TypeAsTBD), + compareAndSwapArrayMethodInfo.MakeGenericMethod(tw.TypeAsTBD.AsReflection()), + Expression.Convert(p, tw.MakeArrayType(1).TypeAsTBD.AsReflection()), i, - Expression.Convert(v, tw.TypeAsTBD), - Expression.Convert(e, tw.TypeAsTBD)), + Expression.Convert(v, tw.TypeAsTBD.AsReflection()), + Expression.Convert(e, tw.TypeAsTBD.AsReflection())), p, i, v, e) .Compile(); } diff --git a/src/IKVM.Runtime/LambdaMetafactory.cs b/src/IKVM.Runtime/LambdaMetafactory.cs index 50877f45b..92079c97a 100644 --- a/src/IKVM.Runtime/LambdaMetafactory.cs +++ b/src/IKVM.Runtime/LambdaMetafactory.cs @@ -24,19 +24,15 @@ Jeroen Frijters using System; using System.Collections.Generic; using System.Diagnostics; +using System.Reflection; +using System.Reflection.Emit; using IKVM.ByteCode; -using IKVM.CoreLib.Diagnostics; -using IKVM.CoreLib.Symbols.Emit; using IKVM.CoreLib.Symbols; +using IKVM.CoreLib.Symbols.Emit; #if IMPORTER using IKVM.Tools.Importer; - -using Type = IKVM.Reflection.Type; -#else -using System.Reflection; -using System.Reflection.Emit; #endif namespace IKVM.Runtime @@ -529,7 +525,7 @@ private static void EmitDispatch(RuntimeByteCodeJavaType.FinishContext context, var mb = interfaceMethod.GetDefineMethodHelper().DefineMethod(context.TypeWrapper, tb, interfaceMethod.Name, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final); if (interfaceMethod.Name != interfaceMethod.RealName) { - tb.DefineMethodOverride(mb, (MethodInfo)interfaceMethod.GetMethod()); + tb.DefineMethodOverride(mb, (IMethodSymbol)interfaceMethod.GetMethod()); } context.Context.AttributeHelper.HideFromJava(mb); diff --git a/src/IKVM.Runtime/MethodHandleUtil.compiler.cs b/src/IKVM.Runtime/MethodHandleUtil.compiler.cs index 01ef18ff1..4772fd86e 100644 --- a/src/IKVM.Runtime/MethodHandleUtil.compiler.cs +++ b/src/IKVM.Runtime/MethodHandleUtil.compiler.cs @@ -1,14 +1,7 @@ -using System; - -#if IMPORTER -using IKVM.Reflection; -using IKVM.Reflection.Emit; - -using Type = IKVM.Reflection.Type; -#else -using System.Reflection; +using System.Reflection; using System.Reflection.Emit; -#endif + +using IKVM.CoreLib.Symbols; namespace IKVM.Runtime { @@ -16,12 +9,12 @@ namespace IKVM.Runtime partial class MethodHandleUtil { - internal void EmitCallDelegateInvokeMethod(CodeEmitter ilgen, Type delegateType) + internal void EmitCallDelegateInvokeMethod(CodeEmitter ilgen, ITypeSymbol delegateType) { if (delegateType.IsGenericType) { // MONOBUG we don't look at the invoke method directly here, because Mono doesn't support GetParameters() on a builder instantiation - Type[] typeArgs = delegateType.GetGenericArguments(); + var typeArgs = delegateType.GetGenericArguments(); if (IsPackedArgsContainer(typeArgs[typeArgs.Length - 1])) { WrapArgs(ilgen, typeArgs[typeArgs.Length - 1]); @@ -31,24 +24,24 @@ internal void EmitCallDelegateInvokeMethod(CodeEmitter ilgen, Type delegateType) WrapArgs(ilgen, typeArgs[typeArgs.Length - 2]); } } + ilgen.Emit(OpCodes.Callvirt, GetDelegateInvokeMethod(delegateType)); } - private void WrapArgs(CodeEmitter ilgen, Type type) + private void WrapArgs(CodeEmitter ilgen, ITypeSymbol type) { - Type last = type.GetGenericArguments()[MaxArity - 1]; + var last = type.GetGenericArguments()[MaxArity - 1]; if (IsPackedArgsContainer(last)) - { WrapArgs(ilgen, last); - } + ilgen.Emit(OpCodes.Newobj, GetDelegateOrPackedArgsConstructor(type)); } - internal MethodInfo GetDelegateInvokeMethod(Type delegateType) + internal IMethodSymbol GetDelegateInvokeMethod(ITypeSymbol delegateType) { if (ReflectUtil.ContainsTypeBuilder(delegateType)) { - return TypeBuilder.GetMethod(delegateType, delegateType.GetGenericTypeDefinition().GetMethod("Invoke")); + return delegateType.GetGenericTypeDefinition().GetMethod("Invoke"); } else { @@ -56,16 +49,16 @@ internal MethodInfo GetDelegateInvokeMethod(Type delegateType) } } - internal ConstructorInfo GetDelegateConstructor(Type delegateType) + internal IConstructorSymbol GetDelegateConstructor(ITypeSymbol delegateType) { return GetDelegateOrPackedArgsConstructor(delegateType); } - private ConstructorInfo GetDelegateOrPackedArgsConstructor(Type type) + private IConstructorSymbol GetDelegateOrPackedArgsConstructor(ITypeSymbol type) { if (ReflectUtil.ContainsTypeBuilder(type)) { - return TypeBuilder.GetConstructor(type, type.GetGenericTypeDefinition().GetConstructors()[0]); + return type.GetGenericTypeDefinition().GetConstructors()[0]; } else { @@ -74,26 +67,24 @@ private ConstructorInfo GetDelegateOrPackedArgsConstructor(Type type) } // for delegate types used for "ldc " we don't want ghost arrays to be erased - internal Type CreateDelegateTypeForLoadConstant(RuntimeJavaType[] args, RuntimeJavaType ret) + internal ITypeSymbol CreateDelegateTypeForLoadConstant(RuntimeJavaType[] args, RuntimeJavaType ret) { - Type[] typeArgs = new Type[args.Length]; + var typeArgs = new ITypeSymbol[args.Length]; for (int i = 0; i < args.Length; i++) - { typeArgs[i] = TypeWrapperToTypeForLoadConstant(args[i]); - } + return CreateDelegateType(typeArgs, TypeWrapperToTypeForLoadConstant(ret)); } - private Type TypeWrapperToTypeForLoadConstant(RuntimeJavaType tw) + ITypeSymbol TypeWrapperToTypeForLoadConstant(RuntimeJavaType tw) { if (tw.IsGhostArray) { int dims = tw.ArrayRank; while (tw.IsArray) - { tw = tw.ElementTypeWrapper; - } - return RuntimeArrayJavaType.MakeArrayType(tw.TypeAsSignatureType, dims); + + return tw.TypeAsSignatureType.MakeArrayType(dims); } else { diff --git a/src/IKVM.Runtime/RuntimeArrayJavaType.cs b/src/IKVM.Runtime/RuntimeArrayJavaType.cs index 5295a96b6..72934b2d5 100644 --- a/src/IKVM.Runtime/RuntimeArrayJavaType.cs +++ b/src/IKVM.Runtime/RuntimeArrayJavaType.cs @@ -119,7 +119,7 @@ internal override ITypeSymbol TypeAsTBD while (arrayType == null) { bool prevFinished = finished; - var type = MakeArrayType(ultimateElementTypeWrapper.TypeAsArrayType, this.ArrayRank); + var type = ultimateElementTypeWrapper.TypeAsArrayType.MakeArrayType(ArrayRank); if (prevFinished) { // We were already finished prior to the call to MakeArrayType, so we can safely diff --git a/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs b/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs index 8ce64aa78..86cdeeb73 100644 --- a/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs +++ b/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs @@ -22,30 +22,20 @@ Jeroen Frijters */ using System; -using System.IO; using System.Collections.Generic; using System.Diagnostics; -using System.Threading; -using System.Runtime.Serialization; +using System.IO; +using System.Reflection; using System.Runtime.CompilerServices; +using System.Runtime.Serialization; +using System.Threading; -using IKVM.CoreLib.Diagnostics; using IKVM.Attributes; -using IKVM.Runtime.Syntax; +using IKVM.CoreLib.Diagnostics; using IKVM.CoreLib.Symbols; - - - -#if IMPORTER || EXPORTER -using IKVM.Reflection; - -using Type = IKVM.Reflection.Type; -#else +using IKVM.Runtime.Syntax; using IKVM.Runtime.Vfs; -using System.Reflection; -#endif - #if IMPORTER using IKVM.Tools.Importer; #endif @@ -1141,7 +1131,7 @@ internal List> GetPackageInfo() var list = new List>(); foreach (var m in assemblyLoader.Assembly.GetModules(false)) { - var attr = m.GetCustomAttributes(); + var attr = m.AsReflection().GetCustomAttributes(); foreach (var p in attr) list.Add(new KeyValuePair(p.jar, p.packages)); } diff --git a/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishContext.cs b/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishContext.cs index 1001ff45a..8c18ded24 100644 --- a/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishContext.cs +++ b/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishContext.cs @@ -24,6 +24,8 @@ Jeroen Frijters using System; using System.Collections.Generic; using System.Diagnostics; +using System.Reflection; +using System.Reflection.Emit; using IKVM.Attributes; using IKVM.ByteCode; @@ -36,8 +38,6 @@ Jeroen Frijters using DynamicOrAotTypeWrapper = IKVM.Tools.Importer.RuntimeImportByteCodeJavaType; #else -using System.Reflection; -using System.Reflection.Emit; using DynamicOrAotTypeWrapper = IKVM.Runtime.RuntimeByteCodeJavaType; #endif @@ -195,13 +195,13 @@ private void CreateGetCallerID() ilgen.DoEmit(); } - private void RegisterNestedTypeBuilder(TypeBuilder tb) + private void RegisterNestedTypeBuilder(ITypeSymbolBuilder tb) { - nestedTypeBuilders ??= new List(); + nestedTypeBuilders ??= new List(); nestedTypeBuilders.Add(tb); } - internal Type FinishImpl() + internal ITypeSymbol FinishImpl() { var methods = wrapper.GetMethods(); var fields = wrapper.GetFields(); @@ -665,7 +665,7 @@ internal Type FinishImpl() if (m.Annotations != null) { - ParameterBuilder returnParameter = null; + IParameterSymbolBuilder returnParameter = null; foreach (object[] def in m.Annotations) { var annotation = Annotation.Load(wrapper, def); @@ -741,7 +741,7 @@ internal Type FinishImpl() } #if !IMPORTER if (liveObjects != null) - context.Resolver.ResolveRuntimeType("IKVM.Runtime.LiveObjectHolder`1").GetField("values", BindingFlags.Static | BindingFlags.Public).AsReflection().SetValue(liveObjects.ToArray()); + context.Resolver.ResolveRuntimeType("IKVM.Runtime.LiveObjectHolder`1").GetField("values", BindingFlags.Static | BindingFlags.Public).AsReflection().SetValue(null, liveObjects.ToArray()); #endif } finally @@ -1005,7 +1005,7 @@ private bool EmitInterlockedCompareAndSet(RuntimeJavaMethod method, string field private void AddMethodParameterInfo(ClassFile.Method m, RuntimeJavaMethod mw, IMethodSymbolBuilder mb, out string[] parameterNames) { parameterNames = null; - ParameterBuilder[] parameterBuilders = null; + IParameterSymbolBuilder[] parameterBuilders = null; if (wrapper.ClassLoader.EmitSymbols #if IMPORTER @@ -1660,7 +1660,7 @@ public JniBuilder(RuntimeContext context) this.context = context ?? throw new ArgumentNullException(nameof(context)); } - Type LocalRefStructType => context.Resolver.ResolveRuntimeType("IKVM.Runtime.JNI.JNIFrame").AsReflection(); + ITypeSymbol LocalRefStructType => context.Resolver.ResolveRuntimeType("IKVM.Runtime.JNI.JNIFrame"); IMethodSymbol JniFuncPtrMethod => LocalRefStructType.GetMethod("GetFuncPtr"); @@ -1781,7 +1781,7 @@ internal void Generate(RuntimeByteCodeJavaType.FinishContext context, CodeEmitte ilGenerator.Emit(OpCodes.Ldsfld, methodPtr); - Type realRetType; + ITypeSymbol realRetType; if (retTypeWrapper == context.Context.PrimitiveJavaTypeFactory.BOOLEAN) realRetType = context.Context.Types.Byte; else if (retTypeWrapper.IsPrimitive) @@ -1940,16 +1940,16 @@ void ImplementInterfaces(RuntimeJavaType[] interfaces, List int // look for "magic" interfaces that imply a .NET interface if (iface.ClassLoader == context.JavaBase.TypeOfJavaLangObject.ClassLoader) { - if (iface.Name == "java.lang.Iterable" && !wrapper.ImplementsInterface(context.ClassLoaderFactory.GetJavaTypeFromType(context.Resolver.ResolveCoreType(typeof(System.Collections.IEnumerable).FullName).AsReflection()))) + if (iface.Name == "java.lang.Iterable" && !wrapper.ImplementsInterface(context.ClassLoaderFactory.GetJavaTypeFromType(context.Resolver.ResolveCoreType(typeof(System.Collections.IEnumerable).FullName)))) { var enumeratorType = context.ClassLoaderFactory.GetBootstrapClassLoader().TryLoadClassByName("ikvm.lang.IterableEnumerator"); if (enumeratorType != null) { - typeBuilder.AddInterfaceImplementation(context.Resolver.ResolveCoreType(typeof(System.Collections.IEnumerable).FullName).AsReflection()); + typeBuilder.AddInterfaceImplementation(context.Resolver.ResolveCoreType(typeof(System.Collections.IEnumerable).FullName)); // FXBUG we're using the same method name as the C# compiler here because both the .NET and Mono implementations of Xml serialization depend on this method name - var mb = typeBuilder.DefineMethod("System.Collections.IEnumerable.GetEnumerator", MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final | MethodAttributes.SpecialName, context.Resolver.ResolveCoreType(typeof(System.Collections.IEnumerator).FullName).AsReflection(), []); + var mb = typeBuilder.DefineMethod("System.Collections.IEnumerable.GetEnumerator", MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final | MethodAttributes.SpecialName, context.Resolver.ResolveCoreType(typeof(System.Collections.IEnumerator).FullName), []); context.AttributeHelper.HideFromJava(mb); - typeBuilder.DefineMethodOverride(mb, context.Resolver.ResolveCoreType(typeof(System.Collections.IEnumerable).FullName).GetMethod("GetEnumerator").AsReflection()); + typeBuilder.DefineMethodOverride(mb, context.Resolver.ResolveCoreType(typeof(System.Collections.IEnumerable).FullName).GetMethod("GetEnumerator")); var ilgen = context.CodeEmitterFactory.Create(mb); ilgen.Emit(OpCodes.Ldarg_0); var mw = enumeratorType.GetMethodWrapper("", "(Ljava.lang.Iterable;)V", false); @@ -1990,7 +1990,7 @@ void AddUnsupportedAbstractMethods() if (RuntimeManagedJavaType.IsUnsupportedAbstractMethod(mb)) GenerateUnsupportedAbstractMethodStub(mb); - var h = new Dictionary(); + var h = new Dictionary(); var tw = (RuntimeJavaType)wrapper; while (tw != null) { @@ -2096,7 +2096,7 @@ static bool IsCompatibleArgList(RuntimeJavaType[] caller, RuntimeJavaType[] call return false; } - void EmitCallerIDInitialization(CodeEmitter ilGenerator, FieldInfo callerIDField) + void EmitCallerIDInitialization(CodeEmitter ilGenerator, IFieldSymbol callerIDField) { var tw = context.JavaBase.TypeOfIkvmInternalCallerID; if (tw.InternalsVisibleTo(wrapper)) @@ -2193,7 +2193,7 @@ internal IMethodSymbolBuilder DefineThreadLocalType() int id = nestedTypeBuilders == null ? 0 : nestedTypeBuilders.Count; var tb = typeBuilder.DefineNestedType(NestedTypeName.ThreadLocal + id, TypeAttributes.NestedPrivate | TypeAttributes.Sealed, threadLocal.TypeAsBaseType); var fb = tb.DefineField("field", context.Types.Object, FieldAttributes.Private | FieldAttributes.Static); - fb.SetCustomAttribute(new CustomAttributeBuilder(context.Resolver.ResolveCoreType(typeof(ThreadStaticAttribute).FullName).GetConstructor([]).AsReflection(), [])); + fb.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveCoreType(typeof(ThreadStaticAttribute).FullName).GetConstructor([]), [])); var mbGet = tb.DefineMethod("get", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final, context.Types.Object, []); var ilgen = mbGet.GetILGenerator(); diff --git a/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.DelegateConstructorMethodWrapper.cs b/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.DelegateConstructorMethodWrapper.cs index a964df954..ea6793966 100644 --- a/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.DelegateConstructorMethodWrapper.cs +++ b/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.DelegateConstructorMethodWrapper.cs @@ -21,17 +21,11 @@ Jeroen Frijters jeroen@frijters.net */ -using System; - -#if IMPORTER -using IKVM.Reflection; -using IKVM.Reflection.Emit; - -using Type = IKVM.Reflection.Type; -#else using System.Reflection; using System.Reflection.Emit; -#endif + +using IKVM.CoreLib.Symbols; +using IKVM.CoreLib.Symbols.Emit; namespace IKVM.Runtime { @@ -45,8 +39,8 @@ private sealed partial class JavaTypeImpl sealed class DelegateConstructorMethodWrapper : RuntimeJavaMethod { - MethodBuilder constructor; - MethodInfo invoke; + IMethodSymbolBuilder constructor; + IMethodSymbol invoke; /// /// Initializes a new instance. @@ -59,14 +53,14 @@ internal DelegateConstructorMethodWrapper(RuntimeByteCodeJavaType tw, ClassFile. } - internal void DoLink(TypeBuilder typeBuilder) + internal void DoLink(ITypeSymbolBuilder typeBuilder) { var attribs = MethodAttributes.HideBySig | MethodAttributes.Public; - constructor = ReflectUtil.DefineConstructor(typeBuilder, attribs, new Type[] { DeclaringType.Context.Types.Object, DeclaringType.Context.Types.IntPtr }); + constructor = ReflectUtil.DefineConstructor(typeBuilder, attribs, [DeclaringType.Context.Types.Object, DeclaringType.Context.Types.IntPtr]); constructor.SetImplementationFlags(MethodImplAttributes.Runtime); var mw = GetParameters()[0].GetMethods()[0]; mw.Link(); - invoke = (MethodInfo)mw.GetMethod(); + invoke = (IMethodSymbol)mw.GetMethod(); } internal override void EmitNewobj(CodeEmitter ilgen) diff --git a/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.DelegateInvokeStubMethodWrapper.cs b/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.DelegateInvokeStubMethodWrapper.cs index 7e4a7f3ec..ad9115d70 100644 --- a/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.DelegateInvokeStubMethodWrapper.cs +++ b/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.DelegateInvokeStubMethodWrapper.cs @@ -21,21 +21,18 @@ Jeroen Frijters jeroen@frijters.net */ -using System; +using System.Reflection; +using System.Reflection.Emit; using IKVM.Attributes; using IKVM.CoreLib.Symbols; +using IKVM.CoreLib.Symbols.Emit; #if IMPORTER -using IKVM.Reflection; -using IKVM.Reflection.Emit; using IKVM.Tools.Importer; using Type = IKVM.Reflection.Type; using RuntimeDynamicOrImportJavaType = IKVM.Tools.Importer.RuntimeImportByteCodeJavaType; -#else -using System.Reflection; -using System.Reflection.Emit; #endif namespace IKVM.Runtime @@ -64,7 +61,7 @@ internal DelegateInvokeStubMethodWrapper(RuntimeJavaType declaringType, ITypeSym this.delegateType = delegateType; } - internal MethodInfo DoLink(TypeBuilder tb) + internal IMethodSymbol DoLink(ITypeSymbolBuilder tb) { var mw = DeclaringType.GetMethodWrapper("Invoke", Signature, true); @@ -74,7 +71,7 @@ internal MethodInfo DoLink(TypeBuilder tb) for (int i = 0; i < parameterTypes.Length; i++) parameterTypes[i] = parameters[i].ParameterType; - var mb = tb.DefineMethod(Name, MethodAttributes.Public, invoke.ReturnType.AsReflection(), parameterTypes.AsReflection()); + var mb = tb.DefineMethod(Name, MethodAttributes.Public, invoke.ReturnType, parameterTypes); DeclaringType.Context.AttributeHelper.HideFromReflection(mb); var ilgen = DeclaringType.Context.CodeEmitterFactory.Create(mb); if (mw == null || mw.IsStatic || !mw.IsPublic) @@ -90,7 +87,7 @@ internal MethodInfo DoLink(TypeBuilder tb) if (parameters[i].ParameterType.IsByRef) { var elemType = parameters[i].ParameterType.GetElementType(); - var local = ilgen.DeclareLocal(RuntimeArrayJavaType.MakeArrayType(elemType, 1)); + var local = ilgen.DeclareLocal(elemType.MakeArrayType(1)); byrefs[i] = local; ilgen.Emit(OpCodes.Ldc_I4_1); ilgen.Emit(OpCodes.Newarr, elemType); diff --git a/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.cs b/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.cs index 5f5053619..af8b03ae0 100644 --- a/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.cs +++ b/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.cs @@ -26,20 +26,18 @@ Jeroen Frijters using System.Diagnostics; using System.Collections.Concurrent; +using System.Reflection; +using System.Reflection.Emit; + using IKVM.Attributes; using IKVM.CoreLib.Symbols.Emit; using IKVM.CoreLib.Symbols; #if IMPORTER -using IKVM.Reflection; -using IKVM.Reflection.Emit; using IKVM.Tools.Importer; -using Type = IKVM.Reflection.Type; using RuntimeDynamicOrImportJavaType = IKVM.Tools.Importer.RuntimeImportByteCodeJavaType; #else -using System.Reflection; -using System.Reflection.Emit; using RuntimeDynamicOrImportJavaType = IKVM.Runtime.RuntimeByteCodeJavaType; #endif @@ -1109,11 +1107,13 @@ internal override IFieldSymbol LinkField(RuntimeJavaField fw) field = DefineField(realFieldName, fw.FieldTypeWrapper, attribs, fld.IsVolatile); } + if (fld.IsTransient) { - var transientAttrib = new CustomAttributeBuilder(wrapper.Context.Resolver.ResolveCoreType(typeof(NonSerializedAttribute).FullName).GetConstructor([]).AsReflection(), []); + var transientAttrib = wrapper.Context.Resolver.Symbols.CreateCustomAttribute(wrapper.Context.Resolver.ResolveCoreType(typeof(NonSerializedAttribute).FullName).GetConstructor([]), []); field.SetCustomAttribute(transientAttrib); } + #if IMPORTER { // if the Java modifiers cannot be expressed in .NET, we emit the Modifiers attribute to store @@ -1137,8 +1137,7 @@ internal override IFieldSymbol LinkField(RuntimeJavaField fw) IFieldSymbolBuilder DefineField(string name, RuntimeJavaType tw, FieldAttributes attribs, bool isVolatile) { - var modreq = isVolatile ? [wrapper.Context.Types.IsVolatile] : []; - return typeBuilder.DefineField(name, tw.TypeAsSignatureType, modreq, wrapper.GetModOpt(tw, false), attribs); + return typeBuilder.DefineField(name, tw.TypeAsSignatureType, isVolatile ? [wrapper.Context.Types.IsVolatile] : [], wrapper.GetModOpt(tw, false), attribs); } internal override void EmitRunClassConstructor(CodeEmitter ilgen) @@ -1301,7 +1300,7 @@ FinishedTypeImpl FinishCore() privateInterfaceMethods.CreateType(); } #endif - var finishedClinitMethod = (MethodInfo)clinitMethod; + var finishedClinitMethod = (IMethodSymbol)clinitMethod; #if !IMPORTER if (finishedClinitMethod != null) { @@ -2129,7 +2128,7 @@ bool IsAccessibleInternal(RuntimeJavaMethod mw) return mw.IsInternal && mw.DeclaringType.InternalsVisibleTo(wrapper); } - static IMethodSymbol LinkAndGetMethod(RuntimeJavaMethod mw) + static IMethodBaseSymbol LinkAndGetMethod(RuntimeJavaMethod mw) { mw.Link(); return mw.GetMethod(); @@ -2288,7 +2287,7 @@ static IMethodSymbol GetBaseFinalizeMethod(RuntimeJavaType wrapper) } var type = wrapper.TypeAsBaseType; - var baseFinalize = type.GetMethod("__", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, [], null); + var baseFinalize = type.GetMethod("__", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, []); if (baseFinalize != null) return baseFinalize; @@ -2716,7 +2715,7 @@ IMethodSymbolBuilder GenerateMethod(int index, ClassFile.Method m, ref bool setM { bool needFinalize = false; bool needDispatch = false; - MethodInfo baseFinalize = null; + IMethodSymbol baseFinalize = null; if (baseMethods[index] != null && ReferenceEquals(m.Name, StringConstants.FINALIZE) && ReferenceEquals(m.Signature, StringConstants.SIG_VOID)) { baseFinalize = GetBaseFinalizeMethod(wrapper.BaseTypeWrapper); @@ -2805,7 +2804,7 @@ IMethodSymbolBuilder GenerateMethod(int index, ClassFile.Method m, ref bool setM } else if (subsequent || methods[index].IsExplicitOverride || baseMethod.RealName != name) { - typeBuilder.DefineMethodOverride(mb, (MethodInfo)baseMethod.GetMethod()); + typeBuilder.DefineMethodOverride(mb, (IMethodSymbol)baseMethod.GetMethod()); } // the non-primary base methods always need an explicit method override diff --git a/src/IKVM.Runtime/RuntimeByteCodeJavaType.cs b/src/IKVM.Runtime/RuntimeByteCodeJavaType.cs index 5eb072d7c..d7801d44f 100644 --- a/src/IKVM.Runtime/RuntimeByteCodeJavaType.cs +++ b/src/IKVM.Runtime/RuntimeByteCodeJavaType.cs @@ -24,6 +24,8 @@ Jeroen Frijters using System; using System.Collections.Generic; using System.Diagnostics; +using System.Reflection; +using System.Reflection.Emit; using IKVM.Attributes; using IKVM.CoreLib.Diagnostics; @@ -31,16 +33,9 @@ Jeroen Frijters using IKVM.CoreLib.Symbols.Emit; #if IMPORTER -using IKVM.Reflection; -using IKVM.Reflection.Emit; using IKVM.Tools.Importer; - -using Type = IKVM.Reflection.Type; using ProtectionDomain = System.Object; #else -using System.Reflection; -using System.Reflection.Emit; - using ProtectionDomain = java.security.ProtectionDomain; #endif @@ -406,7 +401,7 @@ void GenerateOverrideStub(ITypeSymbolBuilder typeBuilder, RuntimeJavaMethod base Debug.Assert(!baseMethod.HasCallerID); var overrideStub = baseMethod.GetDefineMethodHelper().DefineMethod(this, typeBuilder, "__" + baseMethod.DeclaringType.Name + "::" + baseMethod.Name, MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final); - typeBuilder.DefineMethodOverride(overrideStub, (MethodInfo)baseMethod.GetMethod()); + typeBuilder.DefineMethodOverride(overrideStub, (IMethodSymbol)baseMethod.GetMethod()); var stubargs = baseMethod.GetParameters(); var targetArgs = targetMethod.GetParameters(); @@ -939,7 +934,7 @@ static ITypeSymbol GetModOptHelper(RuntimeJavaType tw) if (tw.IsArray) { - return RuntimeArrayJavaType.MakeArrayType(GetModOptHelper(tw.GetUltimateElementTypeWrapper()), tw.ArrayRank); + return GetModOptHelper(tw.GetUltimateElementTypeWrapper()).MakeArrayType(tw.ArrayRank); } else if (tw.IsGhost) { diff --git a/src/IKVM.Runtime/RuntimeJavaType.cs b/src/IKVM.Runtime/RuntimeJavaType.cs index 319b7455a..53d61e830 100644 --- a/src/IKVM.Runtime/RuntimeJavaType.cs +++ b/src/IKVM.Runtime/RuntimeJavaType.cs @@ -146,7 +146,7 @@ ITypeSymbol GetClassLiteralType() while (tw.IsArray) tw = tw.ElementTypeWrapper; - return RuntimeArrayJavaType.MakeArrayType(tw.TypeAsTBD, rank); + return tw.TypeAsTBD.MakeArrayType(rank); } else { @@ -929,7 +929,7 @@ internal ITypeSymbol TypeAsSignatureType return ((RuntimeUnloadableJavaType)this).MissingType ?? context.Types.Object; if (IsGhostArray) - return RuntimeArrayJavaType.MakeArrayType(context.Types.Object, ArrayRank); + return context.Types.Object.MakeArrayType(ArrayRank); return TypeAsTBD; } @@ -953,7 +953,7 @@ internal ITypeSymbol TypeAsLocalOrStackType } if (IsGhostArray) - return RuntimeArrayJavaType.MakeArrayType(context.Types.Object, ArrayRank); + return context.Types.Object.MakeArrayType(ArrayRank); return TypeAsTBD; } @@ -968,7 +968,7 @@ internal ITypeSymbol TypeAsArrayType return context.Types.Object; if (IsGhostArray) - return RuntimeArrayJavaType.MakeArrayType(context.Types.Object, ArrayRank); + return context.Types.Object.MakeArrayType(ArrayRank); return TypeAsTBD; } @@ -1318,7 +1318,7 @@ internal virtual void EmitCheckcast(CodeEmitter ilgen) } ilgen.EmitLdc_I4(rank); ilgen.Emit(System.Reflection.Emit.OpCodes.Call, tw.TypeAsTBD.GetMethod("CastArray")); - ilgen.Emit(System.Reflection.Emit.OpCodes.Castclass, RuntimeArrayJavaType.MakeArrayType(context.Types.Object, rank)); + ilgen.Emit(System.Reflection.Emit.OpCodes.Castclass, context.Types.Object.MakeArrayType(rank)); } else { diff --git a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs index e05682159..dc1156c11 100644 --- a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs @@ -25,23 +25,15 @@ Jeroen Frijters using System.Collections.Generic; using System.Diagnostics; using System.Linq; +using System.Reflection; +using System.Reflection.Emit; -using IKVM.CoreLib.Diagnostics; -using IKVM.CoreLib.Symbols; using IKVM.Attributes; -using IKVM.Runtime.Syntax; using IKVM.ByteCode; +using IKVM.CoreLib.Diagnostics; +using IKVM.CoreLib.Symbols; using IKVM.CoreLib.Symbols.Emit; - -#if IMPORTER || EXPORTER -using IKVM.Reflection; -using IKVM.Reflection.Emit; - -using Type = IKVM.Reflection.Type; -#else -using System.Reflection; -using System.Reflection.Emit; -#endif +using IKVM.Runtime.Syntax; #if IMPORTER using IKVM.Tools.Importer; @@ -1109,7 +1101,7 @@ internal override string[] GetEnclosingMethod() { var enc = Context.AttributeHelper.GetEnclosingMethodAttribute(type); if (enc != null) - return new string[] { enc.ClassName, enc.MethodName, enc.MethodSignature }; + return [enc.ClassName, enc.MethodName, enc.MethodSignature]; return null; } @@ -1125,7 +1117,7 @@ object[] CastArray(CustomAttribute[] l) internal override object[] GetDeclaredAnnotations() { - return CastArray(type.GetCustomAttribute(false)); + return CastArray(type.GetCustomAttributes(false)); } internal override object[] GetMethodAnnotations(RuntimeJavaMethod mw) diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.ByRefJavaMethod.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.ByRefJavaMethod.cs index ee8ee78f2..fbafd618a 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.ByRefJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.ByRefJavaMethod.cs @@ -21,18 +21,11 @@ Jeroen Frijters jeroen@frijters.net */ +using System.Reflection.Emit; + using IKVM.Attributes; using IKVM.CoreLib.Symbols; -#if IMPORTER || EXPORTER -using IKVM.Reflection; -using IKVM.Reflection.Emit; - -using Type = IKVM.Reflection.Type; -#else -using System.Reflection.Emit; -#endif - namespace IKVM.Runtime { @@ -96,7 +89,7 @@ void ConvertByRefArgs(CodeEmitter ilgen) { var type = args[i]; if (type.IsByRef) - type = RuntimeArrayJavaType.MakeArrayType(type.GetElementType(), 1); + type = type.GetElementType().MakeArrayType(1); locals[i] = ilgen.DeclareLocal(type); ilgen.Emit(OpCodes.Stloc, locals[i]); diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.CloneJavaMethod.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.CloneJavaMethod.cs index 669a19174..d50ce108f 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.CloneJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.CloneJavaMethod.cs @@ -22,18 +22,10 @@ Jeroen Frijters */ using System; - -using IKVM.Attributes; - -#if IMPORTER || EXPORTER -using IKVM.Reflection; -using IKVM.Reflection.Emit; - -using Type = IKVM.Reflection.Type; -#else using System.Reflection; using System.Reflection.Emit; -#endif + +using IKVM.Attributes; namespace IKVM.Runtime { @@ -71,7 +63,7 @@ internal override void EmitCall(CodeEmitter ilgen) ilgen.MarkLabel(label2); ilgen.EmitThrow("java.lang.NullPointerException"); ilgen.MarkLabel(label1); - ilgen.Emit(OpCodes.Call, DeclaringType.Context.Types.Object.GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic, null, [], null)); + ilgen.Emit(OpCodes.Call, DeclaringType.Context.Types.Object.GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic, [])); } internal override void EmitCallvirt(CodeEmitter ilgen) diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.DelegateInnerClassJavaType.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.DelegateInnerClassJavaType.cs index 6d00693b2..ed2ff469c 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.DelegateInnerClassJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.DelegateInnerClassJavaType.cs @@ -67,7 +67,7 @@ internal DelegateInnerClassJavaType(RuntimeContext context, string name, ITypeSy if (parameterType.IsByRef) { flags |= MemberFlags.DelegateInvokeWithByRefParameter; - parameterType = RuntimeArrayJavaType.MakeArrayType(parameterType.GetElementType(), 1); + parameterType = parameterType.GetElementType().MakeArrayType(1); } argTypeWrappers[i] = Context.ClassLoaderFactory.GetJavaTypeFromType(parameterType); diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.EnumEnumJavaType.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.EnumEnumJavaType.cs index 9d5dc4e1a..a3412f98c 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.EnumEnumJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.EnumEnumJavaType.cs @@ -23,21 +23,12 @@ Jeroen Frijters */ using System; using System.Collections.Generic; +using System.Reflection; +using System.Reflection.Emit; using IKVM.Attributes; using IKVM.CoreLib.Symbols; - -#if IMPORTER || EXPORTER -using IKVM.Reflection; -using IKVM.Reflection.Emit; - -using Type = IKVM.Reflection.Type; -#else -using System.Reflection; -using System.Reflection.Emit; -#endif - #if IMPORTER using IKVM.Tools.Importer; #endif diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.cs index 0eaac509b..7d9681430 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.cs @@ -24,19 +24,12 @@ Jeroen Frijters using System; using System.Collections.Generic; using System.Diagnostics; +using System.Reflection; +using System.Reflection.Emit; using IKVM.Attributes; using IKVM.CoreLib.Symbols; - -#if IMPORTER || EXPORTER -using IKVM.Reflection; -using IKVM.Reflection.Emit; - -using Type = IKVM.Reflection.Type; -#else -using System.Reflection; -using System.Reflection.Emit; -#endif +using IKVM.CoreLib.Symbols.Emit; namespace IKVM.Runtime { @@ -308,7 +301,7 @@ internal static RuntimeJavaType Create(RuntimeContext context, ITypeSymbol type, Debug.Assert(!type.IsByRef, type.FullName); Debug.Assert(!type.IsPointer, type.FullName); Debug.Assert(!type.Name.EndsWith("[]"), type.FullName); - Debug.Assert(type.AsReflection() is not TypeBuilder, type.FullName); + Debug.Assert(type is not ITypeSymbolBuilder, type.FullName); Debug.Assert(!Context.AttributeHelper.IsJavaModule(type.Module)); this.type = type; @@ -605,7 +598,11 @@ static bool IsPointerType(ITypeSymbol type) type = type.GetElementType(); } - return type.IsUnmanagedFunctionPointer; +#if IMPORTER || EXPORTER + return type.IsFunctionPointer; +#else + return false; +#endif } bool MakeMethodDescriptor(IMethodBaseSymbol mb, out string name, out string sig, out RuntimeJavaType[] args, out RuntimeJavaType ret) @@ -637,7 +634,7 @@ bool MakeMethodDescriptor(IMethodBaseSymbol mb, out string name, out string sig, if (type.IsByRef) { - type = RuntimeArrayJavaType.MakeArrayType(type.GetElementType(), 1); + type = type.GetElementType().MakeArrayType(1); if (mb.IsAbstract) { // Since we cannot override methods with byref arguments, we don't report abstract @@ -655,7 +652,7 @@ bool MakeMethodDescriptor(IMethodBaseSymbol mb, out string name, out string sig, sb.Append(tw.SigName); } sb.Append(')'); - if (mb is ConstructorInfo) + if (mb is IConstructorSymbol) { ret = Context.PrimitiveJavaTypeFactory.VOID; name = mb.IsStatic ? "" : ""; diff --git a/src/IKVM.Runtime/RuntimeUnloadableJavaType.cs b/src/IKVM.Runtime/RuntimeUnloadableJavaType.cs index 7c4e3cf26..4dc3d85bd 100644 --- a/src/IKVM.Runtime/RuntimeUnloadableJavaType.cs +++ b/src/IKVM.Runtime/RuntimeUnloadableJavaType.cs @@ -25,14 +25,6 @@ Jeroen Frijters using IKVM.CoreLib.Symbols; -#if IMPORTER || EXPORTER -using IKVM.Reflection; -using IKVM.Reflection.Emit; - -using Type = IKVM.Reflection.Type; -#else -#endif - #if IMPORTER using IKVM.Tools.Importer; #endif @@ -150,10 +142,10 @@ internal void SetCustomModifier(ITypeSymbol type) #if EMITTERS - internal Type GetCustomModifier(RuntimeJavaTypeFactory context) + internal ITypeSymbol GetCustomModifier(RuntimeJavaTypeFactory context) { // we don't need to lock, because we're only supposed to be called while holding the finish lock - return customModifier ?? (customModifier = context.DefineUnloadable(this.Name)); + return customModifier ??= context.DefineUnloadable(Name); } internal override void EmitCheckcast(CodeEmitter ilgen) diff --git a/src/IKVM.Runtime/Serialization.cs b/src/IKVM.Runtime/Serialization.cs index dc7142b5e..c11630dbb 100644 --- a/src/IKVM.Runtime/Serialization.cs +++ b/src/IKVM.Runtime/Serialization.cs @@ -24,20 +24,15 @@ Jeroen Frijters using System; using System.Runtime.Serialization; using System.Security; +using System.Reflection; +using System.Reflection.Emit; + using IKVM.CoreLib.Symbols; using IKVM.CoreLib.Symbols.Emit; - - #if IMPORTER -using IKVM.Reflection; -using IKVM.Reflection.Emit; using IKVM.Tools.Importer; - -using Type = IKVM.Reflection.Type; #else -using System.Reflection; -using System.Reflection.Emit; #endif namespace IKVM.Runtime @@ -48,8 +43,8 @@ class Serialization readonly RuntimeContext context; - CustomAttributeBuilder serializableAttribute; - CustomAttributeBuilder securityCriticalAttribute; + ICustomAttributeBuilder serializableAttribute; + ICustomAttributeBuilder securityCriticalAttribute; RuntimeJavaType typeOfISerializable; RuntimeJavaType typeofIObjectreference; RuntimeJavaType typeOfExternalizable; @@ -63,13 +58,13 @@ public Serialization(RuntimeContext context) this.context = context ?? throw new ArgumentNullException(nameof(context)); } - CustomAttributeBuilder SerializableAttribute => serializableAttribute ??= new CustomAttributeBuilder(context.Resolver.ResolveCoreType(typeof(SerializableAttribute).FullName).GetConstructor([]).AsReflection(), []); + ICustomAttributeBuilder SerializableAttribute => serializableAttribute ??= context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveCoreType(typeof(SerializableAttribute).FullName).GetConstructor([]), []); - CustomAttributeBuilder SecurityCriticalAttribute => securityCriticalAttribute ??= new CustomAttributeBuilder(context.Resolver.ResolveCoreType(typeof(SecurityCriticalAttribute).FullName).GetConstructor([]).AsReflection(), []); + ICustomAttributeBuilder SecurityCriticalAttribute => securityCriticalAttribute ??= context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveCoreType(typeof(SecurityCriticalAttribute).FullName).GetConstructor([]), []); - RuntimeJavaType TypeOfISerializable => typeOfISerializable ??= context.ClassLoaderFactory.GetJavaTypeFromType(context.Resolver.ResolveCoreType(typeof(ISerializable).FullName).AsReflection()); + RuntimeJavaType TypeOfISerializable => typeOfISerializable ??= context.ClassLoaderFactory.GetJavaTypeFromType(context.Resolver.ResolveCoreType(typeof(ISerializable).FullName)); - RuntimeJavaType TypeOfIObjectReference => typeofIObjectreference ??= context.ClassLoaderFactory.GetJavaTypeFromType(context.Resolver.ResolveCoreType(typeof(IObjectReference).FullName).AsReflection()); + RuntimeJavaType TypeOfIObjectReference => typeofIObjectreference ??= context.ClassLoaderFactory.GetJavaTypeFromType(context.Resolver.ResolveCoreType(typeof(IObjectReference).FullName)); RuntimeJavaType TypeOfExternalizable => typeOfExternalizable ??= context.ClassLoaderFactory.LoadClassCritical("java.io.Externalizable"); @@ -153,7 +148,7 @@ internal IMethodSymbolBuilder AddAutomagicSerialization(RuntimeByteCodeJavaType return serializationCtor; } - internal IMethodSymbolBuilder AddAutomagicSerializationToWorkaroundBaseClass(ITypeSymbolBuilder typeBuilderWorkaroundBaseClass, MethodBase baseCtor) + internal IMethodSymbolBuilder AddAutomagicSerializationToWorkaroundBaseClass(ITypeSymbolBuilder typeBuilderWorkaroundBaseClass, IMethodBaseSymbol baseCtor) { if (typeBuilderWorkaroundBaseClass.BaseType.IsSerializable) { @@ -177,10 +172,10 @@ internal void AddGetObjectData(ITypeSymbolBuilder tb) ? MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final : MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.CheckAccessOnOverride; tb.AddInterfaceImplementation(context.Resolver.ResolveCoreType(typeof(ISerializable).FullName)); - var getObjectData = tb.DefineMethod(name, attr, null, new ITypeSymbol[] { context.Resolver.ResolveCoreType(typeof(SerializationInfo).FullName), context.Resolver.ResolveCoreType(typeof(StreamingContext).FullName).AsReflection() }); + var getObjectData = tb.DefineMethod(name, attr, null, [context.Resolver.ResolveCoreType(typeof(SerializationInfo).FullName), context.Resolver.ResolveCoreType(typeof(StreamingContext).FullName)]); getObjectData.SetCustomAttribute(SecurityCriticalAttribute); context.AttributeHelper.HideFromJava(getObjectData); - tb.DefineMethodOverride(getObjectData, context.Resolver.ResolveCoreType(typeof(ISerializable).FullName).GetMethod("GetObjectData").AsReflection()); + tb.DefineMethodOverride(getObjectData, context.Resolver.ResolveCoreType(typeof(ISerializable).FullName).GetMethod("GetObjectData")); var ilgen = context.CodeEmitterFactory.Create(getObjectData); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Ldarg_1); @@ -194,9 +189,9 @@ internal void AddGetObjectData(ITypeSymbolBuilder tb) IMethodSymbolBuilder AddConstructor(ITypeSymbolBuilder tb, RuntimeJavaMethod defaultConstructor, IMethodBaseSymbol serializationConstructor, bool callReadObject) { - var ctor = ReflectUtil.DefineConstructor(tb, MethodAttributes.Family, new ITypeSymbol[] { context.Resolver.ResolveCoreType(typeof(SerializationInfo).FullName).AsReflection(), context.Resolver.ResolveCoreType(typeof(StreamingContext).FullName).AsReflection() }); + var ctor = ReflectUtil.DefineConstructor(tb, MethodAttributes.Family, [context.Resolver.ResolveCoreType(typeof(SerializationInfo).FullName), context.Resolver.ResolveCoreType(typeof(StreamingContext).FullName)]); context.AttributeHelper.HideFromJava(ctor); - CodeEmitter ilgen = context.CodeEmitterFactory.Create(ctor); + var ilgen = context.CodeEmitterFactory.Create(ctor); ilgen.Emit(OpCodes.Ldarg_0); if (defaultConstructor != null) { @@ -227,11 +222,11 @@ void AddReadResolve(RuntimeByteCodeJavaType wrapper, ITypeSymbolBuilder tb) var mw = wrapper.GetMethodWrapper("readResolve", "()Ljava.lang.Object;", false); if (mw != null && !wrapper.IsSubTypeOf(TypeOfIObjectReference)) { - tb.AddInterfaceImplementation(wrapper.Context.Resolver.ResolveCoreType(typeof(IObjectReference).FullName).AsReflection()); - var getRealObject = tb.DefineMethod("IObjectReference.GetRealObject", MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final, wrapper.Context.Types.Object, new ITypeSymbol[] { wrapper.Context.Resolver.ResolveCoreType(typeof(StreamingContext).FullName) }); + tb.AddInterfaceImplementation(wrapper.Context.Resolver.ResolveCoreType(typeof(IObjectReference).FullName)); + var getRealObject = tb.DefineMethod("IObjectReference.GetRealObject", MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final, wrapper.Context.Types.Object, [wrapper.Context.Resolver.ResolveCoreType(typeof(StreamingContext).FullName)]); getRealObject.SetCustomAttribute(SecurityCriticalAttribute); wrapper.Context.AttributeHelper.HideFromJava(getRealObject); - tb.DefineMethodOverride(getRealObject, wrapper.Context.Resolver.ResolveCoreType(typeof(IObjectReference).FullName).GetMethod("GetRealObject").AsReflection()); + tb.DefineMethodOverride(getRealObject, wrapper.Context.Resolver.ResolveCoreType(typeof(IObjectReference).FullName).GetMethod("GetRealObject")); var ilgen = context.CodeEmitterFactory.Create(getRealObject); mw.Link(); if (!wrapper.IsFinal) @@ -256,11 +251,11 @@ void AddReadResolve(RuntimeByteCodeJavaType wrapper, ITypeSymbolBuilder tb) void RemoveReadResolve(ITypeSymbolBuilder tb) { - tb.AddInterfaceImplementation(context.Resolver.ResolveCoreType(typeof(IObjectReference).FullName).AsReflection()); + tb.AddInterfaceImplementation(context.Resolver.ResolveCoreType(typeof(IObjectReference).FullName)); var getRealObject = tb.DefineMethod("IObjectReference.GetRealObject", MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final, context.Types.Object, [context.Resolver.ResolveCoreType(typeof(StreamingContext).FullName)]); getRealObject.SetCustomAttribute(SecurityCriticalAttribute); context.AttributeHelper.HideFromJava(getRealObject); - tb.DefineMethodOverride(getRealObject, context.Resolver.ResolveCoreType(typeof(IObjectReference).FullName).GetMethod("GetRealObject").AsReflection()); + tb.DefineMethodOverride(getRealObject, context.Resolver.ResolveCoreType(typeof(IObjectReference).FullName).GetMethod("GetRealObject")); var ilgen = context.CodeEmitterFactory.Create(getRealObject); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Ret); diff --git a/src/IKVM.Runtime/compiler.cs b/src/IKVM.Runtime/compiler.cs index 54e99b691..c209e71e2 100644 --- a/src/IKVM.Runtime/compiler.cs +++ b/src/IKVM.Runtime/compiler.cs @@ -25,6 +25,7 @@ Jeroen Frijters using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.SymbolStore; +using System.Reflection; using IKVM.CoreLib.Symbols; using IKVM.CoreLib.Symbols.Emit; @@ -33,11 +34,6 @@ Jeroen Frijters #if IMPORTER using IKVM.Tools.Importer; - -using Type = IKVM.Reflection.Type; -#else -using System.Reflection; -using System.Reflection.Emit; #endif using ExceptionTableEntry = IKVM.Runtime.ClassFile.Method.ExceptionTableEntry; @@ -112,13 +108,13 @@ public CompilerFactory(RuntimeContext context, bool bootstrap) public RuntimeJavaType Throwable => context.JavaBase.TypeOfjavaLangThrowable; - public IMethodSymbol UnmapExceptionMethod => unmapExceptionMethod ??= bootstrap ? (IMethodSymbol)Throwable.GetMethodWrapper("__", "(Ljava.lang.Throwable;)Ljava.lang.Throwable;", false).GetMethod() : Throwable.TypeAsBaseType.GetMethod("__", new ITypeSymbol[] { context.Types.Exception }); + public IMethodSymbol UnmapExceptionMethod => unmapExceptionMethod ??= bootstrap ? (IMethodSymbol)Throwable.GetMethodWrapper("__", "(Ljava.lang.Throwable;)Ljava.lang.Throwable;", false).GetMethod() : Throwable.TypeAsBaseType.GetMethod("__", [context.Types.Exception]); - public IMethodSymbol FixateExceptionMethod => fixateExceptionMethod ??= bootstrap ? (IMethodSymbol)Throwable.GetMethodWrapper("__", "(Ljava.lang.Throwable;)Ljava.lang.Throwable;", false).GetMethod() : Throwable.TypeAsBaseType.GetMethod("__", new ITypeSymbol[] { context.Types.Exception }); + public IMethodSymbol FixateExceptionMethod => fixateExceptionMethod ??= bootstrap ? (IMethodSymbol)Throwable.GetMethodWrapper("__", "(Ljava.lang.Throwable;)Ljava.lang.Throwable;", false).GetMethod() : Throwable.TypeAsBaseType.GetMethod("__", [context.Types.Exception]); public IMethodSymbol SuppressFillInStackTraceMethod => suppressFillInStackTraceMethod ??= bootstrap ? (IMethodSymbol)Throwable.GetMethodWrapper("__", "()V", false).GetMethod() : Throwable.TypeAsBaseType.GetMethod("__", []); - public IMethodSymbol GetTypeFromHandleMethod => getTypeFromHandleMethod ??= context.Types.Type.GetMethod("GetTypeFromHandle", BindingFlags.Static | BindingFlags.Public, [context.Types.RuntimeTypeHandle]); + public IMethodSymbol GetTypeFromHandleMethod => getTypeFromHandleMethod ??= context.Types.Type.GetMethod("GetTypeFromHandle", BindingFlags.Static | BindingFlags.Public, [context.Types.RuntimeTypeHandle]); public IMethodSymbol GetTypeMethod => getTypeMethod ??= context.Types.Object.GetMethod("GetType", BindingFlags.Public | BindingFlags.Instance, []); @@ -192,7 +188,7 @@ sealed class Compiler { ilGenerator.EmitLdarg(i + (m.IsStatic ? 0 : 1)); EmitDynamicCast(args[i]); - ilGenerator.Emit(OpCodes.Pop); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Pop); } } @@ -282,7 +278,7 @@ sealed class Compiler v.isArg = false; ilGenerator.EmitLdarg(arg); tw.EmitConvSignatureTypeToStackType(ilGenerator); - ilGenerator.Emit(OpCodes.Stloc, v.builder); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Stloc, v.builder); } } } @@ -342,7 +338,7 @@ private void Workaroundx64JitBug(RuntimeJavaType[] args) { // TODO prevent this from getting optimized away ilGenerator.EmitLdarga(i); - ilGenerator.Emit(OpCodes.Pop); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Pop); } } } @@ -416,9 +412,9 @@ internal void EmitRet(CodeEmitter ilgen) ilgen.MarkLabel(stub); if (local != null) { - ilgen.Emit(OpCodes.Ldloc, local); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldloc, local); } - ilgen.Emit(OpCodes.Ret); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ret); } } @@ -522,7 +518,7 @@ internal void Load(int i) switch (types[i]) { case StackType.Null: - compiler.ilGenerator.Emit(OpCodes.Ldnull); + compiler.ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldnull); break; case StackType.New: case StackType.FaultBlockException: @@ -530,10 +526,10 @@ internal void Load(int i) break; case StackType.This: case StackType.UnitializedThis: - compiler.ilGenerator.Emit(OpCodes.Ldarg_0); + compiler.ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); break; case StackType.Other: - compiler.ilGenerator.Emit(OpCodes.Ldloc, locals[i]); + compiler.ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldloc, locals[i]); break; default: throw new InvalidOperationException(); @@ -547,14 +543,14 @@ internal void Store(int i) case StackType.Null: case StackType.This: case StackType.UnitializedThis: - compiler.ilGenerator.Emit(OpCodes.Pop); + compiler.ilGenerator.Emit(System.Reflection.Emit.OpCodes.Pop); break; case StackType.New: case StackType.FaultBlockException: // objects aren't really there on the stack break; case StackType.Other: - compiler.ilGenerator.Emit(OpCodes.Stloc, locals[i]); + compiler.ilGenerator.Emit(System.Reflection.Emit.OpCodes.Stloc, locals[i]); break; default: throw new InvalidOperationException(); @@ -635,18 +631,18 @@ internal static void Compile(RuntimeByteCodeJavaType.FinishContext finish, Runti if (m.IsSynchronized && m.IsStatic) { clazz.EmitClassLiteral(ilGenerator); - ilGenerator.Emit(OpCodes.Dup); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Dup); CodeEmitterLocal monitor = ilGenerator.DeclareLocal(finish.Context.Types.Object); - ilGenerator.Emit(OpCodes.Stloc, monitor); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Stloc, monitor); ilGenerator.EmitMonitorEnter(); ilGenerator.BeginExceptionBlock(); var b = new Block(c, 0, int.MaxValue, -1, new List(), true); c.Compile(b, 0); b.Leave(); ilGenerator.BeginFinallyBlock(); - ilGenerator.Emit(OpCodes.Ldloc, monitor); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldloc, monitor); ilGenerator.EmitMonitorExit(); - ilGenerator.Emit(OpCodes.Endfinally); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Endfinally); ilGenerator.EndExceptionBlock(); b.LeaveStubs(new Block(c, 0, int.MaxValue, -1, null, false)); } @@ -961,7 +957,8 @@ void Compile(Block block, int startIndex) exceptionTypeWrapper = classFile.GetConstantPoolClassType(exc.catchType); remap = exceptionTypeWrapper.IsUnloadable || !exceptionTypeWrapper.IsSubTypeOf(finish.Context.JavaBase.TypeOfCliSystemException); } - Type excType = exceptionTypeWrapper.TypeAsExceptionType; + + var excType = exceptionTypeWrapper.TypeAsExceptionType; bool mapSafe = !exceptionTypeWrapper.IsUnloadable && !exceptionTypeWrapper.IsMapUnsafeException && !exceptionTypeWrapper.IsRemapped; if (mapSafe) { @@ -971,12 +968,12 @@ void Compile(Block block, int startIndex) { ilGenerator.BeginCatchBlock(finish.Context.Types.Exception); } - BranchCookie bc = new BranchCookie(this, 1, exc.handlerIndex); + + var bc = new BranchCookie(this, 1, exc.handlerIndex); prevBlock.AddExitHack(bc); - Instruction handlerInstr = code[handlerIndex]; - bool unusedException = (handlerInstr.NormalizedOpCode == NormalizedByteCode.__pop || - (handlerInstr.NormalizedOpCode == NormalizedByteCode.__astore && - localVars.GetLocalVar(handlerIndex) == null)); + + var handlerInstr = code[handlerIndex]; + var unusedException = (handlerInstr.NormalizedOpCode == NormalizedByteCode.__pop || (handlerInstr.NormalizedOpCode == NormalizedByteCode.__astore && localVars.GetLocalVar(handlerIndex) == null)); int mapFlags = unusedException ? 2 : 0; if (mapSafe && unusedException) { @@ -985,12 +982,12 @@ void Compile(Block block, int startIndex) else if (mapSafe) { ilGenerator.EmitLdc_I4(mapFlags | 1); - ilGenerator.Emit(OpCodes.Call, finish.Context.ByteCodeHelperMethods.MapException.MakeGenericMethod(excType)); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Call, finish.Context.ByteCodeHelperMethods.MapException.MakeGenericMethod(excType)); } else if (exceptionTypeWrapper == finish.Context.JavaBase.TypeOfjavaLangThrowable) { ilGenerator.EmitLdc_I4(mapFlags); - ilGenerator.Emit(OpCodes.Call, finish.Context.ByteCodeHelperMethods.MapException.MakeGenericMethod(finish.Context.Types.Exception)); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Call, finish.Context.ByteCodeHelperMethods.MapException.MakeGenericMethod(finish.Context.Types.Exception)); } else { @@ -999,19 +996,21 @@ void Compile(Block block, int startIndex) { Profiler.Count("EmitDynamicExceptionHandler"); EmitDynamicClassLiteral(exceptionTypeWrapper); - ilGenerator.Emit(OpCodes.Call, finish.Context.ByteCodeHelperMethods.DynamicMapException); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Call, finish.Context.ByteCodeHelperMethods.DynamicMapException); } else { - ilGenerator.Emit(OpCodes.Call, finish.Context.ByteCodeHelperMethods.MapException.MakeGenericMethod(excType)); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Call, finish.Context.ByteCodeHelperMethods.MapException.MakeGenericMethod(excType)); } + if (!unusedException) { - ilGenerator.Emit(OpCodes.Dup); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Dup); } - CodeEmitterLabel leave = ilGenerator.DefineLabel(); + + var leave = ilGenerator.DefineLabel(); ilGenerator.EmitBrtrue(leave); - ilGenerator.Emit(OpCodes.Rethrow); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Rethrow); ilGenerator.MarkLabel(leave); } if (unusedException) @@ -1118,23 +1117,23 @@ void Compile(Block block, int startIndex) switch (ByteCodeMetaData.GetFlowControl(instr.NormalizedOpCode)) { case ByteCodeFlowControl.Return: - ilGenerator.Emit(OpCodes.Ldarg_0); - ilGenerator.Emit(OpCodes.Call, finish.Context.CompilerFactory.KeepAliveMethod); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Call, finish.Context.CompilerFactory.KeepAliveMethod); break; case ByteCodeFlowControl.Branch: case ByteCodeFlowControl.CondBranch: if (instr.TargetIndex <= i) { - ilGenerator.Emit(OpCodes.Ldarg_0); - ilGenerator.Emit(OpCodes.Call, finish.Context.CompilerFactory.KeepAliveMethod); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Call, finish.Context.CompilerFactory.KeepAliveMethod); } break; case ByteCodeFlowControl.Throw: case ByteCodeFlowControl.Switch: if (ma.GetLocalTypeWrapper(i, 0) != finish.Context.VerifierJavaTypeFactory.UninitializedThis) { - ilGenerator.Emit(OpCodes.Ldarg_0); - ilGenerator.Emit(OpCodes.Call, finish.Context.CompilerFactory.KeepAliveMethod); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Call, finish.Context.CompilerFactory.KeepAliveMethod); } break; } @@ -1155,8 +1154,8 @@ void Compile(Block block, int startIndex) } case NormalizedByteCode.__getfield: { - ClassFile.ConstantPoolItemFieldref cpi = classFile.GetFieldref(instr.Arg1); - RuntimeJavaField field = cpi.GetField(); + var cpi = classFile.GetFieldref(instr.Arg1); + var field = cpi.GetField(); if (ma.GetStackTypeWrapper(i, 0).IsUnloadable) { if (field.IsProtected) @@ -1179,8 +1178,9 @@ void Compile(Block block, int startIndex) var cpi = classFile.GetFieldref(instr.Arg1); if (cpi.GetClassType() != clazz) nonleaf = true; // we may trigger a static initializer, which is equivalent to a call - RuntimeJavaField field = cpi.GetField(); - RuntimeJavaType tw = field.FieldTypeWrapper; + + var field = cpi.GetField(); + var tw = field.FieldTypeWrapper; tw.EmitConvStackTypeToSignatureType(ilGenerator, ma.GetStackTypeWrapper(i, 0)); if (strictfp) { @@ -1188,20 +1188,20 @@ void Compile(Block block, int startIndex) } else if (tw == finish.Context.PrimitiveJavaTypeFactory.DOUBLE) { - ilGenerator.Emit(OpCodes.Conv_R8); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Conv_R8); } field.EmitSet(ilGenerator); break; } case NormalizedByteCode.__putfield: { - ClassFile.ConstantPoolItemFieldref cpi = classFile.GetFieldref(instr.Arg1); - RuntimeJavaField field = cpi.GetField(); - RuntimeJavaType tw = field.FieldTypeWrapper; + var cpi = classFile.GetFieldref(instr.Arg1); + var field = cpi.GetField(); + var tw = field.FieldTypeWrapper; if (ma.GetStackTypeWrapper(i, 1).IsUnloadable) { CodeEmitterLocal temp = ilGenerator.UnsafeAllocTempLocal(tw.TypeAsLocalOrStackType); - ilGenerator.Emit(OpCodes.Stloc, temp); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Stloc, temp); if (field.IsProtected) { // downcast receiver to our type @@ -1212,7 +1212,7 @@ void Compile(Block block, int startIndex) // downcast receiver to field declaring type field.DeclaringType.EmitCheckcast(ilGenerator); } - ilGenerator.Emit(OpCodes.Ldloc, temp); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldloc, temp); } tw.EmitConvStackTypeToSignatureType(ilGenerator, ma.GetStackTypeWrapper(i, 0)); if (strictfp) @@ -1221,7 +1221,7 @@ void Compile(Block block, int startIndex) } else if (tw == finish.Context.PrimitiveJavaTypeFactory.DOUBLE) { - ilGenerator.Emit(OpCodes.Conv_R8); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Conv_R8); } field.EmitSet(ilGenerator); break; @@ -1234,7 +1234,7 @@ void Compile(Block block, int startIndex) DynamicGetPutField(instr, i); break; case NormalizedByteCode.__aconst_null: - ilGenerator.Emit(OpCodes.Ldnull); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldnull); break; case NormalizedByteCode.__iconst: ilGenerator.EmitLdc_I4(instr.NormalizedArg1); @@ -1310,7 +1310,7 @@ void Compile(Block block, int startIndex) var method = GetMethodCallEmitter(instr.NormalizedOpCode, instr.Arg1); var argcount = method.GetParameters().Length; var type = ma.GetRawStackTypeWrapper(i, argcount); - RuntimeJavaType thisType = ComputeThisType(type, method, instr.NormalizedOpCode); + var thisType = ComputeThisType(type, method, instr.NormalizedOpCode); var eic = new EmitIntrinsicContext(method, finish, ilGenerator, ma, i, mw, classFile, code, flags); if (method.IsIntrinsic && method.EmitIntrinsic(eic)) @@ -1405,7 +1405,7 @@ void Compile(Block block, int startIndex) if (code[i + 1].NormalizedOpCode == NormalizedByteCode.__athrow) { if (thisType.GetMethodWrapper("fillInStackTrace", "()Ljava.lang.Throwable;", true).DeclaringType == finish.Context.JavaBase.TypeOfjavaLangThrowable) - ilGenerator.Emit(OpCodes.Call, finish.Context.CompilerFactory.SuppressFillInStackTraceMethod); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Call, finish.Context.CompilerFactory.SuppressFillInStackTraceMethod); if ((flags[i + 1] & InstructionFlags.BranchTarget) == 0) code[i + 1].PatchOpCode(NormalizedByteCode.__athrow_no_unmap); } @@ -1415,7 +1415,7 @@ void Compile(Block block, int startIndex) if (!thisType.IsUnloadable && thisType.IsSubTypeOf(finish.Context.JavaBase.TypeOfCliSystemException)) { // we call Throwable.__() to disable remapping the exception - ilGenerator.Emit(OpCodes.Call, finish.Context.CompilerFactory.FixateExceptionMethod); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Call, finish.Context.CompilerFactory.FixateExceptionMethod); } if (nontrivial) @@ -1424,7 +1424,7 @@ void Compile(Block block, int startIndex) // code never runs (for code compiled from Java source) it doesn't // really matter var newobj = ilGenerator.DeclareLocal(GetLocalBuilderType(thisType)); - ilGenerator.Emit(OpCodes.Stloc, newobj); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Stloc, newobj); var tempstack = new CodeEmitterLocal[stackfix.Length]; for (int j = 0; j < stackfix.Length; j++) { @@ -1437,12 +1437,12 @@ void Compile(Block block, int startIndex) { // NOTE we abuse the newobj local as a cookie to signal null! tempstack[j] = newobj; - ilGenerator.Emit(OpCodes.Pop); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Pop); } else if (!RuntimeVerifierJavaType.IsNotPresentOnStack(stacktype)) { var lb = ilGenerator.DeclareLocal(GetLocalBuilderType(stacktype)); - ilGenerator.Emit(OpCodes.Stloc, lb); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Stloc, lb); tempstack[j] = lb; } } @@ -1452,15 +1452,15 @@ void Compile(Block block, int startIndex) { if (stackfix[j]) { - ilGenerator.Emit(OpCodes.Ldloc, newobj); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldloc, newobj); } else if (tempstack[j] != null) { // NOTE we abuse the newobj local as a cookie to signal null! if (tempstack[j] == newobj) - ilGenerator.Emit(OpCodes.Ldnull); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldnull); else - ilGenerator.Emit(OpCodes.Ldloc, tempstack[j]); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldloc, tempstack[j]); } } @@ -1474,8 +1474,8 @@ void Compile(Block block, int startIndex) // for invokespecial the resulting type can never be null locals[j].builder = ilGenerator.DeclareLocal(GetLocalBuilderType(locals[j].type)); } - ilGenerator.Emit(OpCodes.Ldloc, newobj); - ilGenerator.Emit(OpCodes.Stloc, locals[j].builder); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldloc, newobj); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Stloc, locals[j].builder); } } } @@ -1483,13 +1483,13 @@ void Compile(Block block, int startIndex) { if (trivcount == 0) { - ilGenerator.Emit(OpCodes.Pop); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Pop); } else { for (int j = 1; j < trivcount; j++) { - ilGenerator.Emit(OpCodes.Dup); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Dup); } } } @@ -1508,8 +1508,8 @@ void Compile(Block block, int startIndex) // for invokespecial the resulting type can never be null locals[j].builder = ilGenerator.DeclareLocal(GetLocalBuilderType(locals[j].type)); } - ilGenerator.Emit(OpCodes.Ldarg_0); - ilGenerator.Emit(OpCodes.Stloc, locals[j].builder); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Stloc, locals[j].builder); } } } @@ -1536,7 +1536,7 @@ void Compile(Block block, int startIndex) } else { - ilGenerator.Emit(OpCodes.Callvirt, finish.GetInvokeSpecialStub(method)); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Callvirt, finish.GetInvokeSpecialStub(method)); } } else @@ -1565,7 +1565,7 @@ void Compile(Block block, int startIndex) break; } case NormalizedByteCode.__clone_array: - ilGenerator.Emit(OpCodes.Callvirt, RuntimeArrayJavaType.GetCloneMethod(finish.Context)); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Callvirt, RuntimeArrayJavaType.GetCloneMethod(finish.Context)); break; case NormalizedByteCode.__return: case NormalizedByteCode.__areturn: @@ -1583,7 +1583,7 @@ void Compile(Block block, int startIndex) var retTypeWrapper = mw.ReturnType; retTypeWrapper.EmitConvStackTypeToSignatureType(ilGenerator, ma.GetStackTypeWrapper(i, 0)); local = ilGenerator.UnsafeAllocTempLocal(retTypeWrapper.TypeAsSignatureType); - ilGenerator.Emit(OpCodes.Stloc, local); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Stloc, local); } var label = ilGenerator.DefineLabel(); @@ -1623,7 +1623,7 @@ void Compile(Block block, int startIndex) if (stackHeight != 0 || x64hack) ilGenerator.EmitClearStack(); - ilGenerator.Emit(OpCodes.Ret); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ret); } else { @@ -1632,9 +1632,9 @@ void Compile(Block block, int startIndex) if (stackHeight != 1) { var local = ilGenerator.AllocTempLocal(retTypeWrapper.TypeAsSignatureType); - ilGenerator.Emit(OpCodes.Stloc, local); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Stloc, local); ilGenerator.EmitClearStack(); - ilGenerator.Emit(OpCodes.Ldloc, local); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldloc, local); ilGenerator.ReleaseTempLocal(local); } else if (x64hack) @@ -1642,7 +1642,7 @@ void Compile(Block block, int startIndex) ilGenerator.EmitTailCallPrevention(); } - ilGenerator.Emit(OpCodes.Ret); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ret); } } break; @@ -1653,7 +1653,7 @@ void Compile(Block block, int startIndex) if (type == finish.Context.VerifierJavaTypeFactory.Null) { // if the local is known to be null, we just emit a null - ilGenerator.Emit(OpCodes.Ldnull); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldnull); } else if (RuntimeVerifierJavaType.IsNotPresentOnStack(type)) { @@ -1661,7 +1661,7 @@ void Compile(Block block, int startIndex) } else if (RuntimeVerifierJavaType.IsThis(type)) { - ilGenerator.Emit(OpCodes.Ldarg_0); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); } else if (type == finish.Context.VerifierJavaTypeFactory.UninitializedThis) { @@ -1669,7 +1669,7 @@ void Compile(Block block, int startIndex) // NOTE if the method overwrites the this references, it will always end up in // a different local (due to the way the local variable liveness analysis works), // so we don't have to worry about that. - ilGenerator.Emit(OpCodes.Ldarg_0); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); } else { @@ -1693,7 +1693,7 @@ void Compile(Block block, int startIndex) // any unitialized reference is always the this reference, we don't store anything // here (because CLR won't allow unitialized references in locals) and then when // the unitialized ref is loaded we redirect to the this reference - ilGenerator.Emit(OpCodes.Pop); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Pop); } else { @@ -1717,7 +1717,7 @@ void Compile(Block block, int startIndex) case NormalizedByteCode.__dstore: if (ma.IsStackTypeExtendedDouble(i, 0)) { - ilGenerator.Emit(OpCodes.Conv_R8); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Conv_R8); } StoreLocal(i); break; @@ -1730,7 +1730,7 @@ void Compile(Block block, int startIndex) // this is here to make sure we throw the exception in the right location (before // evaluating the constructor arguments) EmitDynamicClassLiteral(wrapper); - ilGenerator.Emit(OpCodes.Call, finish.Context.ByteCodeHelperMethods.DynamicNewCheckOnly); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Call, finish.Context.ByteCodeHelperMethods.DynamicNewCheckOnly); } else if (wrapper != clazz && RequiresExplicitClassInit(wrapper, i + 1, flags)) { @@ -1743,26 +1743,26 @@ void Compile(Block block, int startIndex) } case NormalizedByteCode.__multianewarray: { - var localArray = ilGenerator.UnsafeAllocTempLocal(finish.Context.Resolver.ResolveCoreType(typeof(int).FullName).MakeArrayType().AsReflection()); + var localArray = ilGenerator.UnsafeAllocTempLocal(finish.Context.Resolver.ResolveCoreType(typeof(int).FullName).MakeArrayType()); var localInt = ilGenerator.UnsafeAllocTempLocal(finish.Context.Types.Int32); ilGenerator.EmitLdc_I4(instr.Arg2); - ilGenerator.Emit(OpCodes.Newarr, finish.Context.Types.Int32); - ilGenerator.Emit(OpCodes.Stloc, localArray); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Newarr, finish.Context.Types.Int32); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Stloc, localArray); for (int j = 1; j <= instr.Arg2; j++) { - ilGenerator.Emit(OpCodes.Stloc, localInt); - ilGenerator.Emit(OpCodes.Ldloc, localArray); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Stloc, localInt); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldloc, localArray); ilGenerator.EmitLdc_I4(instr.Arg2 - j); - ilGenerator.Emit(OpCodes.Ldloc, localInt); - ilGenerator.Emit(OpCodes.Stelem_I4); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldloc, localInt); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Stelem_I4); } var wrapper = classFile.GetConstantPoolClassType(instr.Arg1); if (wrapper.IsUnloadable) { Profiler.Count("EmitDynamicMultianewarray"); - ilGenerator.Emit(OpCodes.Ldloc, localArray); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldloc, localArray); EmitDynamicClassLiteral(wrapper); - ilGenerator.Emit(OpCodes.Call, finish.Context.ByteCodeHelperMethods.DynamicMultianewarray); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Call, finish.Context.ByteCodeHelperMethods.DynamicMultianewarray); } else if (wrapper.IsGhost || wrapper.IsGhostArray) { @@ -1770,18 +1770,18 @@ void Compile(Block block, int startIndex) while (tw.IsArray) tw = tw.ElementTypeWrapper; - ilGenerator.Emit(OpCodes.Ldtoken, RuntimeArrayJavaType.MakeArrayType(tw.TypeAsTBD, wrapper.ArrayRank)); - ilGenerator.Emit(OpCodes.Ldloc, localArray); - ilGenerator.Emit(OpCodes.Call, finish.Context.ByteCodeHelperMethods.multianewarray_ghost); - ilGenerator.Emit(OpCodes.Castclass, wrapper.TypeAsArrayType); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldtoken, tw.TypeAsTBD.MakeArrayType(wrapper.ArrayRank)); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldloc, localArray); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Call, finish.Context.ByteCodeHelperMethods.multianewarray_ghost); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Castclass, wrapper.TypeAsArrayType); } else { - Type type = wrapper.TypeAsArrayType; - ilGenerator.Emit(OpCodes.Ldtoken, type); - ilGenerator.Emit(OpCodes.Ldloc, localArray); - ilGenerator.Emit(OpCodes.Call, finish.Context.ByteCodeHelperMethods.multianewarray); - ilGenerator.Emit(OpCodes.Castclass, type); + var type = wrapper.TypeAsArrayType; + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldtoken, type); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldloc, localArray); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Call, finish.Context.ByteCodeHelperMethods.multianewarray); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Castclass, type); } break; } @@ -1792,7 +1792,7 @@ void Compile(Block block, int startIndex) { Profiler.Count("EmitDynamicNewarray"); EmitDynamicClassLiteral(wrapper); - ilGenerator.Emit(OpCodes.Call, finish.Context.ByteCodeHelperMethods.DynamicNewarray); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Call, finish.Context.ByteCodeHelperMethods.DynamicNewarray); } else if (wrapper.IsGhost || wrapper.IsGhostArray) { @@ -1810,12 +1810,12 @@ void Compile(Block block, int startIndex) while (tw.IsArray) tw = tw.ElementTypeWrapper; - ilGenerator.Emit(OpCodes.Ldtoken, RuntimeArrayJavaType.MakeArrayType(tw.TypeAsTBD, wrapper.ArrayRank + 1)); - ilGenerator.Emit(OpCodes.Call, finish.Context.ByteCodeHelperMethods.anewarray_ghost.MakeGenericMethod(wrapper.TypeAsArrayType)); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldtoken, tw.TypeAsTBD.MakeArrayType(wrapper.ArrayRank + 1)); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Call, finish.Context.ByteCodeHelperMethods.anewarray_ghost.MakeGenericMethod(wrapper.TypeAsArrayType)); } else { - ilGenerator.Emit(OpCodes.Newarr, wrapper.TypeAsArrayType); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Newarr, wrapper.TypeAsArrayType); } break; @@ -1824,28 +1824,28 @@ void Compile(Block block, int startIndex) switch (instr.Arg1) { case 4: - ilGenerator.Emit(OpCodes.Newarr, finish.Context.PrimitiveJavaTypeFactory.BOOLEAN.TypeAsArrayType); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Newarr, finish.Context.PrimitiveJavaTypeFactory.BOOLEAN.TypeAsArrayType); break; case 5: - ilGenerator.Emit(OpCodes.Newarr, finish.Context.PrimitiveJavaTypeFactory.CHAR.TypeAsArrayType); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Newarr, finish.Context.PrimitiveJavaTypeFactory.CHAR.TypeAsArrayType); break; case 6: - ilGenerator.Emit(OpCodes.Newarr, finish.Context.PrimitiveJavaTypeFactory.FLOAT.TypeAsArrayType); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Newarr, finish.Context.PrimitiveJavaTypeFactory.FLOAT.TypeAsArrayType); break; case 7: - ilGenerator.Emit(OpCodes.Newarr, finish.Context.PrimitiveJavaTypeFactory.DOUBLE.TypeAsArrayType); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Newarr, finish.Context.PrimitiveJavaTypeFactory.DOUBLE.TypeAsArrayType); break; case 8: - ilGenerator.Emit(OpCodes.Newarr, finish.Context.PrimitiveJavaTypeFactory.BYTE.TypeAsArrayType); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Newarr, finish.Context.PrimitiveJavaTypeFactory.BYTE.TypeAsArrayType); break; case 9: - ilGenerator.Emit(OpCodes.Newarr, finish.Context.PrimitiveJavaTypeFactory.SHORT.TypeAsArrayType); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Newarr, finish.Context.PrimitiveJavaTypeFactory.SHORT.TypeAsArrayType); break; case 10: - ilGenerator.Emit(OpCodes.Newarr, finish.Context.PrimitiveJavaTypeFactory.INT.TypeAsArrayType); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Newarr, finish.Context.PrimitiveJavaTypeFactory.INT.TypeAsArrayType); break; case 11: - ilGenerator.Emit(OpCodes.Newarr, finish.Context.PrimitiveJavaTypeFactory.LONG.TypeAsArrayType); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Newarr, finish.Context.PrimitiveJavaTypeFactory.LONG.TypeAsArrayType); break; default: // this can't happen, the verifier would have caught it @@ -1878,7 +1878,7 @@ void Compile(Block block, int startIndex) if (tw.IsUnloadable) { Profiler.Count("EmitDynamicAaload"); - ilGenerator.Emit(OpCodes.Call, finish.Context.ByteCodeHelperMethods.DynamicAaload); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Call, finish.Context.ByteCodeHelperMethods.DynamicAaload); } else { @@ -1886,13 +1886,13 @@ void Compile(Block block, int startIndex) if (elem.IsNonPrimitiveValueType) { var t = elem.TypeAsTBD; - ilGenerator.Emit(OpCodes.Ldelema, t); - ilGenerator.Emit(OpCodes.Ldobj, t); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldelema, t); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldobj, t); elem.EmitBox(ilGenerator); } else { - ilGenerator.Emit(OpCodes.Ldelem_Ref); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldelem_Ref); } } @@ -1900,48 +1900,48 @@ void Compile(Block block, int startIndex) } case NormalizedByteCode.__baload: // NOTE both the JVM and the CLR use signed bytes for boolean arrays (how convenient!) - ilGenerator.Emit(OpCodes.Ldelem_I1); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldelem_I1); break; case NormalizedByteCode.__bastore: - ilGenerator.Emit(OpCodes.Stelem_I1); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Stelem_I1); break; case NormalizedByteCode.__caload: - ilGenerator.Emit(OpCodes.Ldelem_U2); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldelem_U2); break; case NormalizedByteCode.__castore: - ilGenerator.Emit(OpCodes.Stelem_I2); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Stelem_I2); break; case NormalizedByteCode.__saload: - ilGenerator.Emit(OpCodes.Ldelem_I2); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldelem_I2); break; case NormalizedByteCode.__sastore: - ilGenerator.Emit(OpCodes.Stelem_I2); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Stelem_I2); break; case NormalizedByteCode.__iaload: - ilGenerator.Emit(OpCodes.Ldelem_I4); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldelem_I4); break; case NormalizedByteCode.__iastore: - ilGenerator.Emit(OpCodes.Stelem_I4); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Stelem_I4); break; case NormalizedByteCode.__laload: - ilGenerator.Emit(OpCodes.Ldelem_I8); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldelem_I8); break; case NormalizedByteCode.__lastore: - ilGenerator.Emit(OpCodes.Stelem_I8); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Stelem_I8); break; case NormalizedByteCode.__faload: - ilGenerator.Emit(OpCodes.Ldelem_R4); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldelem_R4); break; case NormalizedByteCode.__fastore: - ilGenerator.Emit(OpCodes.Stelem_R4); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Stelem_R4); break; case NormalizedByteCode.__daload: - ilGenerator.Emit(OpCodes.Ldelem_R8); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldelem_R8); break; case NormalizedByteCode.__dastore: if (ma.IsStackTypeExtendedDouble(i, 0)) - ilGenerator.Emit(OpCodes.Conv_R8); - ilGenerator.Emit(OpCodes.Stelem_R8); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Conv_R8); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Stelem_R8); break; case NormalizedByteCode.__aastore: { @@ -1949,7 +1949,7 @@ void Compile(Block block, int startIndex) if (tw.IsUnloadable) { Profiler.Count("EmitDynamicAastore"); - ilGenerator.Emit(OpCodes.Call, finish.Context.ByteCodeHelperMethods.DynamicAastore); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Call, finish.Context.ByteCodeHelperMethods.DynamicAastore); } else { @@ -1958,18 +1958,18 @@ void Compile(Block block, int startIndex) { var t = elem.TypeAsTBD; var local = ilGenerator.UnsafeAllocTempLocal(finish.Context.Types.Object); - ilGenerator.Emit(OpCodes.Stloc, local); - ilGenerator.Emit(OpCodes.Ldelema, t); - ilGenerator.Emit(OpCodes.Ldloc, local); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Stloc, local); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldelema, t); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldloc, local); elem.EmitUnbox(ilGenerator); - ilGenerator.Emit(OpCodes.Stobj, t); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Stobj, t); } else { // NOTE for verifiability it is expressly *not* required that the // value matches the array type, so we don't need to handle interface // references here. - ilGenerator.Emit(OpCodes.Stelem_Ref); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Stelem_Ref); } } @@ -1978,12 +1978,12 @@ void Compile(Block block, int startIndex) case NormalizedByteCode.__arraylength: if (ma.GetRawStackTypeWrapper(i, 0).IsUnloadable) { - ilGenerator.Emit(OpCodes.Castclass, finish.Context.Types.Array); - ilGenerator.Emit(OpCodes.Callvirt, finish.Context.Types.Array.GetMethod("get_Length")); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Castclass, finish.Context.Types.Array); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Callvirt, finish.Context.Types.Array.GetMethod("get_Length")); } else { - ilGenerator.Emit(OpCodes.Ldlen); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldlen); } break; case NormalizedByteCode.__lcmp: @@ -2053,63 +2053,63 @@ void Compile(Block block, int startIndex) case NormalizedByteCode.__lneg: case NormalizedByteCode.__fneg: case NormalizedByteCode.__dneg: - ilGenerator.Emit(OpCodes.Neg); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Neg); break; case NormalizedByteCode.__iadd: case NormalizedByteCode.__ladd: - ilGenerator.Emit(OpCodes.Add); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Add); break; case NormalizedByteCode.__fadd: - ilGenerator.Emit(OpCodes.Add); - ilGenerator.Emit(OpCodes.Conv_R4); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Add); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Conv_R4); break; case NormalizedByteCode.__dadd: - ilGenerator.Emit(OpCodes.Add); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Add); if (strictfp) { - ilGenerator.Emit(OpCodes.Conv_R8); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Conv_R8); } break; case NormalizedByteCode.__isub: case NormalizedByteCode.__lsub: - ilGenerator.Emit(OpCodes.Sub); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Sub); break; case NormalizedByteCode.__fsub: - ilGenerator.Emit(OpCodes.Sub); - ilGenerator.Emit(OpCodes.Conv_R4); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Sub); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Conv_R4); break; case NormalizedByteCode.__dsub: - ilGenerator.Emit(OpCodes.Sub); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Sub); if (strictfp) { - ilGenerator.Emit(OpCodes.Conv_R8); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Conv_R8); } break; case NormalizedByteCode.__ixor: case NormalizedByteCode.__lxor: - ilGenerator.Emit(OpCodes.Xor); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Xor); break; case NormalizedByteCode.__ior: case NormalizedByteCode.__lor: - ilGenerator.Emit(OpCodes.Or); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Or); break; case NormalizedByteCode.__iand: case NormalizedByteCode.__land: - ilGenerator.Emit(OpCodes.And); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.And); break; case NormalizedByteCode.__imul: case NormalizedByteCode.__lmul: - ilGenerator.Emit(OpCodes.Mul); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Mul); break; case NormalizedByteCode.__fmul: - ilGenerator.Emit(OpCodes.Mul); - ilGenerator.Emit(OpCodes.Conv_R4); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Mul); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Conv_R4); break; case NormalizedByteCode.__dmul: - ilGenerator.Emit(OpCodes.Mul); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Mul); if (strictfp) { - ilGenerator.Emit(OpCodes.Conv_R8); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Conv_R8); } break; case NormalizedByteCode.__idiv: @@ -2119,14 +2119,14 @@ void Compile(Block block, int startIndex) ilGenerator.Emit_ldiv(); break; case NormalizedByteCode.__fdiv: - ilGenerator.Emit(OpCodes.Div); - ilGenerator.Emit(OpCodes.Conv_R4); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Div); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Conv_R4); break; case NormalizedByteCode.__ddiv: - ilGenerator.Emit(OpCodes.Div); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Div); if (strictfp) { - ilGenerator.Emit(OpCodes.Conv_R8); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Conv_R8); } break; case NormalizedByteCode.__irem: @@ -2136,58 +2136,58 @@ void Compile(Block block, int startIndex) // because the CLR rem instruction throws an OverflowException when // taking the remainder of dividing Int32.MinValue by -1, and // Java just silently overflows - ilGenerator.Emit(OpCodes.Dup); - ilGenerator.Emit(OpCodes.Ldc_I4_M1); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Dup); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_M1); if (instr.NormalizedOpCode == NormalizedByteCode.__lrem) - ilGenerator.Emit(OpCodes.Conv_I8); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Conv_I8); var label = ilGenerator.DefineLabel(); ilGenerator.EmitBne_Un(label); - ilGenerator.Emit(OpCodes.Pop); - ilGenerator.Emit(OpCodes.Pop); - ilGenerator.Emit(OpCodes.Ldc_I4_0); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Pop); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Pop); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_0); if (instr.NormalizedOpCode == NormalizedByteCode.__lrem) { - ilGenerator.Emit(OpCodes.Conv_I8); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Conv_I8); } var label2 = ilGenerator.DefineLabel(); ilGenerator.EmitBr(label2); ilGenerator.MarkLabel(label); - ilGenerator.Emit(OpCodes.Rem); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Rem); ilGenerator.MarkLabel(label2); break; } case NormalizedByteCode.__frem: - ilGenerator.Emit(OpCodes.Rem); - ilGenerator.Emit(OpCodes.Conv_R4); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Rem); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Conv_R4); break; case NormalizedByteCode.__drem: - ilGenerator.Emit(OpCodes.Rem); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Rem); if (strictfp) - ilGenerator.Emit(OpCodes.Conv_R8); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Conv_R8); break; case NormalizedByteCode.__ishl: ilGenerator.Emit_And_I4(31); - ilGenerator.Emit(OpCodes.Shl); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Shl); break; case NormalizedByteCode.__lshl: ilGenerator.Emit_And_I4(63); - ilGenerator.Emit(OpCodes.Shl); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Shl); break; case NormalizedByteCode.__iushr: ilGenerator.Emit_And_I4(31); - ilGenerator.Emit(OpCodes.Shr_Un); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Shr_Un); break; case NormalizedByteCode.__lushr: ilGenerator.Emit_And_I4(63); - ilGenerator.Emit(OpCodes.Shr_Un); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Shr_Un); break; case NormalizedByteCode.__ishr: ilGenerator.Emit_And_I4(31); - ilGenerator.Emit(OpCodes.Shr); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Shr); break; case NormalizedByteCode.__lshr: ilGenerator.Emit_And_I4(63); - ilGenerator.Emit(OpCodes.Shr); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Shr); break; case NormalizedByteCode.__swap: { @@ -2204,7 +2204,7 @@ void Compile(Block block, int startIndex) case NormalizedByteCode.__dup: // if the TOS contains a "new" object or a fault block exception, it isn't really there, so we don't dup it if (!RuntimeVerifierJavaType.IsNotPresentOnStack(ma.GetRawStackTypeWrapper(i, 0))) - ilGenerator.Emit(OpCodes.Dup); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Dup); break; case NormalizedByteCode.__dup2: @@ -2212,7 +2212,7 @@ void Compile(Block block, int startIndex) var type1 = ma.GetRawStackTypeWrapper(i, 0); if (type1.IsWidePrimitive) { - ilGenerator.Emit(OpCodes.Dup); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Dup); } else { @@ -2393,14 +2393,14 @@ void Compile(Block block, int startIndex) var type1 = ma.GetRawStackTypeWrapper(i, 0); if (type1.IsWidePrimitive) { - ilGenerator.Emit(OpCodes.Pop); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Pop); } else { if (!RuntimeVerifierJavaType.IsNotPresentOnStack(type1)) - ilGenerator.Emit(OpCodes.Pop); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Pop); if (!RuntimeVerifierJavaType.IsNotPresentOnStack(ma.GetRawStackTypeWrapper(i, 1))) - ilGenerator.Emit(OpCodes.Pop); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Pop); } break; } @@ -2408,7 +2408,7 @@ void Compile(Block block, int startIndex) // if the TOS is a new object or a fault block exception, it isn't really there, so we don't need to pop it if (!RuntimeVerifierJavaType.IsNotPresentOnStack(ma.GetRawStackTypeWrapper(i, 0))) { - ilGenerator.Emit(OpCodes.Pop); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Pop); } break; case NormalizedByteCode.__monitorenter: @@ -2420,23 +2420,23 @@ void Compile(Block block, int startIndex) case NormalizedByteCode.__athrow_no_unmap: if (ma.GetRawStackTypeWrapper(i, 0).IsUnloadable) { - ilGenerator.Emit(OpCodes.Castclass, finish.Context.Types.Exception); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Castclass, finish.Context.Types.Exception); } - ilGenerator.Emit(OpCodes.Throw); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Throw); break; case NormalizedByteCode.__athrow: if (RuntimeVerifierJavaType.IsFaultBlockException(ma.GetRawStackTypeWrapper(i, 0))) { - ilGenerator.Emit(OpCodes.Endfinally); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Endfinally); } else { if (ma.GetRawStackTypeWrapper(i, 0).IsUnloadable) { - ilGenerator.Emit(OpCodes.Castclass, finish.Context.Types.Exception); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Castclass, finish.Context.Types.Exception); } - ilGenerator.Emit(OpCodes.Call, finish.Context.CompilerFactory.UnmapExceptionMethod); - ilGenerator.Emit(OpCodes.Throw); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Call, finish.Context.CompilerFactory.UnmapExceptionMethod); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Throw); } break; case NormalizedByteCode.__tableswitch: @@ -2451,7 +2451,7 @@ void Compile(Block block, int startIndex) if (instr.GetSwitchValue(0) != 0) { ilGenerator.EmitLdc_I4(instr.GetSwitchValue(0)); - ilGenerator.Emit(OpCodes.Sub); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Sub); } ilGenerator.EmitSwitch(labels); ilGenerator.EmitBr(block.GetLabel(instr.DefaultTarget)); @@ -2460,65 +2460,65 @@ void Compile(Block block, int startIndex) case NormalizedByteCode.__lookupswitch: for (int j = 0; j < instr.SwitchEntryCount; j++) { - ilGenerator.Emit(OpCodes.Dup); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Dup); ilGenerator.EmitLdc_I4(instr.GetSwitchValue(j)); CodeEmitterLabel label = ilGenerator.DefineLabel(); ilGenerator.EmitBne_Un(label); - ilGenerator.Emit(OpCodes.Pop); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Pop); ilGenerator.EmitBr(block.GetLabel(instr.GetSwitchTargetIndex(j))); ilGenerator.MarkLabel(label); } - ilGenerator.Emit(OpCodes.Pop); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Pop); ilGenerator.EmitBr(block.GetLabel(instr.DefaultTarget)); break; case NormalizedByteCode.__iinc: LoadLocal(i); ilGenerator.EmitLdc_I4(instr.Arg2); - ilGenerator.Emit(OpCodes.Add); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Add); StoreLocal(i); break; case NormalizedByteCode.__i2b: - ilGenerator.Emit(OpCodes.Conv_I1); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Conv_I1); break; case NormalizedByteCode.__i2c: - ilGenerator.Emit(OpCodes.Conv_U2); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Conv_U2); break; case NormalizedByteCode.__i2s: - ilGenerator.Emit(OpCodes.Conv_I2); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Conv_I2); break; case NormalizedByteCode.__l2i: - ilGenerator.Emit(OpCodes.Conv_I4); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Conv_I4); break; case NormalizedByteCode.__f2i: - ilGenerator.Emit(OpCodes.Call, finish.Context.ByteCodeHelperMethods.f2i); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Call, finish.Context.ByteCodeHelperMethods.f2i); break; case NormalizedByteCode.__d2i: - ilGenerator.Emit(OpCodes.Call, finish.Context.ByteCodeHelperMethods.d2i); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Call, finish.Context.ByteCodeHelperMethods.d2i); break; case NormalizedByteCode.__f2l: - ilGenerator.Emit(OpCodes.Call, finish.Context.ByteCodeHelperMethods.f2l); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Call, finish.Context.ByteCodeHelperMethods.f2l); break; case NormalizedByteCode.__d2l: - ilGenerator.Emit(OpCodes.Call, finish.Context.ByteCodeHelperMethods.d2l); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Call, finish.Context.ByteCodeHelperMethods.d2l); break; case NormalizedByteCode.__i2l: - ilGenerator.Emit(OpCodes.Conv_I8); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Conv_I8); break; case NormalizedByteCode.__i2f: case NormalizedByteCode.__l2f: case NormalizedByteCode.__d2f: - ilGenerator.Emit(OpCodes.Conv_R4); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Conv_R4); break; case NormalizedByteCode.__i2d: case NormalizedByteCode.__l2d: case NormalizedByteCode.__f2d: - ilGenerator.Emit(OpCodes.Conv_R8); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Conv_R8); break; case NormalizedByteCode.__nop: - ilGenerator.Emit(OpCodes.Nop); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Nop); break; case NormalizedByteCode.__intrinsic_gettype: - ilGenerator.Emit(OpCodes.Callvirt, finish.Context.CompilerFactory.GetTypeMethod); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Callvirt, finish.Context.CompilerFactory.GetTypeMethod); break; case NormalizedByteCode.__static_error: { @@ -2564,7 +2564,7 @@ void Compile(Block block, int startIndex) var message = harderrors[instr.HardErrorMessageId]; clazz.ClassLoader.Diagnostics.GenericCompilerError($"{exceptionType.Name}: {message}\n\tat {classFile.Name}.{m.Name}{m.Signature}"); - ilGenerator.Emit(OpCodes.Ldstr, message); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldstr, message); RuntimeJavaMethod method = exceptionType.GetMethodWrapper("", "(Ljava.lang.String;)V", false); method.Link(); method.EmitNewobj(ilGenerator); @@ -2572,7 +2572,7 @@ void Compile(Block block, int startIndex) { finish.Context.JavaBase.TypeOfjavaLangThrowable.GetMethodWrapper("initCause", "(Ljava.lang.Throwable;)Ljava.lang.Throwable;", false).EmitCallvirt(ilGenerator); } - ilGenerator.Emit(OpCodes.Throw); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Throw); break; } default: @@ -2614,11 +2614,11 @@ void EmitReturnTypeConversion(RuntimeJavaType returnType) } else if (returnType == finish.Context.PrimitiveJavaTypeFactory.DOUBLE) { - ilGenerator.Emit(OpCodes.Conv_R8); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Conv_R8); } else if (returnType == finish.Context.PrimitiveJavaTypeFactory.FLOAT) { - ilGenerator.Emit(OpCodes.Conv_R4); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Conv_R4); } } @@ -2639,7 +2639,7 @@ void EmitLoadConstant(CodeEmitter ilgen, ConstantHandle constant) ilgen.EmitLdc_I8(classFile.GetConstantPoolConstantLong((LongConstantHandle)constant)); break; case ClassFile.ConstantType.String: - ilgen.Emit(OpCodes.Ldstr, classFile.GetConstantPoolConstantString((StringConstantHandle)constant)); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldstr, classFile.GetConstantPoolConstantString((StringConstantHandle)constant)); break; case ClassFile.ConstantType.Class: EmitLoadClass(ilgen, classFile.GetConstantPoolClassType((ClassConstantHandle)constant)); @@ -2667,10 +2667,10 @@ private void EmitDynamicCast(RuntimeJavaType tw) // NOTE it's important that we don't try to load the class if obj == null var ok = ilGenerator.DefineLabel(); - ilGenerator.Emit(OpCodes.Dup); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Dup); ilGenerator.EmitBrfalse(ok); EmitDynamicClassLiteral(tw); - ilGenerator.Emit(OpCodes.Call, finish.Context.ByteCodeHelperMethods.DynamicCast); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Call, finish.Context.ByteCodeHelperMethods.DynamicCast); ilGenerator.MarkLabel(ok); } @@ -2679,14 +2679,14 @@ void EmitDynamicInstanceOf(RuntimeJavaType tw) // NOTE it's important that we don't try to load the class if obj == null var notnull = ilGenerator.DefineLabel(); var end = ilGenerator.DefineLabel(); - ilGenerator.Emit(OpCodes.Dup); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Dup); ilGenerator.EmitBrtrue(notnull); - ilGenerator.Emit(OpCodes.Pop); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Pop); ilGenerator.EmitLdc_I4(0); ilGenerator.EmitBr(end); ilGenerator.MarkLabel(notnull); EmitDynamicClassLiteral(tw); - ilGenerator.Emit(OpCodes.Call, finish.Context.ByteCodeHelperMethods.DynamicInstanceOf); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Call, finish.Context.ByteCodeHelperMethods.DynamicInstanceOf); ilGenerator.MarkLabel(end); } @@ -2723,7 +2723,7 @@ static class InvokeDynamicBuilder internal static void Emit(Compiler compiler, ClassFile.ConstantPoolItemInvokeDynamic cpi, ITypeSymbol delegateType) { - var typeofOpenIndyCallSite = compiler.finish.Context.Resolver.ResolveRuntimeType("IKVM.Runtime.IndyCallSite`1").AsReflection(); + var typeofOpenIndyCallSite = compiler.finish.Context.Resolver.ResolveRuntimeType("IKVM.Runtime.IndyCallSite`1"); var methodLookup = compiler.finish.Context.ClassLoaderFactory.LoadClassCritical("java.lang.invoke.MethodHandles").GetMethodWrapper("lookup", "()Ljava.lang.invoke.MethodHandles$Lookup;", false); methodLookup.Link(); @@ -2732,8 +2732,8 @@ internal static void Emit(Compiler compiler, ClassFile.ConstantPoolItemInvokeDyn IMethodSymbol methodGetTarget; if (ReflectUtil.ContainsTypeBuilder(typeofIndyCallSite)) { - methodCreateBootStrap = ITypeSymbolBuilder.GetMethod(typeofIndyCallSite, typeofOpenIndyCallSite.GetMethod("CreateBootstrap")); - methodGetTarget = ITypeSymbolBuilder.GetMethod(typeofIndyCallSite, typeofOpenIndyCallSite.GetMethod("GetTarget")); + methodCreateBootStrap = typeofOpenIndyCallSite.GetMethod("CreateBootstrap"); + methodGetTarget = typeofOpenIndyCallSite.GetMethod("GetTarget"); } else { @@ -2744,22 +2744,22 @@ internal static void Emit(Compiler compiler, ClassFile.ConstantPoolItemInvokeDyn var tb = compiler.finish.DefineIndyCallSiteType(); var fb = tb.DefineField("value", typeofIndyCallSite, FieldAttributes.Static | FieldAttributes.Assembly); var ilgen = compiler.finish.Context.CodeEmitterFactory.Create(ReflectUtil.DefineTypeInitializer(tb, compiler.clazz.ClassLoader)); - ilgen.Emit(OpCodes.Ldnull); - ilgen.Emit(OpCodes.Ldftn, CreateBootstrapStub(compiler, cpi, delegateType, tb, fb, methodGetTarget)); - ilgen.Emit(OpCodes.Newobj, compiler.finish.Context.MethodHandleUtil.GetDelegateConstructor(delegateType)); - ilgen.Emit(OpCodes.Call, methodCreateBootStrap); - ilgen.Emit(OpCodes.Stsfld, fb); - ilgen.Emit(OpCodes.Ret); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldnull); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldftn, CreateBootstrapStub(compiler, cpi, delegateType, tb, fb, methodGetTarget)); + ilgen.Emit(System.Reflection.Emit.OpCodes.Newobj, compiler.finish.Context.MethodHandleUtil.GetDelegateConstructor(delegateType)); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, methodCreateBootStrap); + ilgen.Emit(System.Reflection.Emit.OpCodes.Stsfld, fb); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ret); ilgen.DoEmit(); - compiler.ilGenerator.Emit(OpCodes.Ldsfld, fb); - compiler.ilGenerator.Emit(OpCodes.Call, methodGetTarget); + compiler.ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldsfld, fb); + compiler.ilGenerator.Emit(System.Reflection.Emit.OpCodes.Call, methodGetTarget); } static IMethodSymbolBuilder CreateBootstrapStub(Compiler compiler, ClassFile.ConstantPoolItemInvokeDynamic cpi, ITypeSymbol delegateType, ITypeSymbolBuilder tb, IFieldSymbolBuilder fb, IMethodSymbol methodGetTarget) { var typeofCallSite = compiler.finish.Context.ClassLoaderFactory.LoadClassCritical("java.lang.invoke.CallSite").TypeAsSignatureType; - var args = []; + var args = Array.Empty(); if (delegateType.IsGenericType) { @@ -2779,43 +2779,43 @@ static IMethodSymbolBuilder CreateBootstrapStub(Compiler compiler, ClassFile.Con if (EmitCallBootstrapMethod(compiler, cpi, ilgen, ok)) { - ilgen.Emit(OpCodes.Isinst, typeofCallSite); - ilgen.Emit(OpCodes.Stloc, cs); + ilgen.Emit(System.Reflection.Emit.OpCodes.Isinst, typeofCallSite); + ilgen.Emit(System.Reflection.Emit.OpCodes.Stloc, cs); } ilgen.EmitLeave(label); ilgen.BeginCatchBlock(compiler.finish.Context.Types.Exception); - ilgen.Emit(OpCodes.Stloc, ex); - ilgen.Emit(OpCodes.Ldloc, ok); + ilgen.Emit(System.Reflection.Emit.OpCodes.Stloc, ex); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldloc, ok); var label2 = ilgen.DefineLabel(); ilgen.EmitBrtrue(label2); - ilgen.Emit(OpCodes.Rethrow); + ilgen.Emit(System.Reflection.Emit.OpCodes.Rethrow); ilgen.MarkLabel(label2); ilgen.EmitLeave(label); ilgen.EndExceptionBlock(); ilgen.MarkLabel(label); - ilgen.Emit(OpCodes.Ldsflda, fb); - ilgen.Emit(OpCodes.Ldloc, cs); - ilgen.Emit(OpCodes.Ldloc, ex); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldsflda, fb); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldloc, cs); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldloc, ex); if (HasUnloadable(cpi.GetArgTypes(), cpi.GetRetType())) { - ilgen.Emit(OpCodes.Ldstr, cpi.Signature); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldstr, cpi.Signature); compiler.finish.EmitCallerID(ilgen, compiler.m.IsLambdaFormHidden); - ilgen.Emit(OpCodes.Call, compiler.finish.Context.ByteCodeHelperMethods.DynamicLinkIndyCallSite.MakeGenericMethod(delegateType)); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, compiler.finish.Context.ByteCodeHelperMethods.DynamicLinkIndyCallSite.MakeGenericMethod(delegateType)); } else { - ilgen.Emit(OpCodes.Call, compiler.finish.Context.ByteCodeHelperMethods.LinkIndyCallSite.MakeGenericMethod(delegateType)); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, compiler.finish.Context.ByteCodeHelperMethods.LinkIndyCallSite.MakeGenericMethod(delegateType)); } - ilgen.Emit(OpCodes.Ldsfld, fb); - ilgen.Emit(OpCodes.Call, methodGetTarget); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldsfld, fb); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, methodGetTarget); for (int i = 0; i < args.Length; i++) ilgen.EmitLdarg(i); - ilgen.Emit(OpCodes.Callvirt, compiler.finish.Context.MethodHandleUtil.GetDelegateInvokeMethod(delegateType)); - ilgen.Emit(OpCodes.Ret); + ilgen.Emit(System.Reflection.Emit.OpCodes.Callvirt, compiler.finish.Context.MethodHandleUtil.GetDelegateInvokeMethod(delegateType)); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ret); ilgen.DoEmit(); return mb; } @@ -2847,9 +2847,9 @@ static bool EmitCallBootstrapMethod(Compiler compiler, ClassFile.ConstantPoolIte default: // to throw the right exception, we have to resolve the MH constant here compiler.finish.GetValue(bsm.BootstrapMethodIndex.Slot).Emit(compiler, ilgen, bsm.BootstrapMethodIndex); - ilgen.Emit(OpCodes.Pop); + ilgen.Emit(System.Reflection.Emit.OpCodes.Pop); ilgen.EmitLdc_I4(1); - ilgen.Emit(OpCodes.Stloc, ok); + ilgen.Emit(System.Reflection.Emit.OpCodes.Stloc, ok); ilgen.EmitThrow("java.lang.invoke.WrongMethodTypeException"); return false; } @@ -2858,7 +2858,7 @@ static bool EmitCallBootstrapMethod(Compiler compiler, ClassFile.ConstantPoolIte { // to throw the right exception (i.e. without wrapping it in a BootstrapMethodError), we have to resolve the MH constant here compiler.finish.GetValue(bsm.BootstrapMethodIndex.Slot).Emit(compiler, ilgen, bsm.BootstrapMethodIndex); - ilgen.Emit(OpCodes.Pop); + ilgen.Emit(System.Reflection.Emit.OpCodes.Pop); if (mh.MemberConstantPoolItem is ClassFile.ConstantPoolItemMI cpiMI) { mw = new DynamicBinder().Get(compiler, mh.Kind, cpiMI, false); @@ -2866,7 +2866,7 @@ static bool EmitCallBootstrapMethod(Compiler compiler, ClassFile.ConstantPoolIte else { ilgen.EmitLdc_I4(1); - ilgen.Emit(OpCodes.Stloc, ok); + ilgen.Emit(System.Reflection.Emit.OpCodes.Stloc, ok); ilgen.EmitThrow("java.lang.invoke.WrongMethodTypeException"); return false; } @@ -2884,7 +2884,7 @@ static bool EmitCallBootstrapMethod(Compiler compiler, ClassFile.ConstantPoolIte else if (extraArgs != bsm.ArgumentCount) { ilgen.EmitLdc_I4(1); - ilgen.Emit(OpCodes.Stloc, ok); + ilgen.Emit(System.Reflection.Emit.OpCodes.Stloc, ok); ilgen.EmitThrow("java.lang.invoke.WrongMethodTypeException"); return false; } @@ -2896,20 +2896,20 @@ static bool EmitCallBootstrapMethod(Compiler compiler, ClassFile.ConstantPoolIte compiler.finish.EmitCallerID(ilgen, compiler.m.IsLambdaFormCompiled); methodLookup.EmitCall(ilgen); - ilgen.Emit(OpCodes.Ldstr, cpi.Name); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldstr, cpi.Name); parameters[1].EmitConvStackTypeToSignatureType(ilgen, compiler.finish.Context.JavaBase.TypeOfJavaLangString); if (HasUnloadable(cpi.GetArgTypes(), cpi.GetRetType())) { // the cache is useless since we only run once, so we use a local - ilgen.Emit(OpCodes.Ldloca, ilgen.DeclareLocal(compiler.finish.Context.JavaBase.TypeOfJavaLangInvokeMethodType.TypeAsSignatureType)); - ilgen.Emit(OpCodes.Ldstr, cpi.Signature); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldloca, ilgen.DeclareLocal(compiler.finish.Context.JavaBase.TypeOfJavaLangInvokeMethodType.TypeAsSignatureType)); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldstr, cpi.Signature); compiler.finish.EmitCallerID(ilgen, compiler.m.IsLambdaFormCompiled); - ilgen.Emit(OpCodes.Call, compiler.finish.Context.ByteCodeHelperMethods.DynamicLoadMethodType); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, compiler.finish.Context.ByteCodeHelperMethods.DynamicLoadMethodType); } else { - ilgen.Emit(OpCodes.Call, compiler.finish.Context.ByteCodeHelperMethods.LoadMethodType.MakeGenericMethod(compiler.finish.Context.MethodHandleUtil.CreateDelegateTypeForLoadConstant(cpi.GetArgTypes(), cpi.GetRetType()))); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, compiler.finish.Context.ByteCodeHelperMethods.LoadMethodType.MakeGenericMethod(compiler.finish.Context.MethodHandleUtil.CreateDelegateTypeForLoadConstant(cpi.GetArgTypes(), cpi.GetRetType()))); } parameters[2].EmitConvStackTypeToSignatureType(ilgen, compiler.finish.Context.JavaBase.TypeOfJavaLangInvokeMethodType); @@ -2921,17 +2921,17 @@ static bool EmitCallBootstrapMethod(Compiler compiler, ClassFile.ConstantPoolIte { ilgen.EmitLdc_I4(varArgs); var elemType = parameters[parameters.Length - 1].ElementTypeWrapper; - ilgen.Emit(OpCodes.Newarr, elemType.TypeAsArrayType); + ilgen.Emit(System.Reflection.Emit.OpCodes.Newarr, elemType.TypeAsArrayType); for (int i = 0; i < varArgs; i++) { - ilgen.Emit(OpCodes.Dup); + ilgen.Emit(System.Reflection.Emit.OpCodes.Dup); ilgen.EmitLdc_I4(i); EmitExtraArg(compiler, ilgen, bsm, i + fixedArgs, elemType, ok); - ilgen.Emit(OpCodes.Stelem_Ref); + ilgen.Emit(System.Reflection.Emit.OpCodes.Stelem_Ref); } } ilgen.EmitLdc_I4(1); - ilgen.Emit(OpCodes.Stloc, ok); + ilgen.Emit(System.Reflection.Emit.OpCodes.Stloc, ok); if (mw.IsConstructor) mw.EmitNewobj(ilgen); @@ -2962,7 +2962,7 @@ static void EmitExtraArg(Compiler compiler, CodeEmitter ilgen, ClassFile.Bootstr if (constType != targetType) { ilgen.EmitLdc_I4(1); - ilgen.Emit(OpCodes.Stloc, wrapException); + ilgen.Emit(System.Reflection.Emit.OpCodes.Stloc, wrapException); if (constType.IsPrimitive) { @@ -2977,17 +2977,17 @@ static void EmitExtraArg(Compiler compiler, CodeEmitter ilgen, ClassFile.Bootstr else if (targetType.IsPrimitive) { var wrapper = GetWrapperType(targetType, out var unbox); - ilgen.Emit(OpCodes.Castclass, wrapper.TypeAsBaseType); + ilgen.Emit(System.Reflection.Emit.OpCodes.Castclass, wrapper.TypeAsBaseType); wrapper.GetMethodWrapper(unbox, "()" + targetType.SigName, false).EmitCallvirt(ilgen); } else if (!constType.IsAssignableTo(targetType)) { - ilgen.Emit(OpCodes.Castclass, targetType.TypeAsBaseType); + ilgen.Emit(System.Reflection.Emit.OpCodes.Castclass, targetType.TypeAsBaseType); } targetType.EmitConvStackTypeToSignatureType(ilgen, targetType); ilgen.EmitLdc_I4(0); - ilgen.Emit(OpCodes.Stloc, wrapException); + ilgen.Emit(System.Reflection.Emit.OpCodes.Stloc, wrapException); } } @@ -3029,13 +3029,13 @@ void EmitInvokeDynamic(ClassFile.ConstantPoolItemInvokeDynamic cpi) for (int i = args.Length - 1; i >= 0; i--) { temps[i] = ilgen.DeclareLocal(args[i].TypeAsSignatureType); - ilgen.Emit(OpCodes.Stloc, temps[i]); + ilgen.Emit(System.Reflection.Emit.OpCodes.Stloc, temps[i]); } var delegateType = finish.Context.MethodHandleUtil.CreateMethodHandleDelegateType(args, cpi.GetRetType()); InvokeDynamicBuilder.Emit(this, cpi, delegateType); for (int i = 0; i < args.Length; i++) - ilgen.Emit(OpCodes.Ldloc, temps[i]); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldloc, temps[i]); finish.Context.MethodHandleUtil.EmitCallDelegateInvokeMethod(ilgen, delegateType); } @@ -3051,13 +3051,13 @@ internal void Emit(Compiler compiler, CodeEmitter ilgen, MethodHandleConstantHan field = compiler.finish.DefineDynamicMethodHandleCacheField(); var mh = compiler.classFile.GetConstantPoolConstantMethodHandle(handle); - ilgen.Emit(OpCodes.Ldsflda, field); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldsflda, field); ilgen.EmitLdc_I4((int)mh.Kind); - ilgen.Emit(OpCodes.Ldstr, mh.Class); - ilgen.Emit(OpCodes.Ldstr, mh.Name); - ilgen.Emit(OpCodes.Ldstr, mh.Signature); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldstr, mh.Class); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldstr, mh.Name); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldstr, mh.Signature); compiler.finish.EmitCallerID(ilgen, compiler.m.IsLambdaFormCompiled); - ilgen.Emit(OpCodes.Call, compiler.finish.Context.ByteCodeHelperMethods.DynamicLoadMethodHandle); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, compiler.finish.Context.ByteCodeHelperMethods.DynamicLoadMethodHandle); } } @@ -3075,14 +3075,14 @@ internal void Emit(Compiler compiler, CodeEmitter ilgen, MethodTypeConstantHandl if (dynamic) { - ilgen.Emit(OpCodes.Ldsflda, field); - ilgen.Emit(OpCodes.Ldstr, compiler.classFile.GetConstantPoolConstantMethodType(handle).Signature); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldsflda, field); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldstr, compiler.classFile.GetConstantPoolConstantMethodType(handle).Signature); compiler.finish.EmitCallerID(ilgen, compiler.m.IsLambdaFormCompiled); - ilgen.Emit(OpCodes.Call, compiler.finish.Context.ByteCodeHelperMethods.DynamicLoadMethodType); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, compiler.finish.Context.ByteCodeHelperMethods.DynamicLoadMethodType); } else { - ilgen.Emit(OpCodes.Ldsfld, field); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldsfld, field); } } @@ -3103,9 +3103,9 @@ static IFieldSymbolBuilder CreateField(Compiler compiler, MethodTypeConstantHand var field = tb.DefineField("value", compiler.finish.Context.JavaBase.TypeOfJavaLangInvokeMethodType.TypeAsSignatureType, FieldAttributes.Assembly | FieldAttributes.Static | FieldAttributes.InitOnly); var ilgen = compiler.finish.Context.CodeEmitterFactory.Create(ReflectUtil.DefineTypeInitializer(tb, compiler.clazz.ClassLoader)); var delegateType = compiler.finish.Context.MethodHandleUtil.CreateDelegateTypeForLoadConstant(args, ret); - ilgen.Emit(OpCodes.Call, compiler.finish.Context.ByteCodeHelperMethods.LoadMethodType.MakeGenericMethod(delegateType)); - ilgen.Emit(OpCodes.Stsfld, field); - ilgen.Emit(OpCodes.Ret); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, compiler.finish.Context.ByteCodeHelperMethods.LoadMethodType.MakeGenericMethod(delegateType)); + ilgen.Emit(System.Reflection.Emit.OpCodes.Stsfld, field); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ret); ilgen.DoEmit(); return field; } @@ -3224,11 +3224,11 @@ void CastInterfaceArgs(RuntimeJavaType declaringType, RuntimeJavaType[] args, in } else if (declaringType.IsNonPrimitiveValueType) { - ilGenerator.Emit(OpCodes.Unbox, declaringType.TypeAsTBD); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Unbox, declaringType.TypeAsTBD); } else { - ilGenerator.Emit(OpCodes.Castclass, declaringType.TypeAsSignatureType); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Castclass, declaringType.TypeAsSignatureType); } } for (int i = firstCastArg; i < args.Length; i++) @@ -3251,24 +3251,24 @@ void CastInterfaceArgs(RuntimeJavaType declaringType, RuntimeJavaType[] args, in // the wrapper value onto the stack if (!instanceMethod || i != 0) { - ilGenerator.Emit(OpCodes.Ldobj, args[i].TypeAsSignatureType); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldobj, args[i].TypeAsSignatureType); } } else { CodeEmitterLocal ghost = ilGenerator.AllocTempLocal(finish.Context.Types.Object); - ilGenerator.Emit(OpCodes.Stloc, ghost); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Stloc, ghost); CodeEmitterLocal local = ilGenerator.AllocTempLocal(args[i].TypeAsSignatureType); - ilGenerator.Emit(OpCodes.Ldloca, local); - ilGenerator.Emit(OpCodes.Ldloc, ghost); - ilGenerator.Emit(OpCodes.Stfld, args[i].GhostRefField); - ilGenerator.Emit(OpCodes.Ldloca, local); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldloca, local); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldloc, ghost); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Stfld, args[i].GhostRefField); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldloca, local); ilGenerator.ReleaseTempLocal(local); ilGenerator.ReleaseTempLocal(ghost); // NOTE when the this argument is a value type, we need the address on the stack instead of the value if (i != 0 || !instanceMethod) { - ilGenerator.Emit(OpCodes.Ldobj, args[i].TypeAsSignatureType); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldobj, args[i].TypeAsSignatureType); } } } @@ -3283,7 +3283,7 @@ void CastInterfaceArgs(RuntimeJavaType declaringType, RuntimeJavaType[] args, in // we only need to unbox if the method was actually declared on the value type if (declaringType == args[i]) { - ilGenerator.Emit(OpCodes.Unbox, args[i].TypeAsTBD); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Unbox, args[i].TypeAsTBD); } } else @@ -3293,7 +3293,7 @@ void CastInterfaceArgs(RuntimeJavaType declaringType, RuntimeJavaType[] args, in } else if (ma.GetRawStackTypeWrapper(instructionIndex, args.Length - 1 - i).IsUnloadable) { - ilGenerator.Emit(OpCodes.Castclass, args[i].TypeAsSignatureType); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Castclass, args[i].TypeAsSignatureType); } } } @@ -3350,7 +3350,7 @@ private void DynamicGetPutField(Instruction instr, int i) } else if (fieldType == finish.Context.PrimitiveJavaTypeFactory.DOUBLE) { - ilGenerator.Emit(OpCodes.Conv_R8); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Conv_R8); } } finish.GetValue(instr.Arg1 | ((byte)kind << 24)).Emit(this, cpi, kind); @@ -3368,16 +3368,16 @@ private static void EmitReturnTypeConversion(CodeEmitter ilgen, RuntimeJavaType } else if (typeWrapper == ilgen.Context.PrimitiveJavaTypeFactory.VOID) { - ilgen.Emit(OpCodes.Pop); + ilgen.Emit(System.Reflection.Emit.OpCodes.Pop); } else if (typeWrapper.IsPrimitive) { // NOTE we don't need to use TypeWrapper.EmitUnbox, because the return value cannot be null - ilgen.Emit(OpCodes.Unbox, typeWrapper.TypeAsTBD); - ilgen.Emit(OpCodes.Ldobj, typeWrapper.TypeAsTBD); + ilgen.Emit(System.Reflection.Emit.OpCodes.Unbox, typeWrapper.TypeAsTBD); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldobj, typeWrapper.TypeAsTBD); if (typeWrapper == ilgen.Context.PrimitiveJavaTypeFactory.BYTE) { - ilgen.Emit(OpCodes.Conv_I1); + ilgen.Emit(System.Reflection.Emit.OpCodes.Conv_I1); } } else @@ -3443,23 +3443,23 @@ internal static void EmitLinkToCall(RuntimeContext context, CodeEmitter ilgen, R { temps[i] = ilgen.DeclareLocal(context.MethodHandleUtil.AsBasicType(args[i])); ToBasic(args[i], ilgen); - ilgen.Emit(OpCodes.Stloc, temps[i]); + ilgen.Emit(System.Reflection.Emit.OpCodes.Stloc, temps[i]); } temps[0] = ilgen.DeclareLocal(args[0].TypeAsSignatureType); - ilgen.Emit(OpCodes.Stloc, temps[0]); + ilgen.Emit(System.Reflection.Emit.OpCodes.Stloc, temps[0]); Array.Resize(ref args, args.Length - 1); Type delegateType = context.MethodHandleUtil.CreateMemberWrapperDelegateType(args, retType); - ilgen.Emit(OpCodes.Ldloc, temps[args.Length]); - ilgen.Emit(OpCodes.Ldfld, typeof(java.lang.invoke.MemberName).GetField("vmtarget", BindingFlags.Instance | BindingFlags.NonPublic)); - ilgen.Emit(OpCodes.Castclass, delegateType); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldloc, temps[args.Length]); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldfld, typeof(java.lang.invoke.MemberName).GetField("vmtarget", BindingFlags.Instance | BindingFlags.NonPublic)); + ilgen.Emit(System.Reflection.Emit.OpCodes.Castclass, delegateType); for (int i = 0; i < args.Length; i++) { - ilgen.Emit(OpCodes.Ldloc, temps[i]); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldloc, temps[i]); } context.MethodHandleUtil.EmitCallDelegateInvokeMethod(ilgen, delegateType); FromBasic(retType, ilgen); #else - throw new InvalidOperationException(); + throw new InvalidOperationException(); #endif } @@ -3470,25 +3470,25 @@ private void EmitInvokeExact(CodeEmitter ilgen) for (int i = args.Length - 1; i >= 0; i--) { temps[i] = ilgen.DeclareLocal(args[i].TypeAsSignatureType); - ilgen.Emit(OpCodes.Stloc, temps[i]); + ilgen.Emit(System.Reflection.Emit.OpCodes.Stloc, temps[i]); } var delegateType = ilgen.Context.MethodHandleUtil.CreateMethodHandleDelegateType(args, cpi.GetRetType()); if (HasUnloadable(cpi.GetArgTypes(), cpi.GetRetType())) { // TODO consider sharing the cache for the same signatures - ilgen.Emit(OpCodes.Ldsflda, compiler.finish.DefineDynamicMethodTypeCacheField()); - ilgen.Emit(OpCodes.Ldstr, cpi.Signature); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldsflda, compiler.finish.DefineDynamicMethodTypeCacheField()); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldstr, cpi.Signature); compiler.finish.EmitCallerID(ilgen, compiler.m.IsLambdaFormCompiled); - ilgen.Emit(OpCodes.Call, ilgen.Context.ByteCodeHelperMethods.DynamicLoadMethodType); - ilgen.Emit(OpCodes.Call, ilgen.Context.ByteCodeHelperMethods.LoadMethodType.MakeGenericMethod(delegateType)); - ilgen.Emit(OpCodes.Call, ilgen.Context.ByteCodeHelperMethods.DynamicEraseInvokeExact); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, ilgen.Context.ByteCodeHelperMethods.DynamicLoadMethodType); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, ilgen.Context.ByteCodeHelperMethods.LoadMethodType.MakeGenericMethod(delegateType)); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, ilgen.Context.ByteCodeHelperMethods.DynamicEraseInvokeExact); } var mi = ilgen.Context.ByteCodeHelperMethods.GetDelegateForInvokeExact.MakeGenericMethod(delegateType); - ilgen.Emit(OpCodes.Call, mi); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, mi); for (int i = 0; i < args.Length; i++) - ilgen.Emit(OpCodes.Ldloc, temps[i]); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldloc, temps[i]); ilgen.Context.MethodHandleUtil.EmitCallDelegateInvokeMethod(ilgen, delegateType); } @@ -3500,58 +3500,60 @@ private void EmitInvokeMaxArity(CodeEmitter ilgen) for (int i = args.Length - 1; i >= 0; i--) { temps[i] = ilgen.DeclareLocal(args[i].TypeAsSignatureType); - ilgen.Emit(OpCodes.Stloc, temps[i]); + ilgen.Emit(System.Reflection.Emit.OpCodes.Stloc, temps[i]); } var delegateType = compiler.finish.Context.MethodHandleUtil.CreateMethodHandleDelegateType(args, cpi.GetRetType()); - ilgen.Emit(OpCodes.Call, compiler.finish.Context.ByteCodeHelperMethods.LoadMethodType.MakeGenericMethod(delegateType)); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, compiler.finish.Context.ByteCodeHelperMethods.LoadMethodType.MakeGenericMethod(delegateType)); compiler.finish.Context.JavaBase.TypeOfJavaLangInvokeMethodHandle.GetMethodWrapper("asType", "(Ljava.lang.invoke.MethodType;)Ljava.lang.invoke.MethodHandle;", false).EmitCallvirt(ilgen); var mi = compiler.finish.Context.ByteCodeHelperMethods.GetDelegateForInvokeExact.MakeGenericMethod(delegateType); - ilgen.Emit(OpCodes.Call, mi); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, mi); for (int i = 0; i < args.Length; i++) { - ilgen.Emit(OpCodes.Ldloc, temps[i]); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldloc, temps[i]); } compiler.finish.Context.MethodHandleUtil.EmitCallDelegateInvokeMethod(ilgen, delegateType); } - private void EmitInvoke(CodeEmitter ilgen) + void EmitInvoke(CodeEmitter ilgen) { if (cpi.GetArgTypes().Length >= 127 && compiler.finish.Context.MethodHandleUtil.SlotCount(cpi.GetArgTypes()) >= 254) { EmitInvokeMaxArity(ilgen); return; } - RuntimeJavaType[] args = ArrayUtil.Concat(compiler.finish.Context.JavaBase.TypeOfJavaLangInvokeMethodHandle, cpi.GetArgTypes()); - CodeEmitterLocal[] temps = new CodeEmitterLocal[args.Length]; + + var args = ArrayUtil.Concat(compiler.finish.Context.JavaBase.TypeOfJavaLangInvokeMethodHandle, cpi.GetArgTypes()); + var temps = new CodeEmitterLocal[args.Length]; for (int i = args.Length - 1; i >= 0; i--) { temps[i] = ilgen.DeclareLocal(args[i].TypeAsSignatureType); - ilgen.Emit(OpCodes.Stloc, temps[i]); + ilgen.Emit(System.Reflection.Emit.OpCodes.Stloc, temps[i]); } - Type delegateType = compiler.finish.Context.MethodHandleUtil.CreateMethodHandleDelegateType(args, cpi.GetRetType()); + + var delegateType = compiler.finish.Context.MethodHandleUtil.CreateMethodHandleDelegateType(args, cpi.GetRetType()); var mi = ilgen.Context.ByteCodeHelperMethods.GetDelegateForInvoke.MakeGenericMethod(delegateType); - var typeofInvokeCache = compiler.finish.Context.Resolver.ResolveRuntimeType("IKVM.Runtime.InvokeCache`1").AsReflection(); + var typeofInvokeCache = compiler.finish.Context.Resolver.ResolveRuntimeType("IKVM.Runtime.InvokeCache`1"); var fb = compiler.finish.DefineMethodHandleInvokeCacheField(typeofInvokeCache.MakeGenericType(delegateType)); - ilgen.Emit(OpCodes.Ldloc, temps[0]); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldloc, temps[0]); if (HasUnloadable(cpi.GetArgTypes(), cpi.GetRetType())) { // TODO consider sharing the cache for the same signatures - ilgen.Emit(OpCodes.Ldsflda, compiler.finish.DefineDynamicMethodTypeCacheField()); - ilgen.Emit(OpCodes.Ldstr, cpi.Signature); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldsflda, compiler.finish.DefineDynamicMethodTypeCacheField()); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldstr, cpi.Signature); compiler.finish.EmitCallerID(ilgen, compiler.m.IsLambdaFormCompiled); - ilgen.Emit(OpCodes.Call, ilgen.Context.ByteCodeHelperMethods.DynamicLoadMethodType); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, ilgen.Context.ByteCodeHelperMethods.DynamicLoadMethodType); } else { - ilgen.Emit(OpCodes.Ldnull); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldnull); } - ilgen.Emit(OpCodes.Ldsflda, fb); - ilgen.Emit(OpCodes.Call, mi); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldsflda, fb); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, mi); for (int i = 0; i < args.Length; i++) { - ilgen.Emit(OpCodes.Ldloc, temps[i]); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldloc, temps[i]); } compiler.finish.Context.MethodHandleUtil.EmitCallDelegateInvokeMethod(ilgen, delegateType); } @@ -3574,17 +3576,17 @@ internal static void EmitInvokeBasic(RuntimeContext context, CodeEmitter ilgen, { ToBasic(args[i], ilgen); } - ilgen.Emit(OpCodes.Stloc, temps[i]); + ilgen.Emit(System.Reflection.Emit.OpCodes.Stloc, temps[i]); } temps[0] = ilgen.DeclareLocal(args[0].TypeAsSignatureType); - ilgen.Emit(OpCodes.Stloc, temps[0]); + ilgen.Emit(System.Reflection.Emit.OpCodes.Stloc, temps[0]); var delegateType = context.MethodHandleUtil.CreateMemberWrapperDelegateType(args, retType); var mi = context.ByteCodeHelperMethods.GetDelegateForInvokeBasic.MakeGenericMethod(delegateType); - ilgen.Emit(OpCodes.Ldloc, temps[0]); - ilgen.Emit(OpCodes.Call, mi); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldloc, temps[0]); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, mi); for (int i = 0; i < args.Length; i++) { - ilgen.Emit(OpCodes.Ldloc, temps[i]); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldloc, temps[i]); } context.MethodHandleUtil.EmitCallDelegateInvokeMethod(ilgen, delegateType); } @@ -3623,7 +3625,7 @@ internal void Emit(Compiler compiler, ClassFile.ConstantPoolItemFieldref cpi, Me if (method == null) method = CreateMethod(compiler, cpi, kind); - compiler.ilGenerator.Emit(OpCodes.Call, method); + compiler.ilGenerator.Emit(System.Reflection.Emit.OpCodes.Call, method); } private static IMethodSymbol CreateMethod(Compiler compiler, ClassFile.ConstantPoolItemFieldref cpi, MethodHandleKind kind) @@ -3703,13 +3705,13 @@ internal static IMethodSymbol Emit(Compiler compiler, MethodHandleKind kind, Cla var mb = compiler.finish.DefineMethodHandleDispatchStub(ret.TypeAsSignatureType, types); var ilgen = compiler.finish.Context.CodeEmitterFactory.Create(mb); - ilgen.Emit(OpCodes.Ldsfld, fb); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldsfld, fb); var label = ilgen.DefineLabel(); ilgen.EmitBrtrue(label); ilgen.EmitLdc_I4((int)kind); - ilgen.Emit(OpCodes.Ldstr, cpi.Class); - ilgen.Emit(OpCodes.Ldstr, cpi.Name); - ilgen.Emit(OpCodes.Ldstr, cpi.Signature); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldstr, cpi.Class); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldstr, cpi.Name); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldstr, cpi.Signature); if (privileged) { compiler.finish.EmitHostCallerID(ilgen); @@ -3718,21 +3720,21 @@ internal static IMethodSymbol Emit(Compiler compiler, MethodHandleKind kind, Cla { compiler.finish.EmitCallerID(ilgen, compiler.m.IsLambdaFormCompiled); } - ilgen.Emit(OpCodes.Call, compiler.finish.Context.ByteCodeHelperMethods.DynamicBinderMemberLookup.MakeGenericMethod(delegateType)); - ilgen.Emit(OpCodes.Volatile); - ilgen.Emit(OpCodes.Stsfld, fb); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, compiler.finish.Context.ByteCodeHelperMethods.DynamicBinderMemberLookup.MakeGenericMethod(delegateType)); + ilgen.Emit(System.Reflection.Emit.OpCodes.Volatile); + ilgen.Emit(System.Reflection.Emit.OpCodes.Stsfld, fb); ilgen.MarkLabel(label); - ilgen.Emit(OpCodes.Ldsfld, fb); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldsfld, fb); for (int i = 0; i < args.Length; i++) { ilgen.EmitLdarg(i); if (i == 0 && ghostTarget) { - ilgen.Emit(OpCodes.Ldobj, args[0].TypeAsSignatureType); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldobj, args[0].TypeAsSignatureType); } } compiler.finish.Context.MethodHandleUtil.EmitCallDelegateInvokeMethod(ilgen, delegateType); - ilgen.Emit(OpCodes.Ret); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ret); ilgen.DoEmit(); return mb; } @@ -3750,17 +3752,17 @@ internal DynamicBinderMethodWrapper(ClassFile.ConstantPoolItemMI cpi, IMethodSym internal override void EmitCall(CodeEmitter ilgen) { - ilgen.Emit(OpCodes.Call, method); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, method); } internal override void EmitCallvirt(CodeEmitter ilgen) { - ilgen.Emit(OpCodes.Call, method); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, method); } internal override void EmitNewobj(CodeEmitter ilgen) { - ilgen.Emit(OpCodes.Call, method); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, method); } } @@ -3900,13 +3902,13 @@ private LocalVar LoadLocal(int instructionIndex) int i = m.ArgMap[instr.NormalizedArg1]; ilGenerator.EmitLdarg(i); if (v.type == finish.Context.PrimitiveJavaTypeFactory.DOUBLE) - ilGenerator.Emit(OpCodes.Conv_R8); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Conv_R8); if (v.type == finish.Context.PrimitiveJavaTypeFactory.FLOAT) - ilGenerator.Emit(OpCodes.Conv_R4); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Conv_R4); } else if (v.type == finish.Context.VerifierJavaTypeFactory.Null) { - ilGenerator.Emit(OpCodes.Ldnull); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldnull); } else { @@ -3917,7 +3919,7 @@ private LocalVar LoadLocal(int instructionIndex) v.builder.SetLocalSymInfo(v.name); } - ilGenerator.Emit(OpCodes.Ldloc, v.builder); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldloc, v.builder); } return v; @@ -3929,7 +3931,7 @@ LocalVar StoreLocal(int instructionIndex) if (v == null) { // dead store - ilGenerator.Emit(OpCodes.Pop); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Pop); } else if (v.isArg) { @@ -3939,7 +3941,7 @@ LocalVar StoreLocal(int instructionIndex) } else if (v.type == finish.Context.VerifierJavaTypeFactory.Null) { - ilGenerator.Emit(OpCodes.Pop); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Pop); } else { @@ -3949,7 +3951,7 @@ LocalVar StoreLocal(int instructionIndex) if (debug && v.name != null) v.builder.SetLocalSymInfo(v.name); } - ilGenerator.Emit(OpCodes.Stloc, v.builder); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Stloc, v.builder); } return v; diff --git a/src/IKVM.Runtime/intrinsics.cs b/src/IKVM.Runtime/intrinsics.cs index fab8a4e37..14f5c24ff 100644 --- a/src/IKVM.Runtime/intrinsics.cs +++ b/src/IKVM.Runtime/intrinsics.cs @@ -24,18 +24,14 @@ Jeroen Frijters using System; using System.Collections.Generic; +using System.Reflection; +using System.Reflection.Emit; using IKVM.CoreLib.Diagnostics; +using IKVM.CoreLib.Symbols; #if IMPORTER -using IKVM.Reflection; -using IKVM.Reflection.Emit; using IKVM.Tools.Importer; - -using Type = IKVM.Reflection.Type; -#else -using System.Reflection; -using System.Reflection.Emit; #endif using Instruction = IKVM.Runtime.ClassFile.Method.Instruction; @@ -228,29 +224,29 @@ private static bool IsSafeForGetClassOptimization(RuntimeJavaType tw) private static bool Float_floatToRawIntBits(EmitIntrinsicContext eic) { - EmitConversion(eic.Emitter, eic.Method.DeclaringType.Context.Resolver.ResolveRuntimeType("IKVM.Runtime.FloatConverter").AsReflection(), "ToInt"); + EmitConversion(eic.Emitter, eic.Method.DeclaringType.Context.Resolver.ResolveRuntimeType("IKVM.Runtime.FloatConverter"), "ToInt"); return true; } private static bool Float_intBitsToFloat(EmitIntrinsicContext eic) { - EmitConversion(eic.Emitter, eic.Method.DeclaringType.Context.Resolver.ResolveRuntimeType("IKVM.Runtime.FloatConverter").AsReflection(), "ToFloat"); + EmitConversion(eic.Emitter, eic.Method.DeclaringType.Context.Resolver.ResolveRuntimeType("IKVM.Runtime.FloatConverter"), "ToFloat"); return true; } private static bool Double_doubleToRawLongBits(EmitIntrinsicContext eic) { - EmitConversion(eic.Emitter, eic.Method.DeclaringType.Context.Resolver.ResolveRuntimeType("IKVM.Runtime.DoubleConverter").AsReflection(), "ToLong"); + EmitConversion(eic.Emitter, eic.Method.DeclaringType.Context.Resolver.ResolveRuntimeType("IKVM.Runtime.DoubleConverter"), "ToLong"); return true; } static bool Double_longBitsToDouble(EmitIntrinsicContext eic) { - EmitConversion(eic.Emitter, eic.Method.DeclaringType.Context.Resolver.ResolveRuntimeType("IKVM.Runtime.DoubleConverter").AsReflection(), "ToDouble"); + EmitConversion(eic.Emitter, eic.Method.DeclaringType.Context.Resolver.ResolveRuntimeType("IKVM.Runtime.DoubleConverter"), "ToDouble"); return true; } - static void EmitConversion(CodeEmitter ilgen, Type converterType, string method) + static void EmitConversion(CodeEmitter ilgen, ITypeSymbol converterType, string method) { var converter = ilgen.UnsafeAllocTempLocal(converterType); ilgen.Emit(OpCodes.Ldloca, converter); @@ -1003,7 +999,7 @@ static bool Unsafe_compareAndSwapLong(EmitIntrinsicContext eic) } } - internal static MethodInfo MakeExchange(RuntimeContext context, Type type) + internal static IMethodSymbol MakeExchange(RuntimeContext context, ITypeSymbol type) { return context.InterlockedMethods.ExchangeOfT.MakeGenericMethod(type); } diff --git a/src/IKVM.Tools.Exporter/ExportImpl.cs b/src/IKVM.Tools.Exporter/ExportImpl.cs index dc57fffe8..322042b35 100644 --- a/src/IKVM.Tools.Exporter/ExportImpl.cs +++ b/src/IKVM.Tools.Exporter/ExportImpl.cs @@ -8,6 +8,7 @@ using IKVM.CoreLib.Diagnostics; using IKVM.CoreLib.Symbols; +using IKVM.CoreLib.Symbols.IkvmReflection; using IKVM.Reflection; using IKVM.Runtime; using IKVM.Tools.Importer; @@ -78,6 +79,7 @@ public int Execute() // build universe and resolver against universe and references var universe = new Universe(coreLibName); + var symbols = new IkvmReflectionSymbolContext(universe); var assemblyResolver = new AssemblyResolver(); assemblyResolver.Warning += new AssemblyResolver.WarningEvent(Resolver_Warning); assemblyResolver.Init(universe, options.NoStdLib, references, libpaths); @@ -145,7 +147,7 @@ public int Execute() } compiler = new StaticCompiler(universe, assemblyResolver, runtimeAssembly); - context = new RuntimeContext(new RuntimeContextOptions(), diagnostics, new ManagedTypeResolver(compiler, null), true, compiler); + context = new RuntimeContext(new RuntimeContextOptions(), diagnostics, new ManagedTypeResolver(symbols, compiler, null), true, compiler); context.ClassLoaderFactory.SetBootstrapClassLoader(new RuntimeBootstrapClassLoader(context)); } else @@ -172,7 +174,7 @@ public int Execute() } compiler = new StaticCompiler(universe, assemblyResolver, runtimeAssembly); - context = new RuntimeContext(new RuntimeContextOptions(), diagnostics, new ManagedTypeResolver(compiler, baseAssembly), false, compiler); + context = new RuntimeContext(new RuntimeContextOptions(), diagnostics, new ManagedTypeResolver(symbols, compiler, baseAssembly), false, compiler); } if (context.AttributeHelper.IsJavaModule(context.Resolver.ResolveModule(assembly.ManifestModule))) diff --git a/src/IKVM.Tools.Exporter/ManagedTypeResolver.cs b/src/IKVM.Tools.Exporter/ManagedTypeResolver.cs index 3d9941628..111b284f6 100644 --- a/src/IKVM.Tools.Exporter/ManagedTypeResolver.cs +++ b/src/IKVM.Tools.Exporter/ManagedTypeResolver.cs @@ -1,4 +1,6 @@ -using System; +#nullable enable + +using System; using IKVM.CoreLib.Symbols; using IKVM.CoreLib.Symbols.IkvmReflection; @@ -11,85 +13,104 @@ namespace IKVM.Tools.Exporter { class ManagedTypeResolver : IRuntimeSymbolResolver - { + { - readonly StaticCompiler compiler; - readonly Assembly baseAssembly; - readonly IkvmReflectionSymbolContext symbols = new(); + readonly StaticCompiler compiler; + readonly Assembly baseAssembly; + readonly IkvmReflectionSymbolContext symbols; /// /// Initializes a new instance. /// /// /// - public ManagedTypeResolver(StaticCompiler compiler, Assembly baseAssembly) - { - this.compiler = compiler ?? throw new ArgumentNullException(nameof(compiler)); - this.baseAssembly = baseAssembly; + public ManagedTypeResolver(IkvmReflectionSymbolContext symbols, StaticCompiler compiler, Assembly baseAssembly) + { + this.symbols = symbols ?? throw new ArgumentNullException(nameof(symbols)); + this.compiler = compiler ?? throw new ArgumentNullException(nameof(compiler)); + this.baseAssembly = baseAssembly; } - /// + /// public ISymbolContext Symbols => symbols; /// /// Attempts to resolve the base Java assembly. /// /// - public IAssemblySymbol ResolveBaseAssembly() - { - return baseAssembly != null ? symbols.GetOrCreateAssemblySymbol(baseAssembly) : null; - } - - /// - /// Attempts to resolve an assembly from one of the assembly sources. - /// - /// - /// - public IAssemblySymbol ResolveAssembly(string assemblyName) - { - return compiler.Load(assemblyName) is { } a ? symbols.GetOrCreateAssemblySymbol(a) : null; - } - - /// - /// Attempts to resolve a type from one of the assembly sources. - /// - /// - /// - public ITypeSymbol ResolveCoreType(string typeName) - { - foreach (var assembly in compiler.Universe.GetAssemblies()) - if (assembly.GetType(typeName) is Type t) - return ResolveType(t); - - return null; - } - - /// - /// Attempts to resolve a type from the IKVM runtime assembly. - /// - /// - /// - public ITypeSymbol ResolveRuntimeType(string typeName) - { - return compiler.GetRuntimeType(typeName) is { } t ? symbols.GetOrCreateTypeSymbol(t) : null; + public IAssemblySymbol? ResolveBaseAssembly() + { + return ResolveAssembly(baseAssembly); + } + + /// + /// Attempts to resolve an assembly from one of the assembly sources. + /// + /// + /// + public IAssemblySymbol? ResolveAssembly(string assemblyName) + { + return ResolveAssembly(compiler.Load(assemblyName)); + } + + /// + /// Attempts to resolve a type from one of the assembly sources. + /// + /// + /// + public ITypeSymbol? ResolveCoreType(string typeName) + { + foreach (var assembly in compiler.Universe.GetAssemblies()) + if (assembly.GetType(typeName) is Type t) + return ResolveType(t); + + return null; + } + + /// + /// Attempts to resolve a type from the IKVM runtime assembly. + /// + /// + /// + public ITypeSymbol? ResolveRuntimeType(string typeName) + { + return ResolveType(compiler.GetRuntimeType(typeName)); + } + + /// + public IAssemblySymbol? ResolveAssembly(Assembly? assembly) + { + return assembly != null ? symbols.GetOrCreateAssemblySymbol(assembly) : null; + } + + /// + public IModuleSymbol? ResolveModule(Module? module) + { + return module != null ? symbols.GetOrCreateModuleSymbol(module) : null; + } + + /// + public ITypeSymbol? ResolveType(Type? type) + { + return type != null ? symbols.GetOrCreateTypeSymbol(type) : null; } /// - public IAssemblySymbol ResolveAssembly(Assembly assembly) + public IMethodBaseSymbol? ResolveMethodBase(MethodBase? method) { - return symbols.GetOrCreateAssemblySymbol(assembly); + return method != null ? symbols.GetOrCreateMethodBaseSymbol(method) : null; } /// - public IModuleSymbol ResolveModule(Module module) + public IConstructorSymbol? ResolveConstructor(ConstructorInfo? ctor) { - return symbols.GetOrCreateModuleSymbol(module); + return ctor != null ? symbols.GetOrCreateConstructorSymbol(ctor) : null; } /// - public ITypeSymbol ResolveType(Type type) + public IMethodSymbol? ResolveMethod(MethodInfo? method) { - return symbols.GetOrCreateTypeSymbol(type); + return method != null ? symbols.GetOrCreateMethodSymbol(method) : null; } } diff --git a/src/ikvmstub/Properties/launchSettings.json b/src/ikvmstub/Properties/launchSettings.json index 88236f0da..7cb1e7372 100644 --- a/src/ikvmstub/Properties/launchSettings.json +++ b/src/ikvmstub/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "ikvmstub": { "commandName": "Project", - "commandLineArgs": "foo.dll -out foo.jar -log json" + "commandLineArgs": "--bootstrap --nostdlib --parameters --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\Microsoft.VisualBasic.Core.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.IO.FileSystem.DriveInfo.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Runtime.dll\" --reference:\"D:\\ikvm\\src\\IKVM.Java-ref\\obj\\Debug\\net8.0\\ref\\IKVM.Java.dll\" --reference:\"D:\\ikvm\\src\\IKVM.Runtime-ref\\obj\\Debug\\net8.0\\ref\\IKVM.Runtime.dll\" --out:\"C:\\Users\\jhaltom\\Microsoft.VisualBasic.Core.jar\" \"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\Microsoft.VisualBasic.Core.dll\"" } } } \ No newline at end of file diff --git a/src/ikvmstub/ikvmstub.csproj b/src/ikvmstub/ikvmstub.csproj index 1d89f5a4d..15e796a6b 100644 --- a/src/ikvmstub/ikvmstub.csproj +++ b/src/ikvmstub/ikvmstub.csproj @@ -1,7 +1,7 @@  Exe - net472;net6.0;net8.0 + net8.0;net472;net6.0 $(_SupportedToolRuntimes) true true diff --git a/testenvironments.json b/testenvironments.json index 051d6ff28..9e94f92b2 100644 --- a/testenvironments.json +++ b/testenvironments.json @@ -13,4 +13,3 @@ } ] } - From 1da941c1fac49efaeeb4c8f638277c9a67bb312d Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Fri, 20 Sep 2024 20:45:57 -0500 Subject: [PATCH 11/51] Fix array length. Turn on -skiperror. Need to figure out what happened here. Fix libpath for discovery of corelibname. --- .../IkvmReflection/IkvmReflectionTypeSpecTable.cs | 2 +- .../targets/IKVM.Java.Core.NoTasks.targets | 1 + src/IKVM.Runtime/MethodHandleUtil.compiler.cs | 5 ++++- src/IKVM.Runtime/RuntimeArrayJavaType.cs | 2 +- ...e.JavaTypeImpl.DelegateInvokeStubMethodWrapper.cs | 2 +- src/IKVM.Runtime/RuntimeByteCodeJavaType.cs | 5 ++++- src/IKVM.Runtime/RuntimeJavaType.cs | 12 +++++++----- .../RuntimeManagedJavaType.ByRefJavaMethod.cs | 2 +- ...timeManagedJavaType.DelegateInnerClassJavaType.cs | 2 +- src/IKVM.Runtime/RuntimeManagedJavaType.cs | 2 +- src/IKVM.Runtime/compiler.cs | 5 +++-- src/IKVM.Tools.Exporter/ExportImpl.cs | 6 ++++++ src/ikvmstub/Properties/launchSettings.json | 4 ++-- 13 files changed, 33 insertions(+), 17 deletions(-) diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSpecTable.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSpecTable.cs index 4a3de6e08..f52e96eb4 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSpecTable.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSpecTable.cs @@ -91,7 +91,7 @@ public IIkvmReflectionTypeSymbol GetOrCreatePointerTypeSymbol() public IIkvmReflectionTypeSymbol GetOrCreateByRefTypeSymbol() { if (_asByRef == null) - Interlocked.CompareExchange(ref _asByRef, new IkvmReflectionTypeSymbol(_context, _module, _elementType.UnderlyingType.MakePointerType()), null); + Interlocked.CompareExchange(ref _asByRef, new IkvmReflectionTypeSymbol(_context, _module, _elementType.UnderlyingType.MakeByRefType()), null); return _asByRef; } diff --git a/src/IKVM.NET.Sdk/targets/IKVM.Java.Core.NoTasks.targets b/src/IKVM.NET.Sdk/targets/IKVM.Java.Core.NoTasks.targets index 15b39348c..5d2016920 100644 --- a/src/IKVM.NET.Sdk/targets/IKVM.Java.Core.NoTasks.targets +++ b/src/IKVM.NET.Sdk/targets/IKVM.Java.Core.NoTasks.targets @@ -137,6 +137,7 @@ Value = b.ToString(); <_IkvmExporterArgs Remove="@(_IkvmExporterArgs)" /> <_IkvmExporterArgs Include="--bootstrap" Condition=" '%(ReferenceExport.Bootstrap)' == 'true' " /> <_IkvmExporterArgs Include="--nostdlib" Condition=" '%(ReferenceExport.NoStdLib)' == 'true' " /> + <_IkvmExporterArgs Include="--skiperror" /> <_IkvmExporterArgs Include="--non-public-types" Condition=" '%(ReferenceExport.IncludeNonPublicTypes)' == 'true' " /> <_IkvmExporterArgs Include="--non-public-interfaces" Condition=" '%(ReferenceExport.IncludeNonPublicInterfaces)' == 'true' " /> <_IkvmExporterArgs Include="--non-public-members" Condition=" '%(ReferenceExport.IncludeNonPublicMembers)' == 'true' " /> diff --git a/src/IKVM.Runtime/MethodHandleUtil.compiler.cs b/src/IKVM.Runtime/MethodHandleUtil.compiler.cs index 4772fd86e..5015c8972 100644 --- a/src/IKVM.Runtime/MethodHandleUtil.compiler.cs +++ b/src/IKVM.Runtime/MethodHandleUtil.compiler.cs @@ -84,7 +84,10 @@ ITypeSymbol TypeWrapperToTypeForLoadConstant(RuntimeJavaType tw) while (tw.IsArray) tw = tw.ElementTypeWrapper; - return tw.TypeAsSignatureType.MakeArrayType(dims); + if (dims == 1) + return tw.TypeAsSignatureType.MakeArrayType(); + else + return tw.TypeAsSignatureType.MakeArrayType(dims); } else { diff --git a/src/IKVM.Runtime/RuntimeArrayJavaType.cs b/src/IKVM.Runtime/RuntimeArrayJavaType.cs index 72934b2d5..4d681af32 100644 --- a/src/IKVM.Runtime/RuntimeArrayJavaType.cs +++ b/src/IKVM.Runtime/RuntimeArrayJavaType.cs @@ -119,7 +119,7 @@ internal override ITypeSymbol TypeAsTBD while (arrayType == null) { bool prevFinished = finished; - var type = ultimateElementTypeWrapper.TypeAsArrayType.MakeArrayType(ArrayRank); + var type = ArrayRank == 1 ? ultimateElementTypeWrapper.TypeAsArrayType.MakeArrayType() : ultimateElementTypeWrapper.TypeAsArrayType.MakeArrayType(ArrayRank); if (prevFinished) { // We were already finished prior to the call to MakeArrayType, so we can safely diff --git a/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.DelegateInvokeStubMethodWrapper.cs b/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.DelegateInvokeStubMethodWrapper.cs index ad9115d70..364179d83 100644 --- a/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.DelegateInvokeStubMethodWrapper.cs +++ b/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.DelegateInvokeStubMethodWrapper.cs @@ -87,7 +87,7 @@ internal IMethodSymbol DoLink(ITypeSymbolBuilder tb) if (parameters[i].ParameterType.IsByRef) { var elemType = parameters[i].ParameterType.GetElementType(); - var local = ilgen.DeclareLocal(elemType.MakeArrayType(1)); + var local = ilgen.DeclareLocal(elemType.MakeArrayType()); byrefs[i] = local; ilgen.Emit(OpCodes.Ldc_I4_1); ilgen.Emit(OpCodes.Newarr, elemType); diff --git a/src/IKVM.Runtime/RuntimeByteCodeJavaType.cs b/src/IKVM.Runtime/RuntimeByteCodeJavaType.cs index d7801d44f..f58a1df74 100644 --- a/src/IKVM.Runtime/RuntimeByteCodeJavaType.cs +++ b/src/IKVM.Runtime/RuntimeByteCodeJavaType.cs @@ -934,7 +934,10 @@ static ITypeSymbol GetModOptHelper(RuntimeJavaType tw) if (tw.IsArray) { - return GetModOptHelper(tw.GetUltimateElementTypeWrapper()).MakeArrayType(tw.ArrayRank); + if (tw.ArrayRank == 1) + return GetModOptHelper(tw.GetUltimateElementTypeWrapper()).MakeArrayType(); + else + return GetModOptHelper(tw.GetUltimateElementTypeWrapper()).MakeArrayType(tw.ArrayRank); } else if (tw.IsGhost) { diff --git a/src/IKVM.Runtime/RuntimeJavaType.cs b/src/IKVM.Runtime/RuntimeJavaType.cs index 53d61e830..70d6189dd 100644 --- a/src/IKVM.Runtime/RuntimeJavaType.cs +++ b/src/IKVM.Runtime/RuntimeJavaType.cs @@ -929,7 +929,7 @@ internal ITypeSymbol TypeAsSignatureType return ((RuntimeUnloadableJavaType)this).MissingType ?? context.Types.Object; if (IsGhostArray) - return context.Types.Object.MakeArrayType(ArrayRank); + return ArrayRank == 1 ? context.Types.Object.MakeArrayType() : context.Types.Object.MakeArrayType(ArrayRank); return TypeAsTBD; } @@ -953,7 +953,7 @@ internal ITypeSymbol TypeAsLocalOrStackType } if (IsGhostArray) - return context.Types.Object.MakeArrayType(ArrayRank); + return ArrayRank == 1 ? context.Types.Object.MakeArrayType() : context.Types.Object.MakeArrayType(ArrayRank); return TypeAsTBD; } @@ -968,7 +968,7 @@ internal ITypeSymbol TypeAsArrayType return context.Types.Object; if (IsGhostArray) - return context.Types.Object.MakeArrayType(ArrayRank); + return ArrayRank == 1 ? context.Types.Object.MakeArrayType() : context.Types.Object.MakeArrayType(ArrayRank); return TypeAsTBD; } @@ -1306,19 +1306,21 @@ internal virtual void EmitCheckcast(CodeEmitter ilgen) else if (IsGhostArray) { ilgen.Emit(System.Reflection.Emit.OpCodes.Dup); + // TODO make sure we get the right "CastArray" method and cache it // NOTE for dynamic ghosts we don't end up here because AotTypeWrapper overrides this method, // so we're safe to call GetMethod on TypeAsTBD (because it has to be a compiled type, if we're here) - RuntimeJavaType tw = this; + var tw = this; int rank = 0; while (tw.IsArray) { rank++; tw = tw.ElementTypeWrapper; } + ilgen.EmitLdc_I4(rank); ilgen.Emit(System.Reflection.Emit.OpCodes.Call, tw.TypeAsTBD.GetMethod("CastArray")); - ilgen.Emit(System.Reflection.Emit.OpCodes.Castclass, context.Types.Object.MakeArrayType(rank)); + ilgen.Emit(System.Reflection.Emit.OpCodes.Castclass, rank == 1 ? context.Types.Object.MakeArrayType() : context.Types.Object.MakeArrayType(rank)); } else { diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.ByRefJavaMethod.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.ByRefJavaMethod.cs index fbafd618a..683a6b82a 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.ByRefJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.ByRefJavaMethod.cs @@ -89,7 +89,7 @@ void ConvertByRefArgs(CodeEmitter ilgen) { var type = args[i]; if (type.IsByRef) - type = type.GetElementType().MakeArrayType(1); + type = type.GetElementType().MakeArrayType(); locals[i] = ilgen.DeclareLocal(type); ilgen.Emit(OpCodes.Stloc, locals[i]); diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.DelegateInnerClassJavaType.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.DelegateInnerClassJavaType.cs index ed2ff469c..7d47c9090 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.DelegateInnerClassJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.DelegateInnerClassJavaType.cs @@ -67,7 +67,7 @@ internal DelegateInnerClassJavaType(RuntimeContext context, string name, ITypeSy if (parameterType.IsByRef) { flags |= MemberFlags.DelegateInvokeWithByRefParameter; - parameterType = parameterType.GetElementType().MakeArrayType(1); + parameterType = parameterType.GetElementType().MakeArrayType(); } argTypeWrappers[i] = Context.ClassLoaderFactory.GetJavaTypeFromType(parameterType); diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.cs index 7d9681430..a4df662c1 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.cs @@ -634,7 +634,7 @@ bool MakeMethodDescriptor(IMethodBaseSymbol mb, out string name, out string sig, if (type.IsByRef) { - type = type.GetElementType().MakeArrayType(1); + type = type.GetElementType().MakeArrayType(); if (mb.IsAbstract) { // Since we cannot override methods with byref arguments, we don't report abstract diff --git a/src/IKVM.Runtime/compiler.cs b/src/IKVM.Runtime/compiler.cs index c209e71e2..b2da6523b 100644 --- a/src/IKVM.Runtime/compiler.cs +++ b/src/IKVM.Runtime/compiler.cs @@ -1770,7 +1770,7 @@ void Compile(Block block, int startIndex) while (tw.IsArray) tw = tw.ElementTypeWrapper; - ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldtoken, tw.TypeAsTBD.MakeArrayType(wrapper.ArrayRank)); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldtoken, wrapper.ArrayRank == 1 ? tw.TypeAsTBD.MakeArrayType() : tw.TypeAsTBD.MakeArrayType(wrapper.ArrayRank)); ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldloc, localArray); ilGenerator.Emit(System.Reflection.Emit.OpCodes.Call, finish.Context.ByteCodeHelperMethods.multianewarray_ghost); ilGenerator.Emit(System.Reflection.Emit.OpCodes.Castclass, wrapper.TypeAsArrayType); @@ -1810,7 +1810,8 @@ void Compile(Block block, int startIndex) while (tw.IsArray) tw = tw.ElementTypeWrapper; - ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldtoken, tw.TypeAsTBD.MakeArrayType(wrapper.ArrayRank + 1)); + var rank = wrapper.ArrayRank + 1; + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldtoken, rank == 1 ? tw.TypeAsTBD.MakeArrayType() : tw.TypeAsTBD.MakeArrayType(rank)); ilGenerator.Emit(System.Reflection.Emit.OpCodes.Call, finish.Context.ByteCodeHelperMethods.anewarray_ghost.MakeGenericMethod(wrapper.TypeAsArrayType)); } else diff --git a/src/IKVM.Tools.Exporter/ExportImpl.cs b/src/IKVM.Tools.Exporter/ExportImpl.cs index 322042b35..149aaf055 100644 --- a/src/IKVM.Tools.Exporter/ExportImpl.cs +++ b/src/IKVM.Tools.Exporter/ExportImpl.cs @@ -246,6 +246,12 @@ static string FindCoreLibName(List references, List libpaths) if (GetAssemblyNameIfCoreLib(reference) is string coreLibName) return coreLibName; + foreach (var libpath in libpaths) + if (Directory.Exists(libpath)) + foreach (var reference in Directory.EnumerateFiles(libpath, "*.dll")) + if (GetAssemblyNameIfCoreLib(reference) is string coreLibName) + return coreLibName; + return null; } diff --git a/src/ikvmstub/Properties/launchSettings.json b/src/ikvmstub/Properties/launchSettings.json index 7cb1e7372..c08101f8e 100644 --- a/src/ikvmstub/Properties/launchSettings.json +++ b/src/ikvmstub/Properties/launchSettings.json @@ -1,8 +1,8 @@ { "profiles": { "ikvmstub": { - "commandName": "Project", - "commandLineArgs": "--bootstrap --nostdlib --parameters --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\Microsoft.VisualBasic.Core.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.IO.FileSystem.DriveInfo.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Runtime.dll\" --reference:\"D:\\ikvm\\src\\IKVM.Java-ref\\obj\\Debug\\net8.0\\ref\\IKVM.Java.dll\" --reference:\"D:\\ikvm\\src\\IKVM.Runtime-ref\\obj\\Debug\\net8.0\\ref\\IKVM.Runtime.dll\" --out:\"C:\\Users\\jhaltom\\Microsoft.VisualBasic.Core.jar\" \"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\Microsoft.VisualBasic.Core.dll\"" + "commandName": "Project", + "commandLineArgs": "--bootstrap --skiperror --nostdlib --parameters --lib:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\" --reference:\"D:\\ikvm\\src\\IKVM.Java-ref\\obj\\Debug\\net8.0\\ref\\IKVM.Java.dll\" --reference:\"D:\\ikvm\\src\\IKVM.Runtime-ref\\obj\\Debug\\net8.0\\ref\\IKVM.Runtime.dll\" --out:\"C:\\Users\\jhaltom\\System.Threading.jar\" \"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Threading.dll\"" } } } \ No newline at end of file From ae381ec4111045766e824e35466b4767359f49c0 Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Sun, 22 Sep 2024 14:59:48 -0500 Subject: [PATCH 12/51] It builds. --- .../Diagnostics/DiagnosticEvent.cs | 5 + .../Symbols/Emit/IAssemblySymbolBuilder.cs | 55 +- .../Symbols/Emit/IModuleSymbolBuilder.cs | 96 +++ .../Symbols/Emit/ITypeSymbolBuilder.cs | 8 + src/IKVM.CoreLib/Symbols/Emit/PEFileKinds.cs | 28 + src/IKVM.CoreLib/Symbols/IAssemblySymbol.cs | 37 ++ src/IKVM.CoreLib/Symbols/ISymbolContext.cs | 6 +- .../IkvmReflectionAssemblySymbolBuilder.cs | 73 +- .../Emit/IkvmReflectionModuleSymbolBuilder.cs | 79 +++ .../Emit/IkvmReflectionTypeSymbolBuilder.cs | 6 + .../IIkvmReflectionAssemblySymbol.cs | 4 +- .../IkvmReflectionAssemblySymbol.cs | 66 +- .../IkvmReflection/IkvmReflectionSymbol.cs | 7 + .../IkvmReflectionSymbolContext.cs | 93 +-- .../IkvmReflection/IkvmReflectionUtil.cs | 13 + src/IKVM.CoreLib/Symbols/ImageFileMachine.cs | 15 + .../Symbols/ManifestResourceInfo.cs | 29 + .../Emit/ReflectionAssemblySymbolBuilder.cs | 80 ++- .../Emit/ReflectionModuleSymbolBuilder.cs | 104 ++- .../Emit/ReflectionTypeSymbolBuilder.cs | 6 + .../Reflection/ReflectionAssemblySymbol.cs | 22 + .../Symbols/Reflection/ReflectionSymbol.cs | 6 + .../Reflection/ReflectionSymbolContext.cs | 8 +- .../Symbols/TypeSymbolExtensions.cs | 43 ++ src/IKVM.Reflection/Assembly.cs | 30 + src/IKVM.Runtime/Annotation.cs | 9 +- src/IKVM.Runtime/AttributeHelper.cs | 42 +- src/IKVM.Runtime/CodeEmitter.cs | 16 +- src/IKVM.Runtime/IRuntimeSymbolResolver.cs | 24 + src/IKVM.Runtime/ReflectUtil.cs | 12 +- .../RuntimeAccessStubJavaMethod.cs | 8 +- .../RuntimeAssemblyClassLoader.cs | 4 +- .../RuntimeByteCodeJavaType.FinishContext.cs | 80 ++- ...peImpl.DelegateConstructorMethodWrapper.cs | 2 +- .../RuntimeByteCodeJavaType.JavaTypeImpl.cs | 131 ++-- src/IKVM.Runtime/RuntimeByteCodeJavaType.cs | 6 +- .../RuntimeByteCodePropertyJavaField.cs | 11 +- src/IKVM.Runtime/RuntimeConstantJavaField.cs | 14 +- .../RuntimeConstructorAccessStubJavaMethod.cs | 8 +- .../RuntimeDefaultInterfaceJavaMethod.cs | 8 +- src/IKVM.Runtime/RuntimeGhostJavaMethod.cs | 14 +- src/IKVM.Runtime/RuntimeJavaMethod.cs | 64 +- src/IKVM.Runtime/RuntimeJavaType.cs | 13 +- ...ntimeManagedByteCodeAccessStubJavaField.cs | 19 +- ...eJavaType.DelegateConstructorJavaMethod.cs | 12 +- ...agedByteCodeJavaType.RemappedJavaMethod.cs | 7 +- .../RuntimeManagedByteCodeJavaType.cs | 56 +- ...RuntimeManagedByteCodePropertyJavaField.cs | 12 +- ...ntimeManagedJavaType.EnumValueJavaField.cs | 13 +- ...ntimeManagedJavaType.FinalizeJavaMethod.cs | 7 +- ...JavaType.ValueTypeDefaultCtorJavaMethod.cs | 9 +- src/IKVM.Runtime/RuntimeMirandaJavaMethod.cs | 8 +- src/IKVM.Runtime/RuntimePrimitiveJavaType.cs | 12 +- .../RuntimePrivateInterfaceJavaMethod.cs | 8 +- .../RuntimeSimpleCallJavaMethod.cs | 6 - src/IKVM.Runtime/RuntimeSimpleJavaField.cs | 16 +- src/IKVM.Runtime/RuntimeTypicalJavaMethod.cs | 13 +- .../RuntimeVolatileLongDoubleJavaField.cs | 9 +- src/IKVM.Runtime/Serialization.cs | 8 +- .../ManagedTypeResolver.cs | 61 +- src/IKVM.Tools.Importer/AssemblyResolver.cs | 44 +- src/IKVM.Tools.Importer/FakeTypes.cs | 47 +- src/IKVM.Tools.Importer/ImportClassLoader.cs | 626 +++++++++--------- src/IKVM.Tools.Importer/ImportContext.cs | 151 ++++- src/IKVM.Tools.Importer/ImportOptions.cs | 2 +- .../ImportRuntimeSymbolResolver.cs | 141 ++++ src/IKVM.Tools.Importer/ImportState.cs | 50 +- src/IKVM.Tools.Importer/ImportTarget.cs | 2 +- src/IKVM.Tools.Importer/ManagedResolver.cs | 75 --- src/IKVM.Tools.Importer/MapXml/Add.cs | 3 +- src/IKVM.Tools.Importer/MapXml/And.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Box.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Call.cs | 28 +- src/IKVM.Tools.Importer/MapXml/Callvirt.cs | 4 +- src/IKVM.Tools.Importer/MapXml/Castclass.cs | 2 +- .../MapXml/Castclass_impl.cs | 2 +- src/IKVM.Tools.Importer/MapXml/Ceq.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Conv_I.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Conv_I1.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Conv_I2.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Conv_I4.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Conv_I8.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Conv_U1.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Conv_U2.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Conv_U4.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Conv_U8.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Cpblk.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Div_Un.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Dup.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Endfinally.cs | 3 +- .../MapXml/ExceptionBlock.cs | 5 +- src/IKVM.Tools.Importer/MapXml/IsInst.cs | 2 +- src/IKVM.Tools.Importer/MapXml/LdArg_0.cs | 3 +- src/IKVM.Tools.Importer/MapXml/LdArg_1.cs | 3 +- src/IKVM.Tools.Importer/MapXml/LdArg_2.cs | 3 +- src/IKVM.Tools.Importer/MapXml/LdArg_3.cs | 3 +- src/IKVM.Tools.Importer/MapXml/LdLoc.cs | 2 +- src/IKVM.Tools.Importer/MapXml/Ldc_I4_0.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Ldc_I4_1.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Ldc_I4_M1.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Ldelema.cs | 2 +- src/IKVM.Tools.Importer/MapXml/Ldfld.cs | 2 +- src/IKVM.Tools.Importer/MapXml/Ldflda.cs | 2 +- src/IKVM.Tools.Importer/MapXml/Ldftn.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Ldind_i1.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Ldind_i2.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Ldind_i4.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Ldind_i8.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Ldind_r4.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Ldind_r8.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Ldind_ref.cs | 4 +- src/IKVM.Tools.Importer/MapXml/Ldlen.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Ldnull.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Ldobj.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Ldsfld.cs | 4 +- src/IKVM.Tools.Importer/MapXml/Ldstr.cs | 2 +- src/IKVM.Tools.Importer/MapXml/Ldtoken.cs | 30 +- src/IKVM.Tools.Importer/MapXml/Ldvirtftn.cs | 5 +- .../MapXml/MapXmlSerializer.cs | 3 +- src/IKVM.Tools.Importer/MapXml/MethodBase.cs | 2 +- src/IKVM.Tools.Importer/MapXml/Mul.cs | 3 +- src/IKVM.Tools.Importer/MapXml/NewObj.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Newarr.cs | 2 +- src/IKVM.Tools.Importer/MapXml/Not.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Or.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Pop.cs | 2 +- src/IKVM.Tools.Importer/MapXml/Redirect.cs | 10 +- src/IKVM.Tools.Importer/MapXml/Rem_Un.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Ret.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Simple.cs | 3 +- src/IKVM.Tools.Importer/MapXml/StLoc.cs | 7 +- src/IKVM.Tools.Importer/MapXml/Stfld.cs | 2 +- src/IKVM.Tools.Importer/MapXml/Stind_i1.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Stind_i2.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Stind_i4.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Stind_i8.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Stind_ref.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Stsfld.cs | 2 +- src/IKVM.Tools.Importer/MapXml/Sub.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Throw.cs | 3 +- .../MapXml/TypeInstruction.cs | 7 +- .../MapXml/TypeOrTypeWrapperInstruction.cs | 5 +- src/IKVM.Tools.Importer/MapXml/Unbox.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Volatile.cs | 3 +- src/IKVM.Tools.Importer/MapXml/Xor.cs | 3 +- src/IKVM.Tools.Importer/Proxy.cs | 23 +- .../RuntimeImportByteCodeJavaType.cs | 69 +- src/IKVM.Tools.Importer/StaticCompiler.cs | 77 ++- 148 files changed, 2006 insertions(+), 1253 deletions(-) create mode 100644 src/IKVM.CoreLib/Symbols/Emit/PEFileKinds.cs create mode 100644 src/IKVM.CoreLib/Symbols/ImageFileMachine.cs create mode 100644 src/IKVM.CoreLib/Symbols/ManifestResourceInfo.cs create mode 100644 src/IKVM.CoreLib/Symbols/TypeSymbolExtensions.cs create mode 100644 src/IKVM.Tools.Importer/ImportRuntimeSymbolResolver.cs delete mode 100644 src/IKVM.Tools.Importer/ManagedResolver.cs diff --git a/src/IKVM.CoreLib/Diagnostics/DiagnosticEvent.cs b/src/IKVM.CoreLib/Diagnostics/DiagnosticEvent.cs index 4b2ebd0f1..c90a66a89 100644 --- a/src/IKVM.CoreLib/Diagnostics/DiagnosticEvent.cs +++ b/src/IKVM.CoreLib/Diagnostics/DiagnosticEvent.cs @@ -26,6 +26,11 @@ readonly partial struct DiagnosticEvent(Diagnostic Diagnostic, object?[] Args, E /// public readonly DiagnosticLocation Location = Location; + internal static DiagnosticEvent RuntimeMismatch(object location, string fullName1, string fullName2) + { + throw new NotImplementedException(); + } + /// /// Formats the diagnostic event message. /// diff --git a/src/IKVM.CoreLib/Symbols/Emit/IAssemblySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IAssemblySymbolBuilder.cs index d99608a52..5df264c93 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/IAssemblySymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/IAssemblySymbolBuilder.cs @@ -1,4 +1,6 @@ -namespace IKVM.CoreLib.Symbols.Emit +using System.Reflection; + +namespace IKVM.CoreLib.Symbols.Emit { interface IAssemblySymbolBuilder : ISymbolBuilder, IAssemblySymbol @@ -41,6 +43,57 @@ interface IAssemblySymbolBuilder : ISymbolBuilder, IAssemblySym /// void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute); + /// + /// Sets a Win32 icon on the generated assembly. + /// + /// + void DefineIconResource(byte[] bytes); + + /// + /// Sets a manifest resource on the generated assembly. + /// + /// + void DefineManifestResource(byte[] bytes); + + /// + /// Sets a Win32 version info resource on the generated assembly. + /// + void DefineVersionInfoResource(); + + /// + /// Sets the entry point for this assembly, assuming that a console application is being built. + /// + /// + void SetEntryPoint(IMethodSymbolBuilder mainMethodProxy); + + /// + /// Sets the entry point for this assembly and defines the type of the portable executable (PE file) being built. + /// + /// + /// + void SetEntryPoint(IMethodSymbolBuilder mainMethodProxy, PEFileKinds target); + + /// + /// Adds a forwarded type to this assembly. + /// + /// + void AddTypeForwarder(ITypeSymbol type); + + /// + /// Adds an external resource file to the assembly. + /// + /// + /// + void AddResourceFile(string name, string fileName); + + /// + /// Saves this assembly to disk. + /// + /// + /// + /// + void Save(string assemblyFileName, PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine); + } } diff --git a/src/IKVM.CoreLib/Symbols/Emit/IModuleSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IModuleSymbolBuilder.cs index 90c4603e1..79737a176 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/IModuleSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/IModuleSymbolBuilder.cs @@ -1,7 +1,10 @@ using System; using System.Diagnostics.SymbolStore; +using System.IO; using System.Reflection; using System.Reflection.Emit; +using System.Reflection.PortableExecutable; +using System.Resources; namespace IKVM.CoreLib.Symbols.Emit { @@ -9,6 +12,21 @@ namespace IKVM.CoreLib.Symbols.Emit interface IModuleSymbolBuilder : ISymbolBuilder, IModuleSymbol { + /// + /// Gets or sets the preferred address of the first byte of the image when it is loaded into memory. + /// + ulong ImageBase { get; set; } + + /// + /// Gets or sets the alignment factor (in bytes) that is used to align the raw data of sections in the image file. + /// + uint FileAlignment { get; set; } + + /// + /// Gets or sets the characteristics of a dynamic link library. + /// + DllCharacteristics DllCharacteristics { get; set; } + /// /// Defines a document for source. /// @@ -19,6 +37,67 @@ interface IModuleSymbolBuilder : ISymbolBuilder, IModuleSymbol /// ISymbolDocumentWriter? DefineDocument(string url, Guid language, Guid languageVendor, Guid documentType); + /// + /// Defines a binary large object (BLOB) that represents a manifest resource to be embedded in the dynamic assembly. + /// + /// + /// + /// + void DefineManifestResource(string name, Stream stream, ResourceAttributes attribute); + + /// + /// Defines the named managed embedded resource to be stored in this module. + /// + /// + /// + /// + IResourceWriter DefineResource(string name, string description); + + /// + /// Defines the named managed embedded resource with the given attributes that is to be stored in this module. + /// + /// + /// + /// + /// + IResourceWriter DefineResource(string name, string description, ResourceAttributes attribute); + + /// + /// Defines a global method with the specified name, attributes, calling convention, return type, and parameter types. + /// + /// + /// + /// + /// + /// + /// + IMethodSymbolBuilder DefineGlobalMethod(string name, MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, ITypeSymbol returnType, ITypeSymbol[] parameterTypes); + + /// + /// Defines a global method with the specified name, attributes, calling convention, return type, custom modifiers for the return type, parameter types, and custom modifiers for the parameter types. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + IMethodSymbolBuilder DefineGlobalMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol returnType, ITypeSymbol[] requiredReturnTypeCustomModifiers, ITypeSymbol[] optionalReturnTypeCustomModifiers, ITypeSymbol[] parameterTypes, ITypeSymbol[][] requiredParameterTypeCustomModifiers, ITypeSymbol[][] optionalParameterTypeCustomModifiers); + + /// + /// Defines a global method with the specified name, attributes, return type, and parameter types. + /// + /// + /// + /// + /// + /// + IMethodSymbolBuilder DefineGlobalMethod(string name, MethodAttributes attributes, ITypeSymbol returnType, ITypeSymbol[] parameterTypes); + /// /// Constructs a TypeBuilder for a private type with the specified name in this module. /// @@ -97,6 +176,23 @@ interface IModuleSymbolBuilder : ISymbolBuilder, IModuleSymbol /// void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute); + /// + /// Explicitely adds a reference to the specified assembly. + /// + /// + void AddReference(IAssemblySymbol assembly); + + /// + /// Finishes the module. + /// + void Complete(); + + /// + /// Saves this module assembly to disk. + /// + /// + /// + void Save(PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine); } } diff --git a/src/IKVM.CoreLib/Symbols/Emit/ITypeSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/ITypeSymbolBuilder.cs index e888e5028..1afc22d77 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/ITypeSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/ITypeSymbolBuilder.cs @@ -31,6 +31,14 @@ interface ITypeSymbolBuilder : ISymbolBuilder, IMemberSymbolBuilder /// void AddInterfaceImplementation(ITypeSymbol interfaceType); + /// + /// Adds a new constructor to the type, with the given attributes and signature and the standard calling convention. + /// + /// + /// + /// + IConstructorSymbolBuilder DefineConstructor(System.Reflection.MethodAttributes attributes, ITypeSymbol[]? parameterTypes); + /// /// Adds a new constructor to the type, with the given attributes and signature. /// diff --git a/src/IKVM.CoreLib/Symbols/Emit/PEFileKinds.cs b/src/IKVM.CoreLib/Symbols/Emit/PEFileKinds.cs new file mode 100644 index 000000000..475eacd6d --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Emit/PEFileKinds.cs @@ -0,0 +1,28 @@ +namespace IKVM.CoreLib.Symbols.Emit +{ + + /// + /// Specifies the type of the portable executable (PE) file. + /// + enum PEFileKinds + { + + /// + /// The portable executable (PE) file is a DLL. + /// + Dll = 1, + + /// + /// The application is a console (not a Windows-based) application. + /// + ConsoleApplication = 2, + + /// + /// The application is a Windows-based application. + /// + WindowApplication = 3, + + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IAssemblySymbol.cs b/src/IKVM.CoreLib/Symbols/IAssemblySymbol.cs index 3d3d39975..4e14036ab 100644 --- a/src/IKVM.CoreLib/Symbols/IAssemblySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IAssemblySymbol.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.IO; using System.Reflection; using IKVM.CoreLib.Symbols.Emit; @@ -15,14 +16,50 @@ interface IAssemblySymbol : ISymbol, ICustomAttributeProvider IEnumerable ExportedTypes { get; } + /// + /// Gets the display name of the assembly. + /// string? FullName { get; } + /// + /// Gets a string representing the version of the common language runtime (CLR) saved in the file containing the manifest. + /// string ImageRuntimeVersion { get; } + /// + /// Gets the full path or UNC location of the loaded file that contains the manifest. + /// + string Location { get; } + + /// + /// Gets the module that contains the manifest for the current assembly. + /// IModuleSymbol ManifestModule { get; } IEnumerable Modules { get; } + /// + /// Loads the specified manifest resource from this assembly. + /// + /// + /// + ManifestResourceInfo? GetManifestResourceInfo(string resourceName); + + /// + /// Loads the specified manifest resource from this assembly. + /// + /// + /// + Stream? GetManifestResourceStream(string name); + + /// + /// Loads the specified manifest resource, scoped by the namespace of the specified type, from this assembly. + /// + /// + /// + /// + Stream? GetManifestResourceStream(ITypeSymbol type, string name); + ITypeSymbol[] GetExportedTypes(); IModuleSymbol? GetModule(string name); diff --git a/src/IKVM.CoreLib/Symbols/ISymbolContext.cs b/src/IKVM.CoreLib/Symbols/ISymbolContext.cs index adef5b72e..47a832f04 100644 --- a/src/IKVM.CoreLib/Symbols/ISymbolContext.cs +++ b/src/IKVM.CoreLib/Symbols/ISymbolContext.cs @@ -13,17 +13,15 @@ interface ISymbolContext /// Defines a dynamic assembly that has the specified name and access rights. /// /// - /// /// - IAssemblySymbolBuilder DefineAssembly(AssemblyName name, AssemblyBuilderAccess access); + IAssemblySymbolBuilder DefineAssembly(AssemblyName name); /// /// Defines a dynamic assembly that has the specified name and access rights. /// /// - /// /// - IAssemblySymbolBuilder DefineAssembly(AssemblyName name, AssemblyBuilderAccess access, ICustomAttributeBuilder[]? assemblyAttributes); + IAssemblySymbolBuilder DefineAssembly(AssemblyName name, ICustomAttributeBuilder[]? assemblyAttributes); /// /// Initializes an instance of the interface given the constructor for the custom attribute and the arguments to the constructor. diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionAssemblySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionAssemblySymbolBuilder.cs index d8e4da24a..bafa374cf 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionAssemblySymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionAssemblySymbolBuilder.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using IKVM.CoreLib.Symbols.Emit; @@ -77,13 +78,61 @@ public IModuleSymbolBuilder DefineModule(string name, string fileName, bool emit /// public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) { - _builder.SetCustomAttribute(con.Unpack(), binaryAttribute); + UnderlyingAssemblyBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); } /// public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) { - _builder.SetCustomAttribute(((IkvmReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); + UnderlyingAssemblyBuilder.SetCustomAttribute(((IkvmReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); + } + + /// + public void DefineIconResource(byte[] bytes) + { + UnderlyingAssemblyBuilder.__DefineIconResource(bytes); + } + + /// + public void DefineManifestResource(byte[] bytes) + { + UnderlyingAssemblyBuilder.__DefineManifestResource(bytes); + } + + /// + public void DefineVersionInfoResource() + { + UnderlyingAssemblyBuilder.DefineVersionInfoResource(); + } + + /// + public void SetEntryPoint(IMethodSymbolBuilder mainMethodProxy) + { + UnderlyingAssemblyBuilder.SetEntryPoint(mainMethodProxy.Unpack()); + } + + /// + public void SetEntryPoint(IMethodSymbolBuilder mainMethodProxy, IKVM.CoreLib.Symbols.Emit.PEFileKinds target) + { + UnderlyingAssemblyBuilder.SetEntryPoint(mainMethodProxy.Unpack(), (IKVM.Reflection.Emit.PEFileKinds)target); + } + + /// + public void AddTypeForwarder(ITypeSymbol type) + { + UnderlyingAssemblyBuilder.__AddTypeForwarder(type.Unpack()); + } + + /// + public void AddResourceFile(string name, string value) + { + UnderlyingAssemblyBuilder.AddResourceFile(name, value); + } + + /// + public void Save(string assemblyFileName, System.Reflection.PortableExecutableKinds portableExecutableKind, IKVM.CoreLib.Symbols.ImageFileMachine imageFileMachine) + { + UnderlyingAssemblyBuilder.Save(assemblyFileName, (PortableExecutableKinds)portableExecutableKind, (IKVM.Reflection.ImageFileMachine)imageFileMachine); } #endregion @@ -114,6 +163,8 @@ public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) /// public override bool IsComplete => _builder == null; + public string Location => throw new NotImplementedException(); + /// public ITypeSymbol[] GetExportedTypes() { @@ -204,6 +255,24 @@ public bool IsDefined(ITypeSymbol attributeType, bool inherit = false) return UnderlyingAssembly.IsDefined(attributeType.Unpack(), inherit); } + /// + public ManifestResourceInfo? GetManifestResourceInfo(string resourceName) + { + return ResolveManifestResourceInfo(UnderlyingAssembly.GetManifestResourceInfo(resourceName)); + } + + /// + public Stream? GetManifestResourceStream(string name) + { + return UnderlyingAssembly.GetManifestResourceStream(name); + } + + /// + public Stream? GetManifestResourceStream(ITypeSymbol type, string name) + { + return UnderlyingAssembly.GetManifestResourceStream(type.Unpack(), name); + } + #endregion } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionModuleSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionModuleSymbolBuilder.cs index b5e84e7f5..1ac802ff4 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionModuleSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionModuleSymbolBuilder.cs @@ -1,6 +1,8 @@ using System; using System.Diagnostics.SymbolStore; +using System.IO; using System.Linq; +using System.Resources; using IKVM.CoreLib.Symbols.Emit; using IKVM.Reflection; @@ -193,6 +195,42 @@ public IIkvmReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypePa return UnderlyingModuleBuilder.DefineDocument(url, language, languageVendor, documentType); } + /// + public void DefineManifestResource(string name, Stream stream, System.Reflection.ResourceAttributes attribute) + { + UnderlyingModuleBuilder.DefineManifestResource(name, stream, (ResourceAttributes)attribute); + } + + /// + public IResourceWriter DefineResource(string name, string description) + { + return UnderlyingModuleBuilder.DefineResource(name, description); + } + + /// + public IResourceWriter DefineResource(string name, string description, System.Reflection.ResourceAttributes attribute) + { + return UnderlyingModuleBuilder.DefineResource(name, description, (ResourceAttributes)attribute); + } + + /// + public IMethodSymbolBuilder DefineGlobalMethod(string name, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, ITypeSymbol returnType, ITypeSymbol[] parameterTypes) + { + return ResolveMethodSymbol(UnderlyingModuleBuilder.DefineGlobalMethod(name, (MethodAttributes)attributes, (CallingConventions)callingConvention, returnType.Unpack(), parameterTypes.Unpack())); + } + + /// + public IMethodSymbolBuilder DefineGlobalMethod(string name, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, ITypeSymbol returnType, ITypeSymbol[] requiredReturnTypeCustomModifiers, ITypeSymbol[] optionalReturnTypeCustomModifiers, ITypeSymbol[] parameterTypes, ITypeSymbol[][] requiredParameterTypeCustomModifiers, ITypeSymbol[][] optionalParameterTypeCustomModifiers) + { + return ResolveMethodSymbol(UnderlyingModuleBuilder.DefineGlobalMethod(name, (MethodAttributes)attributes, (CallingConventions)callingConvention, returnType.Unpack(), requiredReturnTypeCustomModifiers.Unpack(), optionalReturnTypeCustomModifiers.Unpack(), parameterTypes.Unpack(), requiredParameterTypeCustomModifiers.Unpack(), optionalParameterTypeCustomModifiers.Unpack())); + } + + /// + public IMethodSymbolBuilder DefineGlobalMethod(string name, System.Reflection.MethodAttributes attributes, ITypeSymbol returnType, ITypeSymbol[] parameterTypes) + { + return ResolveMethodSymbol(UnderlyingModuleBuilder.DefineGlobalMethod(name, (MethodAttributes)attributes, returnType.Unpack(), parameterTypes.Unpack())); + } + /// public ITypeSymbolBuilder DefineType(string name) { @@ -247,6 +285,26 @@ public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) UnderlyingModuleBuilder.SetCustomAttribute(((IkvmReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); } + /// + public void AddReference(IAssemblySymbol assembly) + { + var t = ((IIkvmReflectionAssemblySymbol)assembly).GetExportedTypes(); + if (t.Length > 0) + UnderlyingModuleBuilder.GetTypeToken(t[0].Unpack()); + } + + /// + public void Complete() + { + UnderlyingModuleBuilder.CreateGlobalFunctions(); + } + + /// + public void Save(System.Reflection.PortableExecutableKinds portableExecutableKind, IKVM.CoreLib.Symbols.ImageFileMachine imageFileMachine) + { + UnderlyingModuleBuilder.__Save((PortableExecutableKinds)portableExecutableKind, (IKVM.Reflection.ImageFileMachine)imageFileMachine); + } + #endregion #region IModuleSymbol @@ -272,6 +330,27 @@ public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) /// public override bool IsComplete => _module == null; + /// + public ulong ImageBase + { + get => UnderlyingModule.__ImageBase; + set => UnderlyingModuleBuilder.__ImageBase = value; + } + + /// + public uint FileAlignment + { + get => UnderlyingModule.__FileAlignment; + set => UnderlyingModuleBuilder.__FileAlignment = value; + } + + /// + public System.Reflection.PortableExecutable.DllCharacteristics DllCharacteristics + { + get => (System.Reflection.PortableExecutable.DllCharacteristics)UnderlyingModule.__DllCharacteristics; + set => UnderlyingModuleBuilder.__DllCharacteristics = (IKVM.Reflection.DllCharacteristics)value; + } + /// public IFieldSymbol? GetField(string name) { diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionTypeSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionTypeSymbolBuilder.cs index d4183cb18..f392d4502 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionTypeSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionTypeSymbolBuilder.cs @@ -197,6 +197,12 @@ public void AddInterfaceImplementation(ITypeSymbol interfaceType) UnderlyingTypeBuilder.AddInterfaceImplementation(interfaceType.Unpack()); } + /// + public IConstructorSymbolBuilder DefineConstructor(System.Reflection.MethodAttributes attributes, ITypeSymbol[]? parameterTypes) + { + return ResolveConstructorSymbol(UnderlyingTypeBuilder.DefineConstructor((MethodAttributes)attributes, CallingConventions.Standard, parameterTypes?.Unpack())); + } + /// public IConstructorSymbolBuilder DefineConstructor(System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, ITypeSymbol[]? parameterTypes) { diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionAssemblySymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionAssemblySymbol.cs index 3d783ca7d..1f608eaf8 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionAssemblySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionAssemblySymbol.cs @@ -1,6 +1,4 @@ -using IKVM.CoreLib.Symbols.IkvmReflection.Emit; -using IKVM.Reflection; -using IKVM.Reflection.Emit; +using IKVM.Reflection; namespace IKVM.CoreLib.Symbols.IkvmReflection { diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs index 1b4b2ef00..61b83f629 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using IKVM.Reflection; @@ -44,114 +45,135 @@ public IIkvmReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) #region IAssemblySymbol /// - public IEnumerable DefinedTypes => ResolveTypeSymbols(_assembly.DefinedTypes); + public IEnumerable DefinedTypes => ResolveTypeSymbols(UnderlyingAssembly.DefinedTypes); /// - public IMethodSymbol? EntryPoint => ResolveMethodSymbol(_assembly.EntryPoint); + public IMethodSymbol? EntryPoint => ResolveMethodSymbol(UnderlyingAssembly.EntryPoint); /// - public IEnumerable ExportedTypes => ResolveTypeSymbols(_assembly.ExportedTypes); + public IEnumerable ExportedTypes => ResolveTypeSymbols(UnderlyingAssembly.ExportedTypes); /// - public string? FullName => _assembly.FullName; + public string? FullName => UnderlyingAssembly.FullName; /// - public string ImageRuntimeVersion => _assembly.ImageRuntimeVersion; + public string ImageRuntimeVersion => UnderlyingAssembly.ImageRuntimeVersion; /// - public IModuleSymbol ManifestModule => ResolveModuleSymbol(_assembly.ManifestModule); + public string Location => UnderlyingAssembly.Location; /// - public IEnumerable Modules => ResolveModuleSymbols(_assembly.Modules); + public IModuleSymbol ManifestModule => ResolveModuleSymbol(UnderlyingAssembly.ManifestModule); + + /// + public IEnumerable Modules => ResolveModuleSymbols(UnderlyingAssembly.Modules); /// public ITypeSymbol[] GetExportedTypes() { - return ResolveTypeSymbols(_assembly.GetExportedTypes()); + return ResolveTypeSymbols(UnderlyingAssembly.GetExportedTypes()); } /// public IModuleSymbol? GetModule(string name) { - return ResolveModuleSymbol(_assembly.GetModule(name)); + return ResolveModuleSymbol(UnderlyingAssembly.GetModule(name)); } /// public IModuleSymbol[] GetModules() { - return ResolveModuleSymbols(_assembly.GetModules()); + return ResolveModuleSymbols(UnderlyingAssembly.GetModules()); } /// public IModuleSymbol[] GetModules(bool getResourceModules) { - return ResolveModuleSymbols(_assembly.GetModules(getResourceModules)); + return ResolveModuleSymbols(UnderlyingAssembly.GetModules(getResourceModules)); } /// public System.Reflection.AssemblyName GetName() { - return _assembly.GetName().Pack(); + return UnderlyingAssembly.GetName().Pack(); } /// public System.Reflection.AssemblyName GetName(bool copiedName) { - return _assembly.GetName().Pack(); + return UnderlyingAssembly.GetName().Pack(); } /// public System.Reflection.AssemblyName[] GetReferencedAssemblies() { - return _assembly.GetReferencedAssemblies().Pack(); + return UnderlyingAssembly.GetReferencedAssemblies().Pack(); } /// public ITypeSymbol? GetType(string name, bool throwOnError) { - return ResolveTypeSymbol(_assembly.GetType(name, throwOnError)); + return ResolveTypeSymbol(UnderlyingAssembly.GetType(name, throwOnError)); } /// public ITypeSymbol? GetType(string name, bool throwOnError, bool ignoreCase) { - return ResolveTypeSymbol(_assembly.GetType(name, throwOnError, ignoreCase)); + return ResolveTypeSymbol(UnderlyingAssembly.GetType(name, throwOnError, ignoreCase)); } /// public ITypeSymbol? GetType(string name) { - return ResolveTypeSymbol(_assembly.GetType(name)); + return ResolveTypeSymbol(UnderlyingAssembly.GetType(name)); } /// public ITypeSymbol[] GetTypes() { - return ResolveTypeSymbols(_assembly.GetTypes()); + return ResolveTypeSymbols(UnderlyingAssembly.GetTypes()); } /// public CustomAttribute[] GetCustomAttributes(bool inherit = false) { - return ResolveCustomAttributes(_assembly.GetCustomAttributesData()); + return ResolveCustomAttributes(UnderlyingAssembly.GetCustomAttributesData()); } /// public CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) { - return ResolveCustomAttributes(_assembly.__GetCustomAttributes(attributeType.Unpack(), inherit)); + return ResolveCustomAttributes(UnderlyingAssembly.__GetCustomAttributes(attributeType.Unpack(), inherit)); } /// public CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) { - return ResolveCustomAttribute(_assembly.__GetCustomAttributes(attributeType.Unpack(), inherit).FirstOrDefault()); + return ResolveCustomAttribute(UnderlyingAssembly.__GetCustomAttributes(attributeType.Unpack(), inherit).FirstOrDefault()); } /// public bool IsDefined(ITypeSymbol attributeType, bool inherit = false) { - return _assembly.IsDefined(attributeType.Unpack(), inherit); + return UnderlyingAssembly.IsDefined(attributeType.Unpack(), inherit); + } + + /// + public ManifestResourceInfo? GetManifestResourceInfo(string resourceName) + { + return ResolveManifestResourceInfo(UnderlyingAssembly.GetManifestResourceInfo(resourceName)); + } + + /// + public Stream? GetManifestResourceStream(string name) + { + return UnderlyingAssembly.GetManifestResourceStream(name); + } + + /// + public Stream? GetManifestResourceStream(ITypeSymbol type, string name) + { + return UnderlyingAssembly.GetManifestResourceStream(type.Unpack(), name); } #endregion diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs index 7d1eb10de..9780e7997 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs @@ -525,6 +525,13 @@ public InterfaceMapping ResolveInterfaceMapping(IKVM.Reflection.InterfaceMapping ResolveMethodSymbols(mapping.TargetMethods), ResolveTypeSymbol(mapping.TargetType)); } + + /// + public ManifestResourceInfo? ResolveManifestResourceInfo(IKVM.Reflection.ManifestResourceInfo? info) + { + return info != null ? new ManifestResourceInfo((System.Reflection.ResourceLocation)info.ResourceLocation, info.FileName, ResolveAssemblySymbol(info.ReferencedAssembly)) : null; + } + } } \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolContext.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolContext.cs index d623f2d1c..c7a1c06ee 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolContext.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolContext.cs @@ -31,32 +31,22 @@ public IkvmReflectionSymbolContext(Universe universe) _universe = universe ?? throw new ArgumentNullException(nameof(universe)); } - /// - /// Defines a dynamic assembly that has the specified name and access rights. - /// - /// - /// - /// - public IAssemblySymbolBuilder DefineAssembly(System.Reflection.AssemblyName name, System.Reflection.Emit.AssemblyBuilderAccess access) + /// + public IAssemblySymbolBuilder DefineAssembly(System.Reflection.AssemblyName name) { if (name is null) throw new ArgumentNullException(nameof(name)); - return GetOrCreateAssemblySymbol(_universe.DefineDynamicAssembly(name.Unpack(), (AssemblyBuilderAccess)access)); + return GetOrCreateAssemblySymbol(_universe.DefineDynamicAssembly(name.Unpack(), AssemblyBuilderAccess.Save)); } - /// - /// Defines a dynamic assembly that has the specified name and access rights. - /// - /// - /// - /// - public IAssemblySymbolBuilder DefineAssembly(System.Reflection.AssemblyName name, System.Reflection.Emit.AssemblyBuilderAccess access, ICustomAttributeBuilder[]? assemblyAttributes) + /// + public IAssemblySymbolBuilder DefineAssembly(System.Reflection.AssemblyName name, ICustomAttributeBuilder[]? assemblyAttributes) { if (name is null) throw new ArgumentNullException(nameof(name)); - return GetOrCreateAssemblySymbol(_universe.DefineDynamicAssembly(name.Unpack(), (AssemblyBuilderAccess)access, assemblyAttributes?.Unpack())); + return GetOrCreateAssemblySymbol(_universe.DefineDynamicAssembly(name.Unpack(), AssemblyBuilderAccess.Save, assemblyAttributes?.Unpack())); } /// @@ -166,6 +156,23 @@ public IIkvmReflectionTypeSymbolBuilder GetOrCreateTypeSymbol(TypeBuilder type) return GetOrCreateModuleSymbol((ModuleBuilder)type.Module).GetOrCreateTypeSymbol(type); } + /// + /// Gets or creates a for the specified . + /// + /// + /// + public IIkvmReflectionMemberSymbol GetOrCreateMemberSymbol(MemberInfo member) + { + return member switch + { + MethodBase method => GetOrCreateMethodBaseSymbol(method), + FieldInfo field => GetOrCreateFieldSymbol(field), + PropertyInfo property => GetOrCreatePropertySymbol(property), + EventInfo @event => GetOrCreateEventSymbol(@event), + _ => throw new InvalidOperationException(), + }; + } + /// /// Gets or creates a for the specified . /// @@ -173,10 +180,11 @@ public IIkvmReflectionTypeSymbolBuilder GetOrCreateTypeSymbol(TypeBuilder type) /// public IIkvmReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method) { - if (method is ConstructorInfo ctor) - return GetOrCreateConstructorSymbol(ctor); - else - return GetOrCreateMethodSymbol((MethodInfo)method); + return method switch + { + ConstructorInfo ctor => GetOrCreateConstructorSymbol(ctor), + _ => GetOrCreateMethodSymbol((MethodInfo)method) + }; } /// @@ -186,10 +194,11 @@ public IIkvmReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase me /// public IIkvmReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) { - if (ctor is ConstructorBuilder builder) - return GetOrCreateConstructorSymbol(builder); - else - return GetOrCreateModuleSymbol(ctor.Module).GetOrCreateConstructorSymbol(ctor); + return ctor switch + { + ConstructorBuilder builder => GetOrCreateConstructorSymbol(builder), + _ => GetOrCreateModuleSymbol(ctor.Module).GetOrCreateConstructorSymbol(ctor) + }; } /// @@ -209,10 +218,11 @@ public IIkvmReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(Cons /// public IIkvmReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) { - if (method is MethodBuilder builder) - return GetOrCreateMethodSymbol(builder); - else - return GetOrCreateModuleSymbol(method.Module).GetOrCreateMethodSymbol(method); + return method switch + { + MethodBuilder builder => GetOrCreateMethodSymbol(builder), + _ => GetOrCreateModuleSymbol(method.Module).GetOrCreateMethodSymbol(method) + }; } /// @@ -252,10 +262,11 @@ public IIkvmReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(Paramete /// public IIkvmReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) { - if (field is FieldBuilder builder) - return GetOrCreateFieldSymbol(builder); - else - return GetOrCreateModuleSymbol(field.Module).GetOrCreateFieldSymbol(field); + return field switch + { + FieldBuilder builder => GetOrCreateFieldSymbol(builder), + _ => GetOrCreateModuleSymbol(field.Module).GetOrCreateFieldSymbol(field) + }; } /// @@ -275,10 +286,11 @@ public IIkvmReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder fie /// public IIkvmReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) { - if (property is PropertyBuilder builder) - return GetOrCreatePropertySymbol(builder); - else - return GetOrCreateModuleSymbol(property.Module).GetOrCreatePropertySymbol(property); + return property switch + { + PropertyBuilder builder => GetOrCreatePropertySymbol(builder), + _ => GetOrCreateModuleSymbol(property.Module).GetOrCreatePropertySymbol(property) + }; } /// @@ -298,10 +310,11 @@ public IIkvmReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBu /// public IIkvmReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) { - if (@event is EventBuilder builder) - return GetOrCreateEventSymbol(builder); - else - return GetOrCreateModuleSymbol(@event.Module).GetOrCreateEventSymbol(@event); + return @event switch + { + EventBuilder builder => GetOrCreateEventSymbol(builder), + _ => GetOrCreateModuleSymbol(@event.Module).GetOrCreateEventSymbol(@event) + }; } /// diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionUtil.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionUtil.cs index 5dbe9d794..7a7d30082 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionUtil.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionUtil.cs @@ -101,6 +101,19 @@ public static AssemblyName[] Unpack(this System.Reflection.AssemblyName[] n) return a; } + /// + /// Unpacks the symbol into their original assembly. + /// + /// + /// + public static Assembly Unpack(this IAssemblySymbol type) + { + if (type is IIkvmReflectionAssemblySymbol symbol) + return symbol.UnderlyingAssembly; + + throw new InvalidOperationException(); + } + /// /// Unpacks the symbol into their original type. /// diff --git a/src/IKVM.CoreLib/Symbols/ImageFileMachine.cs b/src/IKVM.CoreLib/Symbols/ImageFileMachine.cs new file mode 100644 index 000000000..ea0a8fa69 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/ImageFileMachine.cs @@ -0,0 +1,15 @@ +namespace IKVM.CoreLib.Symbols +{ + enum ImageFileMachine + { + + Unknown = 0, + I386 = 0x14c, + ARM = 0x01c0, + IA64 = 0x0200, + AMD64 = 0x8664, + ARM64 = 0xAA64, + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/ManifestResourceInfo.cs b/src/IKVM.CoreLib/Symbols/ManifestResourceInfo.cs new file mode 100644 index 000000000..df44e1eea --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/ManifestResourceInfo.cs @@ -0,0 +1,29 @@ +using System.Reflection; + +namespace IKVM.CoreLib.Symbols +{ + + /// + /// Provides access to manifest resources, which are XML files that describe application dependencies. + /// + readonly struct ManifestResourceInfo(ResourceLocation ResourceLocation, string? FileName, IAssemblySymbol? ReferencedAssembly) + { + + /// + /// Gets the manifest resource's location. + /// + public readonly ResourceLocation ResourceLocation = ResourceLocation; + + /// + /// Gets the name of the file that contains the manifest resource, if it is not the same as the manifest file. + /// + public readonly string? FileName = FileName; + + /// + /// Gets the containing assembly for the manifest resource. + /// + public readonly IAssemblySymbol? ReferencedAssembly = ReferencedAssembly; + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs index 2d3e9e071..941d04e53 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; @@ -73,6 +74,64 @@ public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) _builder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); } + public void SetEntryPoint(IMethodSymbolBuilder mainMethodProxy) + { + throw new NotImplementedException(); + } + + public void SetEntryPoint(IMethodSymbolBuilder mainMethodProxy, Symbols.Emit.PEFileKinds target) + { + throw new NotImplementedException(); + } + + /// + public void DefineIconResource(byte[] bytes) + { + throw new NotSupportedException(); + } + + /// + public void DefineManifestResource(byte[] bytes) + { + throw new NotSupportedException(); + } + + /// + public void DefineVersionInfoResource() + { +#if NETFRAMEWORK + UnderlyingAssemblyBuilder.DefineVersionInfoResource(); +#else + throw new NotSupportedException(); +#endif + } + + /// + public void AddTypeForwarder(ITypeSymbol type) + { + throw new NotSupportedException(); + } + + /// + public void AddResourceFile(string name, string fileName) + { +#if NETFRAMEWORK + UnderlyingAssemblyBuilder.AddResourceFile(name, fileName); +#else + throw new NotSupportedException(); +#endif + } + + /// + public void Save(string assemblyFileName, PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine) + { +#if NETFRAMEWORK + UnderlyingAssemblyBuilder.Save(assemblyFileName, portableExecutableKind, (System.Reflection.ImageFileMachine)imageFileMachine); +#else + throw new NotSupportedException(); +#endif + } + #endregion #region IAssemblySymbol @@ -101,6 +160,8 @@ public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) /// public override bool IsComplete => _builder == null; + public string Location => throw new NotImplementedException(); + /// public ITypeSymbol[] GetExportedTypes() { @@ -192,6 +253,24 @@ public bool IsDefined(ITypeSymbol attributeType, bool inherit = false) return UnderlyingAssembly.IsDefined(attributeType.Unpack(), inherit); } + /// + public ManifestResourceInfo? GetManifestResourceInfo(string resourceName) + { + return ResolveManifestResourceInfo(UnderlyingAssembly.GetManifestResourceInfo(resourceName)); + } + + /// + public Stream? GetManifestResourceStream(string name) + { + return UnderlyingAssembly.GetManifestResourceStream(name); + } + + /// + public Stream? GetManifestResourceStream(ITypeSymbol type, string name) + { + return UnderlyingAssembly.GetManifestResourceStream(type.Unpack(), name); + } + #endregion /// @@ -205,7 +284,6 @@ public IReflectionModuleSymbolBuilder GetOrCreateModuleSymbol(ModuleBuilder modu { return (IReflectionModuleSymbolBuilder)_metadata.GetOrCreateModuleSymbol(module); } - } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionModuleSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionModuleSymbolBuilder.cs index e5e338755..0c6e91d2f 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionModuleSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionModuleSymbolBuilder.cs @@ -1,8 +1,11 @@ using System; using System.Diagnostics.SymbolStore; +using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; +using System.Reflection.PortableExecutable; +using System.Resources; using IKVM.CoreLib.Symbols.Emit; @@ -53,6 +56,54 @@ public ReflectionModuleSymbolBuilder(ReflectionSymbolContext context, IReflectio #endif } + /// + public void DefineManifestResource(string name, Stream stream, ResourceAttributes attribute) + { +#if NETFRAMEWORK + UnderlyingModuleBuilder.DefineManifestResource(name, stream, attribute); +#else + throw new NotSupportedException(); +#endif + } + + /// + public IResourceWriter DefineResource(string name, string description) + { +#if NETFRAMEWORK + return UnderlyingModuleBuilder.DefineResource(name, description); +#else + throw new NotImplementedException(); +#endif + } + + /// + public IResourceWriter DefineResource(string name, string description, ResourceAttributes attribute) + { +#if NETFRAMEWORK + return UnderlyingModuleBuilder.DefineResource(name, description, attribute); +#else + throw new NotImplementedException(); +#endif + } + + /// + public IMethodSymbolBuilder DefineGlobalMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol returnType, ITypeSymbol[] parameterTypes) + { + return ResolveMethodSymbol(UnderlyingModuleBuilder.DefineGlobalMethod(name, attributes, callingConvention, returnType.Unpack(), parameterTypes.Unpack())); + } + + /// + public IMethodSymbolBuilder DefineGlobalMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol returnType, ITypeSymbol[] requiredReturnTypeCustomModifiers, ITypeSymbol[] optionalReturnTypeCustomModifiers, ITypeSymbol[] parameterTypes, ITypeSymbol[][] requiredParameterTypeCustomModifiers, ITypeSymbol[][] optionalParameterTypeCustomModifiers) + { + return ResolveMethodSymbol(UnderlyingModuleBuilder.DefineGlobalMethod(name, attributes, callingConvention, returnType.Unpack(), requiredReturnTypeCustomModifiers.Unpack(), optionalReturnTypeCustomModifiers.Unpack(), parameterTypes.Unpack(), requiredParameterTypeCustomModifiers.Unpack(), optionalParameterTypeCustomModifiers.Unpack())); + } + + /// + public IMethodSymbolBuilder DefineGlobalMethod(string name, MethodAttributes attributes, ITypeSymbol returnType, ITypeSymbol[] parameterTypes) + { + return ResolveMethodSymbol(UnderlyingModuleBuilder.DefineGlobalMethod(name, attributes, returnType.Unpack(), parameterTypes.Unpack())); + } + /// public ITypeSymbolBuilder DefineType(string name) { @@ -107,7 +158,7 @@ public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) UnderlyingModuleBuilder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); } -#endregion + #endregion #region IModuleSymbol @@ -129,6 +180,27 @@ public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) /// public string ScopeName => UnderlyingModule.ScopeName; + /// + public ulong ImageBase + { + get => throw new NotSupportedException(); + set => throw new NotSupportedException(); + } + + /// + public uint FileAlignment + { + get => throw new NotSupportedException(); + set => throw new NotSupportedException(); + } + + /// + public DllCharacteristics DllCharacteristics + { + get => throw new NotSupportedException(); + set => throw new NotSupportedException(); + } + /// public override bool IsComplete => _builder == null; @@ -301,6 +373,36 @@ public bool IsDefined(ITypeSymbol attributeType, bool inherit = false) return UnderlyingModule.IsDefined(attributeType.Unpack(), false); } + /// + public void AddReference(IAssemblySymbol assembly) + { +#if NETFRAMEWORK + var t = ((IReflectionAssemblySymbol)assembly).GetExportedTypes(); + if (t.Length > 0) + UnderlyingModuleBuilder.GetTypeToken(t[0].Unpack()); +#else + throw new NotSupportedException(); +#endif + } + + /// + public void AddTypeForwarder(ITypeSymbol type) + { + throw new NotImplementedException(); + } + + /// + public void Complete() + { + UnderlyingModuleBuilder.CreateGlobalFunctions(); + } + + /// + public void Save(PortableExecutableKinds pekind, ImageFileMachine imageFileMachine) + { + throw new NotSupportedException(); + } + #endregion /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs index 51a6db7e6..8c64b611e 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs @@ -63,6 +63,12 @@ public void AddInterfaceImplementation(ITypeSymbol interfaceType) UnderlyingTypeBuilder.AddInterfaceImplementation(interfaceType.Unpack()); } + /// + public IConstructorSymbolBuilder DefineConstructor(MethodAttributes attributes, ITypeSymbol[]? parameterTypes) + { + return (IConstructorSymbolBuilder)ResolveConstructorSymbol(UnderlyingTypeBuilder.DefineConstructor(attributes, CallingConventions.Standard, parameterTypes?.Unpack())); + } + /// public IConstructorSymbolBuilder DefineConstructor(MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol[]? parameterTypes) { diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs index 3280e999b..951f0c243 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; @@ -49,6 +50,9 @@ public ReflectionAssemblySymbol(ReflectionSymbolContext context, Assembly assemb /// public string ImageRuntimeVersion => _assembly.ImageRuntimeVersion; + /// + public string Location => _assembly.Location; + /// public IModuleSymbol ManifestModule => ResolveModuleSymbol(_assembly.ManifestModule); @@ -146,6 +150,24 @@ public bool IsDefined(ITypeSymbol attributeType, bool inherit = false) return _assembly.IsDefined(attributeType.Unpack(), inherit); } + /// + public ManifestResourceInfo? GetManifestResourceInfo(string resourceName) + { + return ResolveManifestResourceInfo(UnderlyingAssembly.GetManifestResourceInfo(resourceName)); + } + + /// + public Stream? GetManifestResourceStream(string name) + { + return UnderlyingAssembly.GetManifestResourceStream(name); + } + + /// + public Stream? GetManifestResourceStream(ITypeSymbol type, string name) + { + return UnderlyingAssembly.GetManifestResourceStream(type.Unpack(), name); + } + #endregion public IReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbol.cs index 9c719dd28..822ba085c 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbol.cs @@ -524,6 +524,12 @@ public InterfaceMapping ResolveInterfaceMapping(System.Reflection.InterfaceMappi ResolveTypeSymbol(mapping.TargetType)); } + /// + public ManifestResourceInfo? ResolveManifestResourceInfo(System.Reflection.ManifestResourceInfo? info) + { + return info != null ? new ManifestResourceInfo(info.ResourceLocation, info.FileName, ResolveAssemblySymbol(info.ReferencedAssembly)) : null; + } + } } \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs index cb05d82fa..369833fb7 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs @@ -34,12 +34,12 @@ public ReflectionSymbolContext() /// /// /// - public IAssemblySymbolBuilder DefineAssembly(AssemblyName name, AssemblyBuilderAccess access) + public IAssemblySymbolBuilder DefineAssembly(AssemblyName name) { if (name is null) throw new ArgumentNullException(nameof(name)); - return GetOrCreateAssemblySymbol(AssemblyBuilder.DefineDynamicAssembly(name, access)); + return GetOrCreateAssemblySymbol(AssemblyBuilder.DefineDynamicAssembly(name, AssemblyBuilderAccess.RunAndCollect)); } /// @@ -48,12 +48,12 @@ public IAssemblySymbolBuilder DefineAssembly(AssemblyName name, AssemblyBuilderA /// /// /// - public IAssemblySymbolBuilder DefineAssembly(AssemblyName name, AssemblyBuilderAccess access, ICustomAttributeBuilder[]? assemblyAttributes) + public IAssemblySymbolBuilder DefineAssembly(AssemblyName name, ICustomAttributeBuilder[]? assemblyAttributes) { if (name is null) throw new ArgumentNullException(nameof(name)); - return GetOrCreateAssemblySymbol(AssemblyBuilder.DefineDynamicAssembly(name, access, assemblyAttributes?.Unpack())); + return GetOrCreateAssemblySymbol(AssemblyBuilder.DefineDynamicAssembly(name, AssemblyBuilderAccess.RunAndCollect, assemblyAttributes?.Unpack())); } /// diff --git a/src/IKVM.CoreLib/Symbols/TypeSymbolExtensions.cs b/src/IKVM.CoreLib/Symbols/TypeSymbolExtensions.cs new file mode 100644 index 000000000..f6c3ac835 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/TypeSymbolExtensions.cs @@ -0,0 +1,43 @@ +using System; + +namespace IKVM.CoreLib.Symbols +{ + + static class TypeSymbolExtensions + { + + /// + /// Gets the associated for the specified type code. + /// + /// + /// + /// + public static Type GetSystemType(this ITypeSymbol symbol) + { + return symbol.TypeCode switch + { + TypeCode.Empty => typeof(void), + TypeCode.Object => typeof(object), + TypeCode.DBNull => typeof(DBNull), + TypeCode.Boolean => typeof(bool), + TypeCode.Char => typeof(Char), + TypeCode.SByte => typeof(SByte), + TypeCode.Byte => typeof(Byte), + TypeCode.Int16 => typeof(Int16), + TypeCode.UInt16 => typeof(UInt16), + TypeCode.Int32 => typeof(Int32), + TypeCode.UInt32 => typeof(UInt32), + TypeCode.Int64 => typeof(Int64), + TypeCode.UInt64 => typeof(UInt64), + TypeCode.Single => typeof(Single), + TypeCode.Double => typeof(Double), + TypeCode.Decimal => typeof(Decimal), + TypeCode.DateTime => typeof(DateTime), + TypeCode.String => typeof(string), + _ => throw new InvalidOperationException(), + }; + } + + } + +} diff --git a/src/IKVM.Reflection/Assembly.cs b/src/IKVM.Reflection/Assembly.cs index b77e7fa09..f83059e79 100644 --- a/src/IKVM.Reflection/Assembly.cs +++ b/src/IKVM.Reflection/Assembly.cs @@ -23,6 +23,8 @@ Jeroen Frijters */ using System; using System.Collections.Generic; +using System.IO; +using System.Text; namespace IKVM.Reflection { @@ -83,6 +85,34 @@ public event ModuleResolveEventHandler ModuleResolve public abstract ManifestResourceInfo GetManifestResourceInfo(string resourceName); public abstract System.IO.Stream GetManifestResourceStream(string name); + public virtual System.IO.Stream GetManifestResourceStream(Type type, string name) + { + var sb = new StringBuilder(); + if (type == null) + { + throw new ArgumentNullException(nameof(type)); + } + else + { + string? nameSpace = type.Namespace; + if (nameSpace != null) + { + sb.Append(nameSpace); + if (name != null) + { + sb.Append(System.Type.Delimiter); + } + } + } + + if (name != null) + { + sb.Append(name); + } + + return GetManifestResourceStream(sb.ToString()); + } + internal abstract Type FindType(TypeName name); internal abstract Type FindTypeIgnoreCase(TypeName lowerCaseName); diff --git a/src/IKVM.Runtime/Annotation.cs b/src/IKVM.Runtime/Annotation.cs index 9e4d156f4..69d77735f 100644 --- a/src/IKVM.Runtime/Annotation.cs +++ b/src/IKVM.Runtime/Annotation.cs @@ -28,13 +28,6 @@ Jeroen Frijters using IKVM.CoreLib.Symbols; using IKVM.CoreLib.Symbols.Emit; -#if IMPORTER || EXPORTER -using IKVM.Reflection.Emit; -#else -using System.Reflection; -using System.Reflection.Emit; -#endif - namespace IKVM.Runtime { @@ -100,7 +93,7 @@ internal static Annotation Load(RuntimeJavaType owner, object[] def) owner.Diagnostics.GenericCompilerWarning($"Unable to load annotation class {annotationClass}"); #if IMPORTER - return new RuntimeManagedByteCodeJavaType.CompiledAnnotation(owner.Context, owner.Context.Resolver.ResolveRuntimeType("IKVM.Attributes.DynamicAnnotationAttribute").AsReflection()); + return new RuntimeManagedByteCodeJavaType.CompiledAnnotation(owner.Context, owner.Context.Resolver.ResolveRuntimeType("IKVM.Attributes.DynamicAnnotationAttribute")); #else return null; #endif diff --git a/src/IKVM.Runtime/AttributeHelper.cs b/src/IKVM.Runtime/AttributeHelper.cs index 4979b0017..fd2195cb4 100644 --- a/src/IKVM.Runtime/AttributeHelper.cs +++ b/src/IKVM.Runtime/AttributeHelper.cs @@ -34,8 +34,6 @@ Jeroen Frijters using IKVM.ByteCode.Encoding; using IKVM.CoreLib.Symbols; using IKVM.CoreLib.Symbols.Emit; -using IKVM.CoreLib.Symbols.IkvmReflection; - #if IMPORTER || EXPORTER using IKVM.Reflection; @@ -267,6 +265,11 @@ internal void SetCustomAttribute(RuntimeClassLoader loader, IParameterSymbolBuil pb.SetCustomAttribute(CreateCustomAttribute(loader, attr)); } + internal void SetCustomAttribute(RuntimeClassLoader loader, IConstructorSymbolBuilder mb, IKVM.Tools.Importer.MapXml.Attribute attr) + { + mb.SetCustomAttribute(CreateCustomAttribute(loader, attr)); + } + internal void SetCustomAttribute(RuntimeClassLoader loader, IMethodSymbolBuilder mb, IKVM.Tools.Importer.MapXml.Attribute attr) { mb.SetCustomAttribute(CreateCustomAttribute(loader, attr)); @@ -298,7 +301,7 @@ void GetAttributeArgsAndTypes(RuntimeClassLoader loader, IKVM.Tools.Importer.Map if (tw.IsArray) { - var arr = Array.CreateInstance(Type.__GetSystemType(tw.ElementTypeWrapper.TypeAsArrayType.TypeCode), attr.Params[i].Elements.Length); + var arr = Array.CreateInstance(tw.ElementTypeWrapper.TypeAsArrayType.GetSystemType(), attr.Params[i].Elements.Length); for (int j = 0; j < arr.Length; j++) arr.SetValue(ParseValue(loader, tw.ElementTypeWrapper, attr.Params[i].Elements[j].Value), j); @@ -416,6 +419,11 @@ internal void SetEditorBrowsableNever(ITypeSymbolBuilder tb) tb.SetCustomAttribute(GetEditorBrowsableNever()); } + internal void SetEditorBrowsableNever(IConstructorSymbolBuilder mb) + { + mb.SetCustomAttribute(GetEditorBrowsableNever()); + } + internal void SetEditorBrowsableNever(IMethodSymbolBuilder mb) { mb.SetCustomAttribute(GetEditorBrowsableNever()); @@ -450,6 +458,16 @@ internal void SetDeprecatedAttribute(IPropertySymbolBuilder pb) pb.SetCustomAttribute(deprecatedAttribute); } + internal void SetThrowsAttribute(IConstructorSymbolBuilder mb, string[] exceptions) + { + if (exceptions != null && exceptions.Length != 0) + { + throwsAttribute ??= TypeOfThrowsAttribute.GetConstructor([context.Resolver.ResolveCoreType(typeof(string).FullName).MakeArrayType()]); + exceptions = UnicodeUtil.EscapeInvalidSurrogates(exceptions); + mb.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(throwsAttribute, [exceptions])); + } + } + internal void SetThrowsAttribute(IMethodSymbolBuilder mb, string[] exceptions) { if (exceptions != null && exceptions.Length != 0) @@ -500,6 +518,11 @@ internal void HideFromJava(ITypeSymbolBuilder typeBuilder) typeBuilder.SetCustomAttribute(HideFromJavaAttributeBuilder); } + internal void HideFromJava(IConstructorSymbolBuilder ctor) + { + ctor.SetCustomAttribute(HideFromJavaAttributeBuilder); + } + internal void HideFromJava(IMethodSymbolBuilder mb) { mb.SetCustomAttribute(HideFromJavaAttributeBuilder); @@ -726,6 +749,17 @@ internal void SetDebuggingModes(IAssemblySymbolBuilder assemblyBuilder, Debuggab #if IMPORTER + internal void SetModifiers(IConstructorSymbolBuilder cb, Modifiers modifiers, bool isInternal) + { + ICustomAttributeBuilder customAttributeBuilder; + if (isInternal) + customAttributeBuilder = context.Resolver.Symbols.CreateCustomAttribute(TypeOfModifiersAttribute.GetConstructor([TypeOfModifiers, context.Types.Boolean]), [modifiers, isInternal]); + else + customAttributeBuilder = context.Resolver.Symbols.CreateCustomAttribute(TypeOfModifiersAttribute.GetConstructor([TypeOfModifiers]), [modifiers]); + + cb.SetCustomAttribute(customAttributeBuilder); + } + internal void SetModifiers(IMethodSymbolBuilder mb, Modifiers modifiers, bool isInternal) { ICustomAttributeBuilder customAttributeBuilder; @@ -791,7 +825,7 @@ internal void SetSourceFile(ITypeSymbolBuilder typeBuilder, string filename) typeBuilder.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(sourceFileAttribute, [filename])); } - internal void SetSourceFile(IMethodSymbolBuilder moduleBuilder, string filename) + internal void SetSourceFile(IModuleSymbolBuilder moduleBuilder, string filename) { sourceFileAttribute ??= TypeOfSourceFileAttribute.GetConstructor([context.Types.String]); moduleBuilder.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(sourceFileAttribute, [filename])); diff --git a/src/IKVM.Runtime/CodeEmitter.cs b/src/IKVM.Runtime/CodeEmitter.cs index b32b34ba9..59f1fde78 100644 --- a/src/IKVM.Runtime/CodeEmitter.cs +++ b/src/IKVM.Runtime/CodeEmitter.cs @@ -72,11 +72,21 @@ public CodeEmitterFactory(RuntimeContext context) /// /// Creates a new instance. /// - /// + /// /// - public CodeEmitter Create(IMethodSymbolBuilder mb) + public CodeEmitter Create(IMethodSymbolBuilder method) { - return new CodeEmitter(context, mb.GetILGenerator(), mb.DeclaringType); + return new CodeEmitter(context, method.GetILGenerator(), method.DeclaringType); + } + + /// + /// Creates a new instance. + /// + /// + /// + public CodeEmitter Create(IConstructorSymbolBuilder ctor) + { + return new CodeEmitter(context, ctor.GetILGenerator(), ctor.DeclaringType); } #if IMPORTER == false diff --git a/src/IKVM.Runtime/IRuntimeSymbolResolver.cs b/src/IKVM.Runtime/IRuntimeSymbolResolver.cs index 9f5843661..6c48e74ad 100644 --- a/src/IKVM.Runtime/IRuntimeSymbolResolver.cs +++ b/src/IKVM.Runtime/IRuntimeSymbolResolver.cs @@ -3,13 +3,16 @@ using System; using IKVM.CoreLib.Symbols; +using IKVM.CoreLib.Symbols.Emit; #if IMPORTER || EXPORTER using IKVM.Reflection; +using IKVM.Reflection.Emit; using Type = IKVM.Reflection.Type; #else using System.Reflection; +using System.Reflection.Emit; #endif namespace IKVM.Runtime @@ -33,6 +36,13 @@ interface IRuntimeSymbolResolver : ISymbolResolver /// IAssemblySymbol? ResolveAssembly(Assembly? assembly); + /// + /// Gets the associated with the specified assembly. + /// + /// + /// + IAssemblySymbolBuilder? ResolveAssembly(AssemblyBuilder? assembly); + /// /// Gets the associated with the specified module. /// @@ -40,6 +50,13 @@ interface IRuntimeSymbolResolver : ISymbolResolver /// IModuleSymbol? ResolveModule(Module? module); + /// + /// Gets the associated with the specified module. + /// + /// + /// + IModuleSymbolBuilder? ResolveModule(ModuleBuilder? module); + /// /// Gets the associated with the specified type. /// @@ -47,6 +64,13 @@ interface IRuntimeSymbolResolver : ISymbolResolver /// ITypeSymbol? ResolveType(Type? type); + /// + /// Gets the associated with the specified member. + /// + /// + /// + IMemberSymbol? ResolveMember(MemberInfo? memberInfo); + /// /// Gets the associated with the specified method. /// diff --git a/src/IKVM.Runtime/ReflectUtil.cs b/src/IKVM.Runtime/ReflectUtil.cs index f684f71ef..86868c4bb 100644 --- a/src/IKVM.Runtime/ReflectUtil.cs +++ b/src/IKVM.Runtime/ReflectUtil.cs @@ -146,9 +146,9 @@ internal static bool IsConstructor(IMethodBaseSymbol method) return method.IsSpecialName && method.Name == ConstructorInfo.ConstructorName; } - internal static IMethodSymbolBuilder DefineConstructor(ITypeSymbolBuilder tb, System.Reflection.MethodAttributes attribs, ITypeSymbol[] parameterTypes) + internal static IConstructorSymbolBuilder DefineConstructor(ITypeSymbolBuilder tb, System.Reflection.MethodAttributes attribs, ITypeSymbol[] parameterTypes) { - return tb.DefineMethod(ConstructorInfo.ConstructorName, attribs | System.Reflection.MethodAttributes.SpecialName | System.Reflection.MethodAttributes.RTSpecialName, null, parameterTypes); + return tb.DefineConstructor(attribs | System.Reflection.MethodAttributes.SpecialName | System.Reflection.MethodAttributes.RTSpecialName, parameterTypes); } /// @@ -156,7 +156,7 @@ internal static IMethodSymbolBuilder DefineConstructor(ITypeSymbolBuilder tb, Sy /// /// /// - internal static bool CanOwnDynamicMethod(Type type) + internal static bool CanOwnDynamicMethod(ITypeSymbol type) { return type != null && !type.IsInterface && !type.HasElementType && !type.IsGenericTypeDefinition && !type.IsGenericParameter; } @@ -192,13 +192,9 @@ private static bool MatchTypes(ITypeSymbol[] t1, ITypeSymbol[] t2) return false; } - internal static bool IsVector(Type type) + internal static bool IsVector(ITypeSymbol type) { -#if NET return type.IsSZArray; -#else - return type.IsArray && type.Name.EndsWith("[]"); -#endif } #if IMPORTER diff --git a/src/IKVM.Runtime/RuntimeAccessStubJavaMethod.cs b/src/IKVM.Runtime/RuntimeAccessStubJavaMethod.cs index e5d2c4518..de3211c8c 100644 --- a/src/IKVM.Runtime/RuntimeAccessStubJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimeAccessStubJavaMethod.cs @@ -21,15 +21,11 @@ Jeroen Frijters jeroen@frijters.net */ +using System.Reflection.Emit; + using IKVM.Attributes; using IKVM.CoreLib.Symbols; -#if IMPORTER || EXPORTER -using IKVM.Reflection.Emit; -#else -using System.Reflection.Emit; -#endif - namespace IKVM.Runtime { diff --git a/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs b/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs index 86cdeeb73..e44241a4a 100644 --- a/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs +++ b/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs @@ -450,11 +450,11 @@ internal RuntimeAssemblyClassLoader(RuntimeContext context, IAssemblySymbol asse #if IMPORTER - internal static void PreloadExportedAssemblies(StaticCompiler compiler, Assembly assembly) + internal static void PreloadExportedAssemblies(StaticCompiler compiler, IAssemblySymbol assembly) { if (assembly.GetManifestResourceInfo("ikvm.exports") != null) { - using (Stream stream = assembly.GetManifestResourceStream("ikvm.exports")) + using (var stream = assembly.GetManifestResourceStream("ikvm.exports")) { var rdr = new BinaryReader(stream); var assemblyCount = rdr.ReadInt32(); diff --git a/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishContext.cs b/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishContext.cs index 8c18ded24..c884f801a 100644 --- a/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishContext.cs +++ b/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishContext.cs @@ -59,7 +59,7 @@ internal sealed class FinishContext List nestedTypeBuilders; IMethodSymbol callerIDMethod; List items; - Dictionary arfuMap; + Dictionary arfuMap; Dictionary invokespecialstubcache; Dictionary dynamicClassLiteral; #if IMPORTER @@ -289,7 +289,7 @@ internal ITypeSymbol FinishImpl() } } #if IMPORTER - TypeBuilder tbDefaultMethods = null; + ITypeSymbolBuilder tbDefaultMethods = null; #endif bool basehasclinit = wrapper.BaseTypeWrapper != null && wrapper.BaseTypeWrapper.HasStaticInitializer; int clinitIndex = -1; @@ -389,7 +389,7 @@ internal ITypeSymbol FinishImpl() #if IMPORTER // see if there exists a "managed JNI" class for this type - var nativeCodeType = context.Resolver.ResolveRuntimeType("IKVM.Java.Externs." + classFile.Name.Replace("$", "+")).AsReflection(); + var nativeCodeType = context.Resolver.ResolveRuntimeType("IKVM.Java.Externs." + classFile.Name.Replace("$", "+")); if (nativeCodeType != null) { if (!m.IsStatic) @@ -398,7 +398,7 @@ internal ITypeSymbol FinishImpl() if (methods[i].HasCallerID) nargs = ArrayUtil.Concat(nargs, context.JavaBase.TypeOfIkvmInternalCallerID); - foreach (var method in nativeCodeType.GetMethods(BindingFlags.Static | BindingFlags.Public)) + foreach (var method in nativeCodeType.GetMethods(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public)) { var param = method.GetParameters(); int paramLength = param.Length; @@ -762,7 +762,7 @@ internal ITypeSymbol FinishImpl() #if IMPORTER - static void AddConstantPoolAttributeIfNecessary(RuntimeContext context, ClassFile classFile, TypeBuilder typeBuilder) + static void AddConstantPoolAttributeIfNecessary(RuntimeContext context, ClassFile classFile, ITypeSymbolBuilder typeBuilder) { object[] constantPool = null; bool[] inUse = null; @@ -974,11 +974,10 @@ private bool EmitInterlockedCompareAndSet(RuntimeJavaMethod method, string field return false; } - FieldInfo fi = casField.GetField(); + var fi = casField.GetField(); if (fi == null) - { return false; - } + ilGenerator.EmitLdarg(0); ilGenerator.Emit(OpCodes.Ldflda, fi); ilGenerator.EmitLdarg(2); @@ -1059,14 +1058,14 @@ private void AddMethodParameterInfo(ClassFile.Method m, RuntimeJavaMethod mw, IM #if IMPORTER - private void AddImplementsAttribute() + void AddImplementsAttribute() { var interfaces = wrapper.Interfaces; if (wrapper.BaseTypeWrapper == context.JavaBase.TypeOfJavaLangObject) { // We special case classes extending java.lang.Object to optimize the metadata encoding // for anonymous classes that implement an interface. - Type[] actualInterfaces = typeBuilder.GetInterfaces(); + var actualInterfaces = typeBuilder.GetInterfaces(); if (actualInterfaces.Length == 0) { return; @@ -1089,14 +1088,13 @@ private void AddImplementsAttribute() context.AttributeHelper.SetImplementsAttribute(typeBuilder, interfaces); } - private TypeBuilder DefineNestedInteropType(string name) + ITypeSymbolBuilder DefineNestedInteropType(string name) { - ImportClassLoader ccl = wrapper.classLoader; + var ccl = wrapper.classLoader; while (!ccl.ReserveName(classFile.Name + "$" + name)) - { name += "_"; - } - TypeBuilder tb = typeBuilder.DefineNestedType(name, TypeAttributes.Class | TypeAttributes.NestedPublic | TypeAttributes.Sealed | TypeAttributes.Abstract); + + var tb = typeBuilder.DefineNestedType(name, TypeAttributes.Class | TypeAttributes.NestedPublic | TypeAttributes.Sealed | TypeAttributes.Abstract); RegisterNestedTypeBuilder(tb); context.AttributeHelper.HideFromJava(tb); return tb; @@ -1112,17 +1110,13 @@ void AddInterfaceMethodsInterop(RuntimeJavaMethod[] methods) } - private void CreateDefaultMethodInterop(ref TypeBuilder tbDefaultMethods, IMethodSymbolBuilder defaultMethod, RuntimeJavaMethod mw) + private void CreateDefaultMethodInterop(ref ITypeSymbolBuilder tbDefaultMethods, IMethodSymbolBuilder defaultMethod, RuntimeJavaMethod mw) { if (!ParametersAreAccessible(mw)) - { return; - } if (tbDefaultMethods == null) - { tbDefaultMethods = DefineNestedInteropType(NestedTypeName.DefaultMethods); - } var mb = mw.GetDefineMethodHelper().DefineMethod(wrapper.ClassLoader.GetTypeWrapperFactory(), tbDefaultMethods, mw.Name, MethodAttributes.Public | MethodAttributes.Static, wrapper.TypeAsSignatureType, true); var ilgen = context.CodeEmitterFactory.Create(mb); @@ -1303,7 +1297,7 @@ void GenerateAccessStub(RuntimeJavaField fw, bool type1) // we append the IKVM.Attributes.AccessStub type to the modopt array for use in the property accessor method signature // to make sure they never conflict with any user defined methhods - var modopt2 = ArrayUtil.Concat(modopt, context.Resolver.ResolveRuntimeType(typeof(IKVM.Attributes.AccessStub).FullName).AsReflection()); + var modopt2 = ArrayUtil.Concat(modopt, context.Resolver.ResolveRuntimeType(typeof(IKVM.Attributes.AccessStub).FullName)); var getter = typeBuilder.DefineMethod("get_" + fw.Name, attribs, CallingConventions.Standard, propType, null, modopt2, [], null, null); context.AttributeHelper.HideFromJava(getter); pb.SetGetMethod(getter); @@ -1400,7 +1394,7 @@ void GenerateAccessStub(int id, RuntimeJavaMethod mw, bool virt, bool type1) } var returnType = mw.ReturnType.TypeAsPublicSignatureType; - var modoptReturnType = ArrayUtil.Concat(wrapper.GetModOpt(mw.ReturnType, true), context.Resolver.ResolveRuntimeType(typeof(IKVM.Attributes.AccessStub).FullName).AsReflection()); + var modoptReturnType = ArrayUtil.Concat(wrapper.GetModOpt(mw.ReturnType, true), context.Resolver.ResolveRuntimeType(typeof(IKVM.Attributes.AccessStub).FullName)); string name; if (mw.Name == StringConstants.INIT) @@ -1594,7 +1588,7 @@ IMethodSymbolBuilder DefineInterfaceStubMethod(string name, RuntimeJavaMethod mw internal static class JniProxyBuilder { - readonly static ModuleBuilder mod; + readonly static IModuleSymbolBuilder mod; static int count; /// @@ -1602,8 +1596,8 @@ internal static class JniProxyBuilder /// static JniProxyBuilder() { - mod = DynamicClassLoader.CreateJniProxyModuleBuilder(); - var cab = new CustomAttributeBuilder(JVM.Context.Resolver.ResolveRuntimeType(typeof(JavaModuleAttribute).FullName).GetConstructor([]).AsReflection(), []); + mod = DynamicClassLoader.CreateJniProxyModuleBuilder(JVM.Context); + var cab = JVM.Context.Resolver.Symbols.CreateCustomAttribute(JVM.Context.Resolver.ResolveRuntimeType(typeof(JavaModuleAttribute).FullName).GetConstructor([]), []); mod.SetCustomAttribute(cab); } @@ -1611,36 +1605,34 @@ internal static void Generate(RuntimeByteCodeJavaType.FinishContext context, Cod { var tb = mod.DefineType("__" + System.Threading.Interlocked.Increment(ref count), TypeAttributes.Public | TypeAttributes.Class); int instance = m.IsStatic ? 0 : 1; - var argTypes = new ITypeSymbolvvvvvvvvvvvvvvvv[args.Length + instance + 1]; + var argTypes = new ITypeSymbol[args.Length + instance + 1]; if (instance != 0) - { - argTypes[0] = typeof(object); - } + argTypes[0] = context.Context.Types.Object; + for (int i = 0; i < args.Length; i++) { // NOTE we take a shortcut here by assuming that all "special" types (i.e. ghost or value types) // are public and so we can get away with replacing all other types with object. - argTypes[i + instance] = !args[i].IsUnloadable && (args[i].IsPrimitive || args[i].IsGhost || args[i].IsNonPrimitiveValueType) ? args[i].TypeAsSignatureType : typeof(object); + argTypes[i + instance] = !args[i].IsUnloadable && (args[i].IsPrimitive || args[i].IsGhost || args[i].IsNonPrimitiveValueType) ? args[i].TypeAsSignatureType : context.Context.Types.Object; } argTypes[argTypes.Length - 1] = context.context.JavaBase.TypeOfIkvmInternalCallerID.TypeAsSignatureType; - var retType = !mw.ReturnType.IsUnloadable && (mw.ReturnType.IsPrimitive || mw.ReturnType.IsGhost || mw.ReturnType.IsNonPrimitiveValueType) ? mw.ReturnType.TypeAsSignatureType : typeof(object); + var retType = !mw.ReturnType.IsUnloadable && (mw.ReturnType.IsPrimitive || mw.ReturnType.IsGhost || mw.ReturnType.IsNonPrimitiveValueType) ? mw.ReturnType.TypeAsSignatureType : context.Context.Types.Object; var mb = tb.DefineMethod("method", MethodAttributes.Public | MethodAttributes.Static, retType, argTypes); context.context.AttributeHelper.HideFromJava(mb); - CodeEmitter ilgen = context.context.CodeEmitterFactory.Create(mb); + var ilgen = context.context.CodeEmitterFactory.Create(mb); new JniBuilder(context.context).Generate(context, ilgen, wrapper, mw, tb, classFile, m, args, true); ilgen.DoEmit(); - tb.CreateType(); + tb.Complete(); + for (int i = 0; i < argTypes.Length - 1; i++) - { ilGenerator.EmitLdarg(i); - } + context.EmitCallerID(ilGenerator, m.IsLambdaFormCompiled); ilGenerator.Emit(OpCodes.Call, mb); if (!mw.ReturnType.IsUnloadable && !mw.ReturnType.IsPrimitive && !mw.ReturnType.IsGhost && !mw.ReturnType.IsNonPrimitiveValueType) - { ilGenerator.Emit(OpCodes.Castclass, mw.ReturnType.TypeAsSignatureType); - } + ilGenerator.Emit(OpCodes.Ret); } } @@ -1907,7 +1899,7 @@ void EmitCallerIDStub(RuntimeJavaMethod mw, string[] parameterNames) } ilgen.Emit(OpCodes.Ldc_I4_1); ilgen.Emit(OpCodes.Ldc_I4_0); - ilgen.Emit(OpCodes.Newobj, context.Resolver.ResolveCoreType(typeof(StackFrame).FullName).AsReflection().GetConstructor(new ITypeSymbol[] { context.Types.Int32, context.Types.Boolean })); + ilgen.Emit(OpCodes.Newobj, context.Resolver.ResolveCoreType(typeof(StackFrame).FullName).GetConstructor(new ITypeSymbol[] { context.Types.Int32, context.Types.Boolean })); var callerID = context.JavaBase.TypeOfIkvmInternalCallerID.GetMethodWrapper("create", "(Lcli.System.Diagnostics.StackFrame;)Likvm.internal.CallerID;", false); callerID.Link(); callerID.EmitCall(ilgen); @@ -2187,7 +2179,7 @@ void EmitConstantValueInitialization(RuntimeJavaField[] fields, CodeEmitter ilGe } } - internal IMethodSymbolBuilder DefineThreadLocalType() + internal IConstructorSymbolBuilder DefineThreadLocalType() { var threadLocal = context.ClassLoaderFactory.LoadClassCritical("ikvm.internal.IntrinsicThreadLocal"); int id = nestedTypeBuilders == null ? 0 : nestedTypeBuilders.Count; @@ -2219,26 +2211,28 @@ internal IMethodSymbolBuilder DefineThreadLocalType() return cb; } - internal IMethodSymbolBuilder GetAtomicReferenceFieldUpdater(RuntimeJavaField field) + internal IConstructorSymbolBuilder GetAtomicReferenceFieldUpdater(RuntimeJavaField field) { - arfuMap ??= new Dictionary(); + arfuMap ??= new Dictionary(); if (!arfuMap.TryGetValue(field, out var cb)) { var arfuTypeWrapper = context.ClassLoaderFactory.LoadClassCritical("ikvm.internal.IntrinsicAtomicReferenceFieldUpdater"); var tb = typeBuilder.DefineNestedType(NestedTypeName.AtomicReferenceFieldUpdater + arfuMap.Count, TypeAttributes.NestedPrivate | TypeAttributes.Sealed, arfuTypeWrapper.TypeAsBaseType); AtomicReferenceFieldUpdaterEmitter.EmitImpl(context, tb, field.GetField()); + cb = ReflectUtil.DefineConstructor(tb, MethodAttributes.Assembly, []); arfuMap.Add(field, cb); - CodeEmitter ctorilgen = context.CodeEmitterFactory.Create(cb); + var ctorilgen = context.CodeEmitterFactory.Create(cb); ctorilgen.Emit(OpCodes.Ldarg_0); - RuntimeJavaMethod basector = arfuTypeWrapper.GetMethodWrapper("", "()V", false); + var basector = arfuTypeWrapper.GetMethodWrapper("", "()V", false); basector.Link(); basector.EmitCall(ctorilgen); ctorilgen.Emit(OpCodes.Ret); ctorilgen.DoEmit(); RegisterNestedTypeBuilder(tb); } + return cb; } diff --git a/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.DelegateConstructorMethodWrapper.cs b/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.DelegateConstructorMethodWrapper.cs index ea6793966..d4eb4c259 100644 --- a/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.DelegateConstructorMethodWrapper.cs +++ b/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.DelegateConstructorMethodWrapper.cs @@ -39,7 +39,7 @@ private sealed partial class JavaTypeImpl sealed class DelegateConstructorMethodWrapper : RuntimeJavaMethod { - IMethodSymbolBuilder constructor; + IConstructorSymbolBuilder constructor; IMethodSymbol invoke; /// diff --git a/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.cs b/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.cs index af8b03ae0..0f287ff2c 100644 --- a/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.cs +++ b/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.cs @@ -282,7 +282,7 @@ internal void CreateStep2() bool cantNest = false; bool setModifiers = false; - TypeBuilder enclosing = null; + ITypeSymbolBuilder enclosing = null; string enclosingClassName = null; // we only compile inner classes as nested types in the static compiler, because it has a higher cost // and doesn't buy us anything in dynamic mode (and if fact, due to an FXBUG it would make handling @@ -623,17 +623,18 @@ void AddCliEnum() while (!ccl.ReserveName(classFile.Name + "$" + name)) name += "_"; - enumBuilder = typeBuilder.DefineNestedType(name, TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.NestedPublic | TypeAttributes.Serializable, wrapper.Context.Types.Enum.AsReflection()); + enumBuilder = typeBuilder.DefineNestedType(name, TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.NestedPublic | TypeAttributes.Serializable, wrapper.Context.Types.Enum); wrapper.Context.AttributeHelper.HideFromJava(enumBuilder); - enumBuilder.DefineField("value__", wrapper.Context.Types.Int32.AsReflection(), FieldAttributes.Public | FieldAttributes.SpecialName | FieldAttributes.RTSpecialName); + enumBuilder.DefineField("value__", wrapper.Context.Types.Int32, FieldAttributes.Public | FieldAttributes.SpecialName | FieldAttributes.RTSpecialName); for (int i = 0; i < classFile.Fields.Length; i++) { if (classFile.Fields[i].IsEnum) { - FieldBuilder fieldBuilder = enumBuilder.DefineField(classFile.Fields[i].Name, enumBuilder, FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal); + var fieldBuilder = enumBuilder.DefineField(classFile.Fields[i].Name, enumBuilder, FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal); fieldBuilder.SetConstant(i); } } + wrapper.SetEnumType(enumBuilder); } #endif @@ -648,7 +649,7 @@ void AddClinitTrigger() var hasfields = false; // If we have any public static fields, the cctor trigger must (and may) be public as well - foreach (ClassFile.Field fld in classFile.Fields) + foreach (var fld in classFile.Fields) { if (fld.IsPublic && fld.IsStatic) { @@ -685,29 +686,25 @@ private static bool HasStructLayoutAttributeAnnotation(ClassFile c) } #if IMPORTER - private ClassFile.InnerClass getOuterClass() + ClassFile.InnerClass getOuterClass() { - ClassFile.InnerClass[] innerClasses = classFile.InnerClasses; + var innerClasses = classFile.InnerClasses; if (innerClasses != null) - { for (int j = 0; j < innerClasses.Length; j++) - { if (innerClasses[j].innerClass.IsNotNil && classFile.GetConstantPoolClass(innerClasses[j].innerClass) == classFile.Name) - { return innerClasses[j]; - } - } - } + return new ClassFile.InnerClass(); } - private bool IsSideEffectFreeStaticInitializerOrNoop(ClassFile.Method m, out bool noop) + bool IsSideEffectFreeStaticInitializerOrNoop(ClassFile.Method m, out bool noop) { if (m.ExceptionTable.Length != 0) { noop = false; return false; } + noop = true; for (int i = 0; i < m.Instructions.Length; i++) { @@ -725,14 +722,16 @@ private bool IsSideEffectFreeStaticInitializerOrNoop(ClassFile.Method m, out boo // uses a goto to remove the (now unused) code i = target; } + if (bc == NormalizedByteCode.__getstatic || bc == NormalizedByteCode.__putstatic) { - ClassFile.ConstantPoolItemFieldref fld = classFile.SafeGetFieldref(m.Instructions[i].Arg1); + var fld = classFile.SafeGetFieldref(m.Instructions[i].Arg1); if (fld == null || fld.Class != classFile.Name) { noop = false; return false; } + // don't allow getstatic to load non-primitive fields, because that would // cause the verifier to try to load the type if (bc == NormalizedByteCode.__getstatic && "L[".IndexOf(fld.Signature[0]) != -1) @@ -740,12 +739,14 @@ private bool IsSideEffectFreeStaticInitializerOrNoop(ClassFile.Method m, out boo noop = false; return false; } - ClassFile.Field field = classFile.GetField(fld.Name, fld.Signature); + + var field = classFile.GetField(fld.Name, fld.Signature); if (field == null) { noop = false; return false; } + if (bc == NormalizedByteCode.__putstatic) { if (field.IsProperty && field.PropertySetter != null) @@ -791,11 +792,11 @@ private bool IsSideEffectFreeStaticInitializerOrNoop(ClassFile.Method m, out boo } #endif // IMPORTER - private RuntimeJavaMethod GetMethodWrapperDuringCtor(RuntimeJavaType lookup, IList methods, string name, string sig) + RuntimeJavaMethod GetMethodWrapperDuringCtor(RuntimeJavaType lookup, IList methods, string name, string sig) { if (lookup == wrapper) { - foreach (RuntimeJavaMethod mw in methods) + foreach (var mw in methods) { if (mw.Name == name && mw.Signature == sig) { @@ -817,17 +818,19 @@ private RuntimeJavaMethod GetMethodWrapperDuringCtor(RuntimeJavaType lookup, ILi } } - private void AddMirandaMethods(List methods, List baseMethods, RuntimeJavaType tw) + void AddMirandaMethods(List methods, List baseMethods, RuntimeJavaType tw) { - foreach (RuntimeJavaType iface in tw.Interfaces) + foreach (var iface in tw.Interfaces) { if (iface.IsPublic && this.wrapper.IsInterface) { // for interfaces, we only need miranda methods for non-public interfaces that we extend continue; } + AddMirandaMethods(methods, baseMethods, iface); - foreach (RuntimeJavaMethod ifmethod in iface.GetMethods()) + + foreach (var ifmethod in iface.GetMethods()) { // skip and non-virtual interface methods introduced in Java 8 if (ifmethod.IsVirtual) @@ -835,23 +838,26 @@ private void AddMirandaMethods(List methods, List methods, List outer.Length + 1 && inner[outer.Length] == '$' && inner.StartsWith(outer, StringComparison.Ordinal); } - private string AllocNestedTypeName(string outer, string inner) + string AllocNestedTypeName(string outer, string inner) { Debug.Assert(CheckInnerOuterNames(inner, outer)); nestedTypeNames ??= new ConcurrentDictionary(); @@ -892,20 +899,16 @@ private string AllocNestedTypeName(string outer, string inner) #endif - private int GetMethodIndex(RuntimeJavaMethod mw) + int GetMethodIndex(RuntimeJavaMethod mw) { for (int i = 0; i < methods.Length; i++) - { if (methods[i] == mw) - { return i; - } - } throw new InvalidOperationException(); } - private static void CheckLoaderConstraints(RuntimeJavaMethod mw, RuntimeJavaMethod baseMethod) + static void CheckLoaderConstraints(RuntimeJavaMethod mw, RuntimeJavaMethod baseMethod) { if (mw.ReturnType != baseMethod.ReturnType) { @@ -913,9 +916,7 @@ private static void CheckLoaderConstraints(RuntimeJavaMethod mw, RuntimeJavaMeth { // unloadable types can never cause a loader constraint violation if (mw.ReturnType.IsUnloadable && baseMethod.ReturnType.IsUnloadable) - { ((RuntimeUnloadableJavaType)mw.ReturnType).SetCustomModifier(((RuntimeUnloadableJavaType)baseMethod.ReturnType).CustomModifier); - } } else { @@ -926,8 +927,9 @@ private static void CheckLoaderConstraints(RuntimeJavaMethod mw, RuntimeJavaMeth #endif } } - RuntimeJavaType[] here = mw.GetParameters(); - RuntimeJavaType[] there = baseMethod.GetParameters(); + + var here = mw.GetParameters(); + var there = baseMethod.GetParameters(); for (int i = 0; i < here.Length; i++) { if (here[i] != there[i]) @@ -1034,7 +1036,7 @@ internal override IFieldSymbol LinkField(RuntimeJavaField fw) var methodAttribs = MethodAttributes.HideBySig; #if IMPORTER - bool setModifiers = fld.IsInternal || (fld.Modifiers & (Modifiers.Synthetic | Modifiers.Enum)) != 0; + var setModifiers = fld.IsInternal || (fld.Modifiers & (Modifiers.Synthetic | Modifiers.Enum)) != 0; #endif if (fld.IsPrivate) @@ -1090,19 +1092,13 @@ internal override IFieldSymbol LinkField(RuntimeJavaField fw) else if (fld.IsFinal) { if (wrapper.IsInterface || wrapper.classLoader.StrictFinalFieldSemantics) - { attribs |= FieldAttributes.InitOnly; - } else - { setModifiers = true; - } } #else if (fld.IsFinal && wrapper.IsInterface) - { attribs |= FieldAttributes.InitOnly; - } #endif field = DefineField(realFieldName, fw.FieldTypeWrapper, attribs, fld.IsVolatile); @@ -1270,7 +1266,7 @@ FinishedTypeImpl FinishCore() if (annotationBuilder != null) { - var cab = new CustomAttributeBuilder(wrapper.Context.Resolver.ResolveRuntimeType(typeof(AnnotationAttributeAttribute).FullName).AsReflection().GetConstructor(new Type[] { wrapper.Context.Types.String }), new object[] { UnicodeUtil.EscapeInvalidSurrogates(annotationBuilder.AttributeTypeName) }); + var cab = wrapper.Context.Resolver.Symbols.CreateCustomAttribute(wrapper.Context.Resolver.ResolveRuntimeType(typeof(AnnotationAttributeAttribute).FullName).GetConstructor([wrapper.Context.Types.String]), [UnicodeUtil.EscapeInvalidSurrogates(annotationBuilder.AttributeTypeName)]); typeBuilder.SetCustomAttribute(cab); } @@ -1293,11 +1289,11 @@ FinishedTypeImpl FinishCore() } if (enumBuilder != null) { - enumBuilder.CreateType(); + enumBuilder.Complete(); } if (privateInterfaceMethods != null) { - privateInterfaceMethods.CreateType(); + privateInterfaceMethods.Complete(); } #endif var finishedClinitMethod = (IMethodSymbol)clinitMethod; @@ -1383,7 +1379,7 @@ sealed class AnnotationBuilder : Annotation ITypeSymbolBuilder outer; ITypeSymbolBuilder annotationTypeBuilder; ITypeSymbolBuilder attributeTypeBuilder; - IMethodSymbolBuilder defineConstructor; + IConstructorSymbolBuilder defineConstructor; /// /// Initializes a new instance. @@ -1471,11 +1467,11 @@ internal void Link() int dotindex = o.classFile.Name.LastIndexOf('.') + 1; context.AttributeHelper.SetInnerClass(attributeTypeBuilder, o.classFile.Name.Substring(0, dotindex) + "$Proxy" + o.classFile.Name.Substring(dotindex), Modifiers.Final); attributeTypeBuilder.AddInterfaceImplementation(o.typeBuilder); - context.AttributeHelper.SetImplementsAttribute(attributeTypeBuilder, new RuntimeJavaType[] { o.wrapper }); + context.AttributeHelper.SetImplementsAttribute(attributeTypeBuilder, [o.wrapper]); if (o.classFile.Annotations != null) { - CustomAttributeBuilder attributeUsageAttribute = null; + ICustomAttributeBuilder attributeUsageAttribute = null; bool hasAttributeUsageAttribute = false; foreach (object[] def in o.classFile.Annotations) { @@ -1528,7 +1524,7 @@ internal void Link() } } - attributeUsageAttribute = new CustomAttributeBuilder(context.Resolver.ResolveCoreType(typeof(AttributeUsageAttribute).FullName).GetConstructor([context.Resolver.ResolveCoreType(typeof(AttributeTargets).FullName)]).AsReflection(), [targets]); + attributeUsageAttribute = context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveCoreType(typeof(AttributeUsageAttribute).FullName).GetConstructor([context.Resolver.ResolveCoreType(typeof(AttributeTargets).FullName)]), [targets]); } } } @@ -1551,7 +1547,7 @@ internal void Link() } } - defineConstructor = ReflectUtil.DefineConstructor(attributeTypeBuilder, MethodAttributes.Public, [context.Resolver.ResolveCoreType(typeof(object).FullName).MakeArrayType()]); + defineConstructor = ReflectUtil.DefineConstructor(attributeTypeBuilder, MethodAttributes.Public, [context.Types.Object.MakeArrayType()]); context.AttributeHelper.SetEditorBrowsableNever(defineConstructor); } @@ -1590,7 +1586,7 @@ static ITypeSymbol TypeWrapperToAnnotationParameterType(RuntimeJavaType tw) } if (isArray) - argType = RuntimeArrayJavaType.MakeArrayType(argType, 1); + argType = argType.MakeArrayType(); return argType; } @@ -1608,7 +1604,7 @@ internal string AttributeTypeName Link(); if (attributeTypeBuilder != null) - return attributeTypeBuilder.Symbol.FullName; + return attributeTypeBuilder.FullName; return null; } @@ -1694,7 +1690,7 @@ internal void Finish(JavaTypeImpl o) context.AttributeHelper.HideFromJava(reqArgConstructor); ilgen = context.CodeEmitterFactory.Create(reqArgConstructor); ilgen.Emit(OpCodes.Ldarg_0); - ilgen.Emit(OpCodes.Call, defaultConstructor.Symbol); + ilgen.Emit(OpCodes.Call, defaultConstructor); for (int i = 0, j = 0; i < o.methods.Length; i++) { @@ -1716,10 +1712,10 @@ internal void Finish(JavaTypeImpl o) // We don't have any required parameters, but we do have an optional "value" parameter, // so we create an additional constructor (the default constructor will be public in this case) // that accepts the value parameter. - Type argType = TypeWrapperToAnnotationParameterType(o.methods[valueArg].ReturnType); + var argType = TypeWrapperToAnnotationParameterType(o.methods[valueArg].ReturnType); if (argType != null) { - MethodBuilder cb = ReflectUtil.DefineConstructor(attributeTypeBuilder, MethodAttributes.Public, new Type[] { argType }); + var cb = ReflectUtil.DefineConstructor(attributeTypeBuilder, MethodAttributes.Public, [argType]); context.AttributeHelper.HideFromJava(cb); cb.DefineParameter(1, ParameterAttributes.None, "value"); ilgen = context.CodeEmitterFactory.Create(cb); @@ -1762,8 +1758,8 @@ internal void Finish(JavaTypeImpl o) // skip and non-virtual interface methods introduced in Java 8 if (o.methods[i].IsVirtual) { - MethodBuilder mb = o.methods[i].GetDefineMethodHelper().DefineMethod(o.wrapper, attributeTypeBuilder, o.methods[i].Name, MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.NewSlot); - attributeTypeBuilder.DefineMethodOverride(mb, (MethodInfo)o.methods[i].GetMethod()); + var mb = o.methods[i].GetDefineMethodHelper().DefineMethod(o.wrapper, attributeTypeBuilder, o.methods[i].Name, MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.NewSlot); + attributeTypeBuilder.DefineMethodOverride(mb, (IMethodSymbol)o.methods[i].GetMethod()); ilgen = context.CodeEmitterFactory.Create(mb); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Ldstr, o.methods[i].Name); @@ -1818,7 +1814,7 @@ internal void Finish(JavaTypeImpl o) && !(o.methods[i].Name == "value" && requiredArgCount == 0)) { // now add a .NET property for this annotation optional parameter - Type argType = TypeWrapperToAnnotationParameterType(o.methods[i].ReturnType); + var argType = TypeWrapperToAnnotationParameterType(o.methods[i].ReturnType); if (argType != null) { var pb = attributeTypeBuilder.DefineProperty(o.methods[i].Name, PropertyAttributes.None, argType, []); @@ -1835,22 +1831,21 @@ internal void Finish(JavaTypeImpl o) pb.SetGetMethod(getter); // TODO implement the getter method ilgen = context.CodeEmitterFactory.Create(getter); - ilgen.ThrowException(context.Resolver.ResolveCoreType(typeof(NotImplementedException).FullName).AsReflection()); + ilgen.ThrowException(context.Resolver.ResolveCoreType(typeof(NotImplementedException).FullName)); ilgen.DoEmit(); } } } } - attributeTypeBuilder.CreateType(); + attributeTypeBuilder.Complete(); } - private CustomAttributeBuilder MakeCustomAttributeBuilder(RuntimeClassLoader loader, object annotation) + ICustomAttributeBuilder MakeCustomAttributeBuilder(RuntimeClassLoader loader, object annotation) { Link(); - var ctor = defineConstructor != null - ? defineConstructor.__AsConstructorInfo() - : context.Resolver.ResolveRuntimeType("IKVM.Attributes.DynamicAnnotationAttribute").GetConstructor(new [] { context.Types.Object.MakeArrayType() }); - return new CustomAttributeBuilder(ctor, new object[] { AnnotationDefaultAttribute.Escape(QualifyClassNames(loader, annotation)) }); + + var ctor = defineConstructor != null ? defineConstructor : context.Resolver.ResolveRuntimeType("IKVM.Attributes.DynamicAnnotationAttribute").GetConstructor([context.Types.Object.MakeArrayType()]); + return context.Resolver.Symbols.CreateCustomAttribute(ctor, new object[] { AnnotationDefaultAttribute.Escape(QualifyClassNames(loader, annotation)) }); } internal override void Apply(RuntimeClassLoader loader, ITypeSymbolBuilder tb, object annotation) @@ -2287,7 +2282,7 @@ static IMethodSymbol GetBaseFinalizeMethod(RuntimeJavaType wrapper) } var type = wrapper.TypeAsBaseType; - var baseFinalize = type.GetMethod("__", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, []); + var baseFinalize = type.GetMethod("__", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, []); if (baseFinalize != null) return baseFinalize; @@ -2860,7 +2855,7 @@ IMethodSymbolBuilder GenerateMethod(int index, ClassFile.Method m, ref bool setM #if IMPORTER if (classFile.Methods[index].AnnotationDefault != null) { - var cab = new CustomAttributeBuilder(wrapper.Context.Resolver.ResolveRuntimeType("IKVM.Attributes.AnnotationDefaultAttribute").GetConstructor([wrapper.Context.Types.Object]), [AnnotationDefaultAttribute.Escape(classFile.Methods[index].AnnotationDefault)]); + var cab = wrapper.Context.Resolver.Symbols.CreateCustomAttribute(wrapper.Context.Resolver.ResolveRuntimeType("IKVM.Attributes.AnnotationDefaultAttribute").GetConstructor([wrapper.Context.Types.Object]), [AnnotationDefaultAttribute.Escape(classFile.Methods[index].AnnotationDefault)]); mb.SetCustomAttribute(cab); } #endif diff --git a/src/IKVM.Runtime/RuntimeByteCodeJavaType.cs b/src/IKVM.Runtime/RuntimeByteCodeJavaType.cs index f58a1df74..0375c0dfe 100644 --- a/src/IKVM.Runtime/RuntimeByteCodeJavaType.cs +++ b/src/IKVM.Runtime/RuntimeByteCodeJavaType.cs @@ -633,13 +633,13 @@ private static string GetParameterName(string type) protected abstract void EmitMapXmlMetadata(ITypeSymbolBuilder typeBuilder, ClassFile classFile, RuntimeJavaField[] fields, RuntimeJavaMethod[] methods); - protected abstract MethodBuilder DefineGhostMethod(ITypeSymbolBuilder typeBuilder, string name, System.Reflection.MethodAttributes attribs, RuntimeJavaMethod mw); + protected abstract IMethodSymbolBuilder DefineGhostMethod(ITypeSymbolBuilder typeBuilder, string name, System.Reflection.MethodAttributes attribs, RuntimeJavaMethod mw); protected abstract void FinishGhost(ITypeSymbolBuilder typeBuilder, RuntimeJavaMethod[] methods); protected abstract void FinishGhostStep2(); - protected abstract TypeBuilder DefineGhostType(string mangledTypeName, System.Reflection.TypeAttributes typeAttribs); + protected abstract ITypeSymbolBuilder DefineGhostType(string mangledTypeName, System.Reflection.TypeAttributes typeAttribs); #endif // IMPORTER @@ -657,7 +657,7 @@ private bool IsPInvokeMethod(ClassFile.Method m) { if (method.Attributes != null) foreach (IKVM.Tools.Importer.MapXml.Attribute attr in method.Attributes) - if (Context.StaticCompiler.GetType(classLoader, attr.Type) == Context.Resolver.ResolveCoreType(typeof(System.Runtime.InteropServices.DllImportAttribute).FullName).AsReflection()) + if (Context.StaticCompiler.GetType(classLoader, attr.Type) == Context.Resolver.ResolveCoreType(typeof(System.Runtime.InteropServices.DllImportAttribute).FullName)) return true; break; diff --git a/src/IKVM.Runtime/RuntimeByteCodePropertyJavaField.cs b/src/IKVM.Runtime/RuntimeByteCodePropertyJavaField.cs index 877505558..cf22e1ba9 100644 --- a/src/IKVM.Runtime/RuntimeByteCodePropertyJavaField.cs +++ b/src/IKVM.Runtime/RuntimeByteCodePropertyJavaField.cs @@ -21,17 +21,10 @@ Jeroen Frijters jeroen@frijters.net */ -using IKVM.CoreLib.Symbols.Emit; - -#if IMPORTER || EXPORTER -using IKVM.Reflection; -using IKVM.Reflection.Emit; - -using Type = IKVM.Reflection.Type; -#else using System.Reflection; using System.Reflection.Emit; -#endif + +using IKVM.CoreLib.Symbols.Emit; #if IMPORTER using IKVM.Tools.Importer; diff --git a/src/IKVM.Runtime/RuntimeConstantJavaField.cs b/src/IKVM.Runtime/RuntimeConstantJavaField.cs index 178e1a693..8403202e4 100644 --- a/src/IKVM.Runtime/RuntimeConstantJavaField.cs +++ b/src/IKVM.Runtime/RuntimeConstantJavaField.cs @@ -23,21 +23,11 @@ Jeroen Frijters */ using System; using System.Diagnostics; +using System.Reflection.Emit; using IKVM.Attributes; using IKVM.CoreLib.Symbols; - -#if IMPORTER || EXPORTER -using IKVM.Reflection; -using IKVM.Reflection.Emit; - -using Type = IKVM.Reflection.Type; -#else -using System.Reflection; -using System.Reflection.Emit; -#endif - namespace IKVM.Runtime { @@ -151,7 +141,7 @@ protected override void EmitSetImpl(CodeEmitter ilgen) internal override object GetValue(object obj) { var field = GetField(); - return FieldTypeWrapper.IsPrimitive || field == null ? GetConstantValue() : field.GetValue(null); + return FieldTypeWrapper.IsPrimitive || field == null ? GetConstantValue() : field.AsReflection().GetValue(null); } internal override void SetValue(object obj, object value) diff --git a/src/IKVM.Runtime/RuntimeConstructorAccessStubJavaMethod.cs b/src/IKVM.Runtime/RuntimeConstructorAccessStubJavaMethod.cs index 3eb7ca57d..0092b8e3d 100644 --- a/src/IKVM.Runtime/RuntimeConstructorAccessStubJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimeConstructorAccessStubJavaMethod.cs @@ -21,15 +21,11 @@ Jeroen Frijters jeroen@frijters.net */ +using System.Reflection.Emit; + using IKVM.Attributes; using IKVM.CoreLib.Symbols; -#if IMPORTER || EXPORTER -using IKVM.Reflection.Emit; -#else -using System.Reflection.Emit; -#endif - namespace IKVM.Runtime { diff --git a/src/IKVM.Runtime/RuntimeDefaultInterfaceJavaMethod.cs b/src/IKVM.Runtime/RuntimeDefaultInterfaceJavaMethod.cs index 3350b11ea..fb43872ca 100644 --- a/src/IKVM.Runtime/RuntimeDefaultInterfaceJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimeDefaultInterfaceJavaMethod.cs @@ -21,15 +21,11 @@ Jeroen Frijters jeroen@frijters.net */ +using System.Reflection.Emit; + using IKVM.Attributes; using IKVM.CoreLib.Symbols; -#if IMPORTER || EXPORTER -using IKVM.Reflection.Emit; -#else -using System.Reflection.Emit; -#endif - namespace IKVM.Runtime { diff --git a/src/IKVM.Runtime/RuntimeGhostJavaMethod.cs b/src/IKVM.Runtime/RuntimeGhostJavaMethod.cs index e986d0822..c24377024 100644 --- a/src/IKVM.Runtime/RuntimeGhostJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimeGhostJavaMethod.cs @@ -27,14 +27,6 @@ Jeroen Frijters using IKVM.CoreLib.Symbols; using IKVM.CoreLib.Symbols.Emit; -#if IMPORTER || EXPORTER -using IKVM.Reflection; -using IKVM.Reflection.Emit; -#else -using System.Reflection; -using System.Reflection.Emit; -#endif - namespace IKVM.Runtime { @@ -83,7 +75,7 @@ protected override void CallvirtImpl(CodeEmitter ilgen) [HideFromJava] internal override object Invoke(object obj, object[] args) { - return InvokeAndUnwrapException(ghostMethod.AsReflection(), DeclaringType.GhostWrap(obj), args); + return InvokeAndUnwrapException(ghostMethod, DeclaringType.GhostWrap(obj), args); } #endif @@ -102,12 +94,12 @@ internal IMethodSymbol GetDefaultImpl() internal void SetGhostMethod(IMethodSymbolBuilder mb) { - this.ghostMethod = mb.Symbol; + this.ghostMethod = mb; } internal IMethodSymbolBuilder GetGhostMethod() { - return ghostMethod.Builder; + return (IMethodSymbolBuilder)ghostMethod; } #endif diff --git a/src/IKVM.Runtime/RuntimeJavaMethod.cs b/src/IKVM.Runtime/RuntimeJavaMethod.cs index 2456f18ee..d416dc451 100644 --- a/src/IKVM.Runtime/RuntimeJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimeJavaMethod.cs @@ -23,24 +23,12 @@ Jeroen Frijters */ using System; using System.Diagnostics; +using System.Reflection; +using System.Reflection.Emit; using IKVM.Attributes; - -using System.Linq; - using IKVM.CoreLib.Symbols; - - - -#if IMPORTER || EXPORTER -using IKVM.Reflection; -using IKVM.Reflection.Emit; - -using Type = IKVM.Reflection.Type; -#else -using System.Reflection; -using System.Reflection.Emit; -#endif +using IKVM.CoreLib.Symbols.Emit; namespace IKVM.Runtime { @@ -238,7 +226,7 @@ java.lang.Class[] GetExceptions() // NOTE if method is a MethodBuilder, GetCustomAttributes doesn't work (and if // the method had any declared exceptions, the declaredExceptions field would have // been set) - if (method != null && method.AsReflection() is not MethodBuilder) + if (method != null && method is not IMethodSymbolBuilder) { var attr = DeclaringType.Context.AttributeHelper.GetThrows(method); if (attr != null) @@ -479,49 +467,7 @@ internal ITypeSymbol GetDelegateType() /// internal void ResolveMethod() { -#if FIRST_PASS - throw new NotImplementedException(); -#else - // if we've still got the builder object, we need to replace it with the real thing before we can call it - var mb = method.AsReflection() as MethodBuilder; - if (mb != null) - { -#if NETFRAMEWORK - method = mb.Module.ResolveMethod(mb.GetToken().Token); -#else - // though ResolveMethod exists, Core 3.1 does not provide a stable way to obtain the resulting metadata token - // instead we have to scan the methods for the one that matches the signature using the runtime type instances - // FIXME .NET 6 - - var parameters = GetParameters(); - var typeLength = parameters.Length; - if (HasCallerID) - typeLength++; - - var types = new Type[typeLength]; - for (int i = 0; i < parameters.Length; i++) - { - parameters[i].Finish(); - types[i] = parameters[i].TypeAsSignatureType; - } - - if (HasCallerID) - types[typeLength - 1] = DeclaringType.Context.JavaBase.TypeOfIkvmInternalCallerID.TypeAsSignatureType; - - if (ReturnType != null) - ReturnType.Finish(); - - var flags = BindingFlags.DeclaredOnly; - flags |= mb.IsPublic ? BindingFlags.Public : BindingFlags.NonPublic; - flags |= mb.IsStatic ? BindingFlags.Static : BindingFlags.Instance; - method = DeclaringType.TypeAsTBD.GetMethods(flags).FirstOrDefault(i => i.Name == mb.Name && i.GetParameters().Select(j => j.ParameterType).SequenceEqual(types) && i.ReturnType.Equals(ReturnType.TypeAsSignatureType)); - if (method == null) - method = DeclaringType.TypeAsTBD.GetConstructor(flags, null, types, null); - if (method == null) - throw new InternalException("Could not resolve method against runtime type."); -#endif - } -#endif + // should not require anything since Symbols should preserve method } [HideFromJava] diff --git a/src/IKVM.Runtime/RuntimeJavaType.cs b/src/IKVM.Runtime/RuntimeJavaType.cs index 70d6189dd..4908a8d3e 100644 --- a/src/IKVM.Runtime/RuntimeJavaType.cs +++ b/src/IKVM.Runtime/RuntimeJavaType.cs @@ -24,22 +24,13 @@ Jeroen Frijters using System; using System.Diagnostics; using System.Linq; +using System.Reflection; +using System.Reflection.Emit; using IKVM.Attributes; using IKVM.CoreLib.Diagnostics; using IKVM.CoreLib.Symbols; -#if IMPORTER || EXPORTER -using IKVM.Reflection; -using IKVM.Reflection.Emit; - -using Type = IKVM.Reflection.Type; - -#else -using System.Reflection; -using System.Reflection.Emit; -#endif - #if IMPORTER using IKVM.Tools.Importer; #endif diff --git a/src/IKVM.Runtime/RuntimeManagedByteCodeAccessStubJavaField.cs b/src/IKVM.Runtime/RuntimeManagedByteCodeAccessStubJavaField.cs index 624b90831..3b965b99a 100644 --- a/src/IKVM.Runtime/RuntimeManagedByteCodeAccessStubJavaField.cs +++ b/src/IKVM.Runtime/RuntimeManagedByteCodeAccessStubJavaField.cs @@ -21,20 +21,11 @@ Jeroen Frijters jeroen@frijters.net */ +using System.Reflection.Emit; + using IKVM.Attributes; using IKVM.CoreLib.Symbols; - -#if IMPORTER || EXPORTER -using IKVM.Reflection; -using IKVM.Reflection.Emit; - -using Type = IKVM.Reflection.Type; -#else -using System.Reflection; -using System.Reflection.Emit; -#endif - namespace IKVM.Runtime { @@ -117,16 +108,16 @@ protected override void EmitSetImpl(CodeEmitter ilgen) internal override object GetValue(object obj) { // we can only be invoked on type 2 access stubs (because type 1 access stubs are HideFromReflection), so we know we have a field - return GetField().GetValue(obj); + return GetField().AsReflection().GetValue(obj); } internal override void SetValue(object obj, object value) { // we can only be invoked on type 2 access stubs (because type 1 access stubs are HideFromReflection), so we know we have a field - GetField().SetValue(obj, value); + GetField().AsReflection().SetValue(obj, value); } -#endif +#endif } diff --git a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.DelegateConstructorJavaMethod.cs b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.DelegateConstructorJavaMethod.cs index da72483ac..c00004b8c 100644 --- a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.DelegateConstructorJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.DelegateConstructorJavaMethod.cs @@ -21,17 +21,9 @@ Jeroen Frijters jeroen@frijters.net */ -using IKVM.CoreLib.Symbols; - -#if IMPORTER || EXPORTER -using IKVM.Reflection; -using IKVM.Reflection.Emit; - -using Type = IKVM.Reflection.Type; -#else -using System.Reflection; using System.Reflection.Emit; -#endif + +using IKVM.CoreLib.Symbols; namespace IKVM.Runtime { diff --git a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.RemappedJavaMethod.cs b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.RemappedJavaMethod.cs index 6202c7511..dc6311ad0 100644 --- a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.RemappedJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.RemappedJavaMethod.cs @@ -22,16 +22,11 @@ Jeroen Frijters */ using System.Diagnostics; +using System.Reflection.Emit; using IKVM.Attributes; using IKVM.CoreLib.Symbols; -#if IMPORTER || EXPORTER -using IKVM.Reflection.Emit; -#else -using System.Reflection.Emit; -#endif - namespace IKVM.Runtime { diff --git a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs index dc1156c11..c0cda2478 100644 --- a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs @@ -180,7 +180,7 @@ public RuntimeManagedByteCodeJavaType(RuntimeContext context, ExModifiers exmod, public RuntimeManagedByteCodeJavaType(RuntimeContext context, string name, ITypeSymbol type) : this(context, GetModifiers(context, type), name) { - Debug.Assert(!(type.AsReflection() is TypeBuilder)); + Debug.Assert(!(type is ITypeSymbolBuilder)); Debug.Assert(!type.Name.EndsWith("[]")); this.type = type; @@ -241,7 +241,7 @@ internal override bool HasStaticInitializer { try { - clinitMethod = type.GetMethod("__", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic); + clinitMethod = type.GetMethod("__", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); } #if IMPORTER catch (IKVM.Reflection.MissingMemberException) @@ -325,10 +325,10 @@ private RuntimeJavaType[] GetInterfaces() private bool IsNestedTypeAnonymousOrLocalClass(ITypeSymbol type) { - switch (type.Attributes & (System.Reflection.TypeAttributes.SpecialName | System.Reflection.TypeAttributes.VisibilityMask)) + switch (type.Attributes & (TypeAttributes.SpecialName | TypeAttributes.VisibilityMask)) { - case System.Reflection.TypeAttributes.SpecialName | System.Reflection.TypeAttributes.NestedPublic: - case System.Reflection.TypeAttributes.SpecialName | System.Reflection.TypeAttributes.NestedAssembly: + case TypeAttributes.SpecialName | TypeAttributes.NestedPublic: + case TypeAttributes.SpecialName | TypeAttributes.NestedAssembly: return Context.AttributeHelper.HasEnclosingMethodAttribute(type); default: return false; @@ -346,7 +346,7 @@ internal override RuntimeJavaType[] InnerClasses { var wrappers = new List(); - foreach (var nested in type.GetNestedTypes(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.DeclaredOnly)) + foreach (var nested in type.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly)) { if (IsAnnotationAttribute(nested)) { @@ -652,7 +652,7 @@ void GetNameSigFromMethodBase(IMethodBaseSymbol method, out string name, out str protected override void LazyPublishMethods() { - const System.Reflection.BindingFlags flags = System.Reflection.BindingFlags.DeclaredOnly | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Instance; + const BindingFlags flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance; var isDelegate = type.BaseType == Context.Types.MulticastDelegate; var methods = new List(); @@ -670,7 +670,7 @@ protected override void LazyPublishMethods() if (type.IsInterface && (type.IsPublic || type.IsNestedPublic)) { - var privateInterfaceMethods = type.GetNestedType(NestedTypeName.PrivateInterfaceMethods, System.Reflection.BindingFlags.NonPublic); + var privateInterfaceMethods = type.GetNestedType(NestedTypeName.PrivateInterfaceMethods, BindingFlags.NonPublic); if (privateInterfaceMethods != null) AddMethods(privateInterfaceMethods.GetMethods(flags), methods); } @@ -714,7 +714,7 @@ private void AddMethodOrConstructor(IMethodBaseSymbol method, HideFromJavaFlags name = name.Substring(name.IndexOf('|', NamePrefix.AccessStub.Length) + 1); flags |= MemberFlags.AccessStub; - var nonvirt = type.GetMethod(NamePrefix.NonVirtual + id, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.DeclaredOnly | System.Reflection.BindingFlags.Instance); + var nonvirt = type.GetMethod(NamePrefix.NonVirtual + id, BindingFlags.NonPublic | BindingFlags.DeclaredOnly | BindingFlags.Instance); methods.Add(new RuntimeAccessStubJavaMethod(this, name, sig, mi, mi, nonvirt ?? mi, retType, paramTypes, mods.Modifiers & ~Modifiers.Final, flags)); return; } @@ -770,7 +770,7 @@ private void AddMethodOrConstructor(IMethodBaseSymbol method, HideFromJavaFlags IMethodSymbol GetDefaultInterfaceMethodImpl(IMethodSymbol method, string expectedSig) { - foreach (var candidate in method.DeclaringType.GetMethods(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.DeclaredOnly)) + foreach (var candidate in method.DeclaringType.GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly)) { if (candidate.IsSpecialName && candidate.Name.StartsWith(NamePrefix.DefaultMethod, StringComparison.Ordinal) && @@ -789,12 +789,12 @@ IMethodSymbol GetDefaultInterfaceMethodImpl(IMethodSymbol method, string expecte bool GetType2AccessStubs(string name, string sig, out IMethodSymbol stubVirt, out IMethodSymbol stubNonVirt) { - const System.Reflection.BindingFlags flags = - System.Reflection.BindingFlags.DeclaredOnly | - System.Reflection.BindingFlags.Public | - System.Reflection.BindingFlags.NonPublic | - System.Reflection.BindingFlags.Static | - System.Reflection.BindingFlags.Instance; + const BindingFlags flags = + BindingFlags.DeclaredOnly | + BindingFlags.Public | + BindingFlags.NonPublic | + BindingFlags.Static | + BindingFlags.Instance; stubVirt = null; stubNonVirt = null; @@ -818,11 +818,11 @@ bool GetType2AccessStubs(string name, string sig, out IMethodSymbol stubVirt, ou bool GetType2AccessStub(string sig, out IConstructorSymbol stub) { - const System.Reflection.BindingFlags flags = - System.Reflection.BindingFlags.DeclaredOnly | - System.Reflection.BindingFlags.Public | - System.Reflection.BindingFlags.NonPublic | - System.Reflection.BindingFlags.Instance; + const BindingFlags flags = + BindingFlags.DeclaredOnly | + BindingFlags.Public | + BindingFlags.NonPublic | + BindingFlags.Instance; stub = null; foreach (var ctor in type.GetConstructors(flags)) @@ -845,12 +845,12 @@ static int SortFieldByToken(IFieldSymbol field1, IFieldSymbol field2) protected override void LazyPublishFields() { - const System.Reflection.BindingFlags flags = - System.Reflection.BindingFlags.DeclaredOnly | - System.Reflection.BindingFlags.Public | - System.Reflection.BindingFlags.NonPublic | - System.Reflection.BindingFlags.Static | - System.Reflection.BindingFlags.Instance; + const BindingFlags flags = + BindingFlags.DeclaredOnly | + BindingFlags.Public | + BindingFlags.NonPublic | + BindingFlags.Static | + BindingFlags.Instance; var fields = new List(); var rawfields = type.GetFields(flags); @@ -1022,9 +1022,7 @@ RuntimeJavaField CreateFieldWrapper(IFieldSymbol field, HideFromJavaFlags hideFr internal override void EmitRunClassConstructor(CodeEmitter ilgen) { if (HasStaticInitializer) - { ilgen.Emit(OpCodes.Call, clinitMethod); - } } #endif // EMITTERS diff --git a/src/IKVM.Runtime/RuntimeManagedByteCodePropertyJavaField.cs b/src/IKVM.Runtime/RuntimeManagedByteCodePropertyJavaField.cs index 87f276f30..0f1222e26 100644 --- a/src/IKVM.Runtime/RuntimeManagedByteCodePropertyJavaField.cs +++ b/src/IKVM.Runtime/RuntimeManagedByteCodePropertyJavaField.cs @@ -21,17 +21,9 @@ Jeroen Frijters jeroen@frijters.net */ -using IKVM.CoreLib.Symbols; - -#if IMPORTER || EXPORTER -using IKVM.Reflection; -using IKVM.Reflection.Emit; - -using Type = IKVM.Reflection.Type; -#else -using System.Reflection; using System.Reflection.Emit; -#endif + +using IKVM.CoreLib.Symbols; namespace IKVM.Runtime { diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.EnumValueJavaField.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.EnumValueJavaField.cs index de5ed4d6d..c27ed2d7e 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.EnumValueJavaField.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.EnumValueJavaField.cs @@ -21,21 +21,12 @@ Jeroen Frijters jeroen@frijters.net */ -using System; +using System.Reflection; +using System.Reflection.Emit; using IKVM.Attributes; using IKVM.CoreLib.Symbols; - -#if IMPORTER || EXPORTER -using IKVM.Reflection.Emit; - -using Type = IKVM.Reflection.Type; -#else -using System.Reflection; -using System.Reflection.Emit; -#endif - namespace IKVM.Runtime { diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.FinalizeJavaMethod.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.FinalizeJavaMethod.cs index 719def4df..b356c8267 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.FinalizeJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.FinalizeJavaMethod.cs @@ -22,15 +22,10 @@ Jeroen Frijters */ using System; +using System.Reflection.Emit; using IKVM.Attributes; -#if IMPORTER || EXPORTER -using IKVM.Reflection.Emit; -#else -using System.Reflection.Emit; -#endif - namespace IKVM.Runtime { diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.ValueTypeDefaultCtorJavaMethod.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.ValueTypeDefaultCtorJavaMethod.cs index b81eccfa3..730a30941 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.ValueTypeDefaultCtorJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.ValueTypeDefaultCtorJavaMethod.cs @@ -22,15 +22,10 @@ Jeroen Frijters */ using System; +using System.Reflection.Emit; using IKVM.Attributes; -#if IMPORTER -using IKVM.Reflection.Emit; -#else -using System.Reflection.Emit; -#endif - namespace IKVM.Runtime { @@ -70,7 +65,7 @@ internal override void EmitCall(CodeEmitter ilgen) internal override object CreateInstance(object[] args) { - return Activator.CreateInstance(DeclaringType.TypeAsTBD); + return Activator.CreateInstance(DeclaringType.TypeAsTBD.AsReflection()); } #endif diff --git a/src/IKVM.Runtime/RuntimeMirandaJavaMethod.cs b/src/IKVM.Runtime/RuntimeMirandaJavaMethod.cs index 20b759a37..0cedcd20b 100644 --- a/src/IKVM.Runtime/RuntimeMirandaJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimeMirandaJavaMethod.cs @@ -21,13 +21,9 @@ Jeroen Frijters jeroen@frijters.net */ -using IKVM.Attributes; - -#if IMPORTER || EXPORTER -using IKVM.Reflection.Emit; -#else using System.Reflection.Emit; -#endif + +using IKVM.Attributes; namespace IKVM.Runtime { diff --git a/src/IKVM.Runtime/RuntimePrimitiveJavaType.cs b/src/IKVM.Runtime/RuntimePrimitiveJavaType.cs index d0e2256a5..dad64f765 100644 --- a/src/IKVM.Runtime/RuntimePrimitiveJavaType.cs +++ b/src/IKVM.Runtime/RuntimePrimitiveJavaType.cs @@ -22,21 +22,11 @@ Jeroen Frijters */ using System; +using System.Reflection.Emit; using IKVM.Attributes; using IKVM.CoreLib.Symbols; - -#if IMPORTER || EXPORTER -using IKVM.Reflection; -using IKVM.Reflection.Emit; - -using Type = IKVM.Reflection.Type; -#else -using System.Reflection; -using System.Reflection.Emit; -#endif - namespace IKVM.Runtime { diff --git a/src/IKVM.Runtime/RuntimePrivateInterfaceJavaMethod.cs b/src/IKVM.Runtime/RuntimePrivateInterfaceJavaMethod.cs index e7535f9f7..d02d38113 100644 --- a/src/IKVM.Runtime/RuntimePrivateInterfaceJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimePrivateInterfaceJavaMethod.cs @@ -21,15 +21,11 @@ Jeroen Frijters jeroen@frijters.net */ +using System.Reflection.Emit; + using IKVM.Attributes; using IKVM.CoreLib.Symbols; -#if IMPORTER || EXPORTER -using IKVM.Reflection.Emit; -#else -using System.Reflection.Emit; -#endif - namespace IKVM.Runtime { diff --git a/src/IKVM.Runtime/RuntimeSimpleCallJavaMethod.cs b/src/IKVM.Runtime/RuntimeSimpleCallJavaMethod.cs index 424a8ac14..335307cd0 100644 --- a/src/IKVM.Runtime/RuntimeSimpleCallJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimeSimpleCallJavaMethod.cs @@ -24,12 +24,6 @@ Jeroen Frijters using IKVM.Attributes; using IKVM.CoreLib.Symbols; -#if IMPORTER || EXPORTER -using IKVM.Reflection; -#else -using System.Reflection; -#endif - namespace IKVM.Runtime { diff --git a/src/IKVM.Runtime/RuntimeSimpleJavaField.cs b/src/IKVM.Runtime/RuntimeSimpleJavaField.cs index bba30138f..4045ad61d 100644 --- a/src/IKVM.Runtime/RuntimeSimpleJavaField.cs +++ b/src/IKVM.Runtime/RuntimeSimpleJavaField.cs @@ -22,22 +22,10 @@ Jeroen Frijters */ using System.Diagnostics; -using System.Runtime.CompilerServices; -using IKVM.CoreLib.Symbols; - - -#if IMPORTER || EXPORTER -using IKVM.Reflection; -using IKVM.Reflection.Emit; -#else -using System.Reflection; using System.Reflection.Emit; -using System.Threading; -#endif +using System.Runtime.CompilerServices; -#if IMPORTER -using IKVM.Tools.Importer; -#endif +using IKVM.CoreLib.Symbols; namespace IKVM.Runtime { diff --git a/src/IKVM.Runtime/RuntimeTypicalJavaMethod.cs b/src/IKVM.Runtime/RuntimeTypicalJavaMethod.cs index e2a384afa..fc1963a95 100644 --- a/src/IKVM.Runtime/RuntimeTypicalJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimeTypicalJavaMethod.cs @@ -21,20 +21,11 @@ Jeroen Frijters jeroen@frijters.net */ +using System.Reflection.Emit; + using IKVM.Attributes; using IKVM.CoreLib.Symbols; - -#if IMPORTER || EXPORTER -using IKVM.Reflection; -using IKVM.Reflection.Emit; - -using Type = IKVM.Reflection.Type; -#else -using System.Reflection; -using System.Reflection.Emit; -#endif - namespace IKVM.Runtime { diff --git a/src/IKVM.Runtime/RuntimeVolatileLongDoubleJavaField.cs b/src/IKVM.Runtime/RuntimeVolatileLongDoubleJavaField.cs index e2c161e13..3b4dc7fba 100644 --- a/src/IKVM.Runtime/RuntimeVolatileLongDoubleJavaField.cs +++ b/src/IKVM.Runtime/RuntimeVolatileLongDoubleJavaField.cs @@ -22,17 +22,10 @@ Jeroen Frijters */ using System; +using System.Reflection.Emit; using IKVM.CoreLib.Symbols; -#if IMPORTER || EXPORTER -using IKVM.Reflection; -using IKVM.Reflection.Emit; -#else -using System.Reflection; -using System.Reflection.Emit; -#endif - namespace IKVM.Runtime { diff --git a/src/IKVM.Runtime/Serialization.cs b/src/IKVM.Runtime/Serialization.cs index c11630dbb..a2dfffbfb 100644 --- a/src/IKVM.Runtime/Serialization.cs +++ b/src/IKVM.Runtime/Serialization.cs @@ -89,9 +89,9 @@ bool IsSafeForAutomagicSerialization(RuntimeJavaType wrapper) return true; } - internal IMethodSymbolBuilder AddAutomagicSerialization(RuntimeByteCodeJavaType wrapper, ITypeSymbolBuilder typeBuilder) + internal IConstructorSymbolBuilder AddAutomagicSerialization(RuntimeByteCodeJavaType wrapper, ITypeSymbolBuilder typeBuilder) { - IMethodSymbolBuilder serializationCtor = null; + IConstructorSymbolBuilder serializationCtor = null; if ((wrapper.Modifiers & IKVM.Attributes.Modifiers.Enum) != 0) { MarkSerializable(typeBuilder); @@ -148,7 +148,7 @@ internal IMethodSymbolBuilder AddAutomagicSerialization(RuntimeByteCodeJavaType return serializationCtor; } - internal IMethodSymbolBuilder AddAutomagicSerializationToWorkaroundBaseClass(ITypeSymbolBuilder typeBuilderWorkaroundBaseClass, IMethodBaseSymbol baseCtor) + internal IConstructorSymbolBuilder AddAutomagicSerializationToWorkaroundBaseClass(ITypeSymbolBuilder typeBuilderWorkaroundBaseClass, IMethodBaseSymbol baseCtor) { if (typeBuilderWorkaroundBaseClass.BaseType.IsSerializable) { @@ -187,7 +187,7 @@ internal void AddGetObjectData(ITypeSymbolBuilder tb) ilgen.DoEmit(); } - IMethodSymbolBuilder AddConstructor(ITypeSymbolBuilder tb, RuntimeJavaMethod defaultConstructor, IMethodBaseSymbol serializationConstructor, bool callReadObject) + IConstructorSymbolBuilder AddConstructor(ITypeSymbolBuilder tb, RuntimeJavaMethod defaultConstructor, IMethodBaseSymbol serializationConstructor, bool callReadObject) { var ctor = ReflectUtil.DefineConstructor(tb, MethodAttributes.Family, [context.Resolver.ResolveCoreType(typeof(SerializationInfo).FullName), context.Resolver.ResolveCoreType(typeof(StreamingContext).FullName)]); context.AttributeHelper.HideFromJava(ctor); diff --git a/src/IKVM.Tools.Exporter/ManagedTypeResolver.cs b/src/IKVM.Tools.Exporter/ManagedTypeResolver.cs index 111b284f6..35d106fc8 100644 --- a/src/IKVM.Tools.Exporter/ManagedTypeResolver.cs +++ b/src/IKVM.Tools.Exporter/ManagedTypeResolver.cs @@ -3,8 +3,10 @@ using System; using IKVM.CoreLib.Symbols; +using IKVM.CoreLib.Symbols.Emit; using IKVM.CoreLib.Symbols.IkvmReflection; using IKVM.Reflection; +using IKVM.Reflection.Emit; using IKVM.Runtime; using Type = IKVM.Reflection.Type; @@ -34,30 +36,19 @@ public ManagedTypeResolver(IkvmReflectionSymbolContext symbols, StaticCompiler c /// public ISymbolContext Symbols => symbols; - /// - /// Attempts to resolve the base Java assembly. - /// - /// + /// public IAssemblySymbol? ResolveBaseAssembly() { return ResolveAssembly(baseAssembly); } - /// - /// Attempts to resolve an assembly from one of the assembly sources. - /// - /// - /// + /// public IAssemblySymbol? ResolveAssembly(string assemblyName) { return ResolveAssembly(compiler.Load(assemblyName)); } - /// - /// Attempts to resolve a type from one of the assembly sources. - /// - /// - /// + /// public ITypeSymbol? ResolveCoreType(string typeName) { foreach (var assembly in compiler.Universe.GetAssemblies()) @@ -67,11 +58,7 @@ public ManagedTypeResolver(IkvmReflectionSymbolContext symbols, StaticCompiler c return null; } - /// - /// Attempts to resolve a type from the IKVM runtime assembly. - /// - /// - /// + /// public ITypeSymbol? ResolveRuntimeType(string typeName) { return ResolveType(compiler.GetRuntimeType(typeName)); @@ -83,18 +70,42 @@ public ManagedTypeResolver(IkvmReflectionSymbolContext symbols, StaticCompiler c return assembly != null ? symbols.GetOrCreateAssemblySymbol(assembly) : null; } + /// + public IAssemblySymbolBuilder? ResolveAssembly(AssemblyBuilder? assembly) + { + return assembly != null ? symbols.GetOrCreateAssemblySymbol(assembly) : null; + } + /// public IModuleSymbol? ResolveModule(Module? module) { return module != null ? symbols.GetOrCreateModuleSymbol(module) : null; } + /// + public IModuleSymbolBuilder? ResolveModule(ModuleBuilder? module) + { + return module != null ? symbols.GetOrCreateModuleSymbol(module) : null; + } + /// public ITypeSymbol? ResolveType(Type? type) { return type != null ? symbols.GetOrCreateTypeSymbol(type) : null; } + /// + public ITypeSymbolBuilder? ResolveType(TypeBuilder? type) + { + return type != null ? symbols.GetOrCreateTypeSymbol(type) : null; + } + + /// + public IMemberSymbol? ResolveMember(MemberInfo? module) + { + return module != null ? symbols.GetOrCreateMemberSymbol(module) : null; + } + /// public IMethodBaseSymbol? ResolveMethodBase(MethodBase? method) { @@ -107,12 +118,24 @@ public ManagedTypeResolver(IkvmReflectionSymbolContext symbols, StaticCompiler c return ctor != null ? symbols.GetOrCreateConstructorSymbol(ctor) : null; } + /// + public IConstructorSymbolBuilder? ResolveConstructor(ConstructorBuilder? ctor) + { + return ctor != null ? symbols.GetOrCreateConstructorSymbol(ctor) : null; + } + /// public IMethodSymbol? ResolveMethod(MethodInfo? method) { return method != null ? symbols.GetOrCreateMethodSymbol(method) : null; } + /// + public IMethodSymbolBuilder? ResolveMethod(MethodBuilder? method) + { + return method != null ? symbols.GetOrCreateMethodSymbol(method) : null; + } + } } diff --git a/src/IKVM.Tools.Importer/AssemblyResolver.cs b/src/IKVM.Tools.Importer/AssemblyResolver.cs index a6209afaf..2608e2c37 100644 --- a/src/IKVM.Tools.Importer/AssemblyResolver.cs +++ b/src/IKVM.Tools.Importer/AssemblyResolver.cs @@ -1,25 +1,25 @@ /* - Copyright (C) 2010-2013 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - + Copyright (C) 2010-2013 Jeroen Frijters + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jeroen Frijters + jeroen@frijters.net + */ using System; using System.Collections.Generic; @@ -385,4 +385,4 @@ IEnumerable FindAssemblyPath(string file) } -} +} \ No newline at end of file diff --git a/src/IKVM.Tools.Importer/FakeTypes.cs b/src/IKVM.Tools.Importer/FakeTypes.cs index 61bf501de..677d65f0a 100644 --- a/src/IKVM.Tools.Importer/FakeTypes.cs +++ b/src/IKVM.Tools.Importer/FakeTypes.cs @@ -22,10 +22,10 @@ Jeroen Frijters */ using System; +using System.Reflection; using IKVM.CoreLib.Symbols; -using IKVM.Reflection; -using IKVM.Reflection.Emit; +using IKVM.CoreLib.Symbols.Emit; using IKVM.Runtime; namespace IKVM.Tools.Importer @@ -76,12 +76,13 @@ internal ITypeSymbol GetAttributeReturnValueType(ITypeSymbol attributeType) return genericAttributeAnnotationReturnValueType.MakeGenericType(attributeType); } - internal void Create(ModuleBuilder modb, RuntimeClassLoader loader) + internal void Create(IModuleSymbolBuilder modb, RuntimeClassLoader loader) { - var tb = modb.DefineType(RuntimeManagedJavaType.GenericDelegateInterfaceTypeName, TypeAttributes.Interface | TypeAttributes.Abstract | TypeAttributes.Public); - tb.DefineGenericParameters("T")[0].SetBaseTypeConstraint(context.Types.MulticastDelegate.AsReflection()); - genericDelegateInterfaceType = context.Resolver.ResolveType(tb.CreateType()); + var tb = modb.DefineType(RuntimeManagedJavaType.GenericDelegateInterfaceTypeName, TypeAttributes.Interface | System.Reflection.TypeAttributes.Abstract | System.Reflection.TypeAttributes.Public); + tb.DefineGenericParameters("T")[0].SetBaseTypeConstraint(context.Types.MulticastDelegate); + tb.Complete(); + genericDelegateInterfaceType = tb; genericAttributeAnnotationType = CreateAnnotationType(modb, RuntimeManagedJavaType.GenericAttributeAnnotationTypeName); genericAttributeAnnotationMultipleType = CreateAnnotationType(modb, RuntimeManagedJavaType.GenericAttributeAnnotationMultipleTypeName); genericAttributeAnnotationReturnValueType = CreateAnnotationType(modb, RuntimeManagedJavaType.GenericAttributeAnnotationReturnValueTypeName); @@ -90,33 +91,39 @@ internal void Create(ModuleBuilder modb, RuntimeClassLoader loader) internal void Finish(RuntimeClassLoader loader) { - var tb = (TypeBuilder)genericEnumEnumType.AsReflection(); + var tb = (ITypeSymbolBuilder)genericEnumEnumType; var enumTypeWrapper = loader.LoadClassByName("java.lang.Enum"); enumTypeWrapper.Finish(); - tb.SetParent(enumTypeWrapper.TypeAsBaseType.AsReflection()); - var ilgen = context.CodeEmitterFactory.Create(ReflectUtil.DefineConstructor(tb, MethodAttributes.Private, [context.Types.String.AsReflection(), context.Types.Int32.AsReflection()])); - ilgen.Emit(OpCodes.Ldarg_0); - ilgen.Emit(OpCodes.Ldarg_1); - ilgen.Emit(OpCodes.Ldarg_2); + tb.SetParent(enumTypeWrapper.TypeAsBaseType); + var ilgen = context.CodeEmitterFactory.Create(ReflectUtil.DefineConstructor(tb, MethodAttributes.Private, [context.Types.String, context.Types.Int32])); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldarg_1); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldarg_2); enumTypeWrapper.GetMethodWrapper("", "(Ljava.lang.String;I)V", false).EmitCall(ilgen); - ilgen.Emit(OpCodes.Ret); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ret); ilgen.DoEmit(); - genericEnumEnumType = context.Resolver.ResolveType(tb.CreateType()); + tb.Complete(); + + genericEnumEnumType = tb; } - void CreateEnumEnum(ModuleBuilder modb, RuntimeClassLoader loader) + void CreateEnumEnum(IModuleSymbolBuilder modb, RuntimeClassLoader loader) { var tb = modb.DefineType(RuntimeManagedJavaType.GenericEnumEnumTypeName, TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.Public); var gtpb = tb.DefineGenericParameters("T")[0]; - gtpb.SetBaseTypeConstraint(context.Types.Enum.AsReflection()); - genericEnumEnumType = context.Resolver.ResolveType(tb); + gtpb.SetBaseTypeConstraint(context.Types.Enum); + tb.Complete(); + + genericEnumEnumType = tb; } - ITypeSymbol CreateAnnotationType(ModuleBuilder modb, string name) + ITypeSymbol CreateAnnotationType(IModuleSymbolBuilder modb, string name) { var tb = modb.DefineType(name, TypeAttributes.Interface | TypeAttributes.Abstract | TypeAttributes.Public); - tb.DefineGenericParameters("T")[0].SetBaseTypeConstraint(context.Types.Attribute.AsReflection()); - return context.Resolver.ResolveType(tb.CreateType()); + tb.DefineGenericParameters("T")[0].SetBaseTypeConstraint(context.Types.Attribute); + tb.Complete(); + + return tb; } internal void Load(IAssemblySymbol assembly) diff --git a/src/IKVM.Tools.Importer/ImportClassLoader.cs b/src/IKVM.Tools.Importer/ImportClassLoader.cs index a535a1957..ffcb94172 100644 --- a/src/IKVM.Tools.Importer/ImportClassLoader.cs +++ b/src/IKVM.Tools.Importer/ImportClassLoader.cs @@ -61,7 +61,7 @@ sealed class ImportClassLoader : RuntimeClassLoader string assemblyFile; string assemblyDir; bool targetIsModule; - AssemblyBuilder assemblyBuilder; + IAssemblySymbolBuilder assemblyBuilder; MapXml.Attribute[] assemblyAttributes; ImportState state; private readonly StaticCompiler compiler; @@ -138,16 +138,7 @@ internal void AddReference(ImportClassLoader ccl) internal System.Reflection.AssemblyName GetAssemblyName() { - var src = assemblyBuilder.GetName(); - return new System.Reflection.AssemblyName - { - Name = src.Name, - Version = src.Version, - CultureName = src.CultureName, - HashAlgorithm = (System.Configuration.Assemblies.AssemblyHashAlgorithm)src.HashAlgorithm, - Flags = (System.Reflection.AssemblyNameFlags)src.Flags, - ContentType = (System.Reflection.AssemblyContentType)src.ContentType, - }; + return assemblyBuilder.GetName(); } private static PermissionSet Combine(PermissionSet p1, PermissionSet p2) @@ -163,7 +154,7 @@ private static PermissionSet Combine(PermissionSet p1, PermissionSet p2) return p1.Union(p2); } - internal ModuleBuilder CreateModuleBuilder() + internal IModuleSymbolBuilder CreateModuleBuilder() { var name = new AssemblyName(); name.Name = assemblyName; @@ -175,8 +166,8 @@ internal ModuleBuilder CreateModuleBuilder() name.Version = state.version; // define a dynamic assembly and module - assemblyBuilder = Context.StaticCompiler.Universe.DefineDynamicAssembly(name, AssemblyBuilderAccess.ReflectionOnly, assemblyDir); - var moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName, assemblyFile, EmitSymbols); + assemblyBuilder = Context.Resolver.ResolveAssembly(Context.StaticCompiler.Universe.DefineDynamicAssembly(name, AssemblyBuilderAccess.ReflectionOnly, assemblyDir)); + var moduleBuilder = assemblyBuilder.DefineModule(assemblyName, assemblyFile, EmitSymbols); // if configured to emit stack trace info set source file if (EmitStackTraceInfo) @@ -195,11 +186,11 @@ internal ModuleBuilder CreateModuleBuilder() Context.AttributeHelper.SetRuntimeCompatibilityAttribute(assemblyBuilder); if (state.baseAddress != 0) - moduleBuilder.__ImageBase = state.baseAddress; + moduleBuilder.ImageBase = state.baseAddress; if (state.fileAlignment != 0) - moduleBuilder.__FileAlignment = state.fileAlignment; + moduleBuilder.FileAlignment = state.fileAlignment; if (state.highentropyva) - moduleBuilder.__DllCharacteristics |= DllCharacteristics.HighEntropyVA; + moduleBuilder.DllCharacteristics |= System.Reflection.PortableExecutable.DllCharacteristics.HighEntropyVirtualAddressSpace; // allow the runtime to "inject" dynamic classes into the assembly var mainAssemblyName = state.sharedclassloader != null && state.sharedclassloader[0] != this @@ -495,17 +486,17 @@ internal override bool InternalsVisibleToImpl(RuntimeJavaType wrapper, RuntimeJa private void AddInternalsVisibleToAttribute(ImportClassLoader ccl) { internalsVisibleTo.Add(ccl); - AssemblyBuilder asm = ccl.assemblyBuilder; - AssemblyName asmName = asm.GetName(); - string name = asmName.Name; - byte[] pubkey = asmName.GetPublicKey(); + var asm = ccl.assemblyBuilder; + var asmName = asm.GetName(); + var name = asmName.Name; + var pubkey = asmName.GetPublicKey(); + if (pubkey == null && asmName.KeyPair != null) - { pubkey = asmName.KeyPair.PublicKey; - } + if (pubkey != null && pubkey.Length != 0) { - StringBuilder sb = new StringBuilder(name); + var sb = new StringBuilder(name); sb.Append(", PublicKey="); foreach (byte b in pubkey) { @@ -513,6 +504,7 @@ private void AddInternalsVisibleToAttribute(ImportClassLoader ccl) } name = sb.ToString(); } + Context.AttributeHelper.SetInternalsVisibleToAttribute(this.assemblyBuilder, name); } @@ -524,7 +516,7 @@ private void AddInternalsVisibleToAttribute(ImportClassLoader ccl) /// /// /// - void SetMain(RuntimeJavaType type, PEFileKinds target, IDictionary properties, bool noglobbing, Type apartmentAttributeType) + void SetMain(RuntimeJavaType type, IKVM.CoreLib.Symbols.Emit.PEFileKinds target, IDictionary properties, bool noglobbing, ITypeSymbol apartmentAttributeType) { if (type is null) throw new ArgumentNullException(nameof(type)); @@ -532,63 +524,63 @@ void SetMain(RuntimeJavaType type, PEFileKinds target, IDictionary())); + mainMethodProxy.SetCustomAttribute(Context.Resolver.Symbols.CreateCustomAttribute(apartmentAttributeType.GetConstructor([]), [])); var ilgen = Context.CodeEmitterFactory.Create(mainMethodProxy); // first argument to Launch (assembly) - ilgen.Emit(OpCodes.Ldtoken, type.TypeAsTBD); - ilgen.Emit(OpCodes.Call, Context.CompilerFactory.GetTypeFromHandleMethod); - ilgen.Emit(OpCodes.Callvirt, Context.Types.Type.GetProperty(nameof(System.Type.Assembly)).GetGetMethod()); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldtoken, type.TypeAsTBD); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, Context.CompilerFactory.GetTypeFromHandleMethod); + ilgen.Emit(System.Reflection.Emit.OpCodes.Callvirt, Context.Types.Type.GetProperty(nameof(System.Type.Assembly)).GetGetMethod()); // second argument to Launch (type name) - ilgen.Emit(OpCodes.Ldstr, type.Name); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldstr, type.Name); // third argument: is this a jar - ilgen.Emit(OpCodes.Ldc_I4_0); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_0); // fourth argument: args - ilgen.Emit(OpCodes.Ldarg_0); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); // fifth argument, runtime prefix - ilgen.Emit(OpCodes.Ldstr, DEFAULT_RUNTIME_ARGS_PREFIX); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldstr, DEFAULT_RUNTIME_ARGS_PREFIX); // sixth argument, property set to initialize JVM if (properties.Count > 0) { - var environmentType = Context.Resolver.ResolveCoreType(typeof(Environment).FullName).AsReflection(); + var environmentType = Context.Resolver.ResolveCoreType(typeof(Environment).FullName); var environmentExpandMethod = environmentType.GetMethod(nameof(Environment.ExpandEnvironmentVariables), [Context.Types.String]); - var dictionaryType = Context.Resolver.ResolveCoreType(typeof(Dictionary<,>).FullName).AsReflection().MakeGenericType(Context.Types.String, Context.Types.String); + var dictionaryType = Context.Resolver.ResolveCoreType(typeof(Dictionary<,>).FullName).MakeGenericType(Context.Types.String, Context.Types.String); var dictionaryAddMethod = dictionaryType.GetMethod("Add", [Context.Types.String, Context.Types.String]); ilgen.EmitLdc_I4(properties.Count); - ilgen.Emit(OpCodes.Newobj, dictionaryType.GetConstructor([Context.Types.Int32])); + ilgen.Emit(System.Reflection.Emit.OpCodes.Newobj, dictionaryType.GetConstructor([Context.Types.Int32])); foreach (var kvp in properties) { - ilgen.Emit(OpCodes.Dup); - ilgen.Emit(OpCodes.Ldstr, kvp.Key); - ilgen.Emit(OpCodes.Ldstr, kvp.Value); + ilgen.Emit(System.Reflection.Emit.OpCodes.Dup); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldstr, kvp.Key); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldstr, kvp.Value); // property value can reference an environmental variable (reassess the requirment for this) if (kvp.Value.IndexOf('%') < kvp.Value.LastIndexOf('%')) - ilgen.Emit(OpCodes.Call, environmentExpandMethod); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, environmentExpandMethod); // add to properties dictionary - ilgen.Emit(OpCodes.Callvirt, dictionaryAddMethod); + ilgen.Emit(System.Reflection.Emit.OpCodes.Callvirt, dictionaryAddMethod); } } else { - ilgen.Emit(OpCodes.Ldnull); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldnull); } // invoke the launcher main method - var launchMethod = Context.Resolver.ResolveRuntimeType(typeof(IKVM.Runtime.Launcher).FullName).GetMethod(nameof(IKVM.Runtime.Launcher.Run)).AsReflection(); - ilgen.Emit(OpCodes.Call, launchMethod); - ilgen.Emit(OpCodes.Ret); + var launchMethod = Context.Resolver.ResolveRuntimeType(typeof(IKVM.Runtime.Launcher).FullName).GetMethod(nameof(IKVM.Runtime.Launcher.Run)); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, launchMethod); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ret); // generate entry point ilgen.DoEmit(); @@ -602,7 +594,7 @@ void PrepareSave() void Save() { - ModuleBuilder mb = GetTypeWrapperFactory().ModuleBuilder; + var mb = GetTypeWrapperFactory().ModuleBuilder; if (targetIsModule) { // HACK force all referenced assemblies to end up as references in the assembly @@ -611,26 +603,21 @@ void Save() // NOTE now we only do this for modules, when we're an assembly we store the exported // assemblies in the ikvm.exports resource. for (int i = 0; i < referencedAssemblies.Length; i++) - { - Type[] types = referencedAssemblies[i].MainAssembly.GetExportedTypes(); - if (types.Length > 0) - { - mb.GetTypeToken(types[0]); - } - } + mb.AddReference(referencedAssemblies[i].MainAssembly); } - mb.CreateGlobalFunctions(); + + mb.Complete(); AddJavaModuleAttribute(mb); // add a package list and export map if (state.sharedclassloader == null || state.sharedclassloader[0] == this) { - var packageListAttributeCtor = Context.Resolver.ResolveRuntimeType(typeof(PackageListAttribute).FullName).AsReflection().GetConstructor([Context.Types.String, Context.Types.String.MakeArrayType()]); + var packageListAttributeCtor = Context.Resolver.ResolveRuntimeType(typeof(PackageListAttribute).FullName).GetConstructor([Context.Types.String, Context.Types.String.MakeArrayType()]); foreach (object[] args in packages.ToArray()) { args[1] = UnicodeUtil.EscapeInvalidSurrogates((string[])args[1]); - mb.SetCustomAttribute(new CustomAttributeBuilder(packageListAttributeCtor, args)); + mb.SetCustomAttribute(Context.Resolver.Symbols.CreateCustomAttribute(packageListAttributeCtor, args)); } // We can't add the resource when we're a module, because a multi-module assembly has a single resource namespace // and since you cannot combine -target:module with -sharedclassloader we don't need an export map @@ -647,7 +634,7 @@ void Save() try { - GetTypeWrapperFactory().ModuleBuilder.__Save(state.pekind, state.imageFileMachine); + GetTypeWrapperFactory().ModuleBuilder.Save(state.pekind, state.imageFileMachine); } catch (IOException x) { @@ -677,9 +664,9 @@ void Save() } } - void AddJavaModuleAttribute(ModuleBuilder mb) + void AddJavaModuleAttribute(IModuleSymbolBuilder mb) { - var typeofJavaModuleAttribute = Context.Resolver.ResolveRuntimeType(typeof(JavaModuleAttribute).FullName).AsReflection(); + var typeofJavaModuleAttribute = Context.Resolver.ResolveRuntimeType(typeof(JavaModuleAttribute).FullName); var propInfos = new[] { typeofJavaModuleAttribute.GetProperty("Jars") }; var propValues = new object[] { jarList.ToArray() }; @@ -694,12 +681,12 @@ void AddJavaModuleAttribute(ModuleBuilder mb) } list = UnicodeUtil.EscapeInvalidSurrogates(list); - var cab = new CustomAttributeBuilder(typeofJavaModuleAttribute.GetConstructor([Context.Resolver.ResolveCoreType(typeof(string).FullName).MakeArrayType().AsReflection()]), [list], propInfos, propValues); + var cab = Context.Resolver.Symbols.CreateCustomAttribute(typeofJavaModuleAttribute.GetConstructor([Context.Resolver.ResolveCoreType(typeof(string).FullName).MakeArrayType()]), [list], propInfos, propValues); mb.SetCustomAttribute(cab); } else { - var cab = new CustomAttributeBuilder(typeofJavaModuleAttribute.GetConstructor([]), [], propInfos, propValues); + var cab = Context.Resolver.Symbols.CreateCustomAttribute(typeofJavaModuleAttribute.GetConstructor([]), [], propInfos, propValues); mb.SetCustomAttribute(cab); } } @@ -777,7 +764,7 @@ void WriteExportMap() } } ms.Position = 0; - GetTypeWrapperFactory().ModuleBuilder.DefineManifestResource("ikvm.exports", ms, ResourceAttributes.Public); + GetTypeWrapperFactory().ModuleBuilder.DefineManifestResource("ikvm.exports", ms, System.Reflection.ResourceAttributes.Public); } void WriteResources() @@ -839,49 +826,49 @@ void WriteResources() name = Path.GetFileNameWithoutExtension(name) + "-" + moduleBuilder.ModuleVersionId.ToString("N") + Path.GetExtension(name); jarList.Add(name); - moduleBuilder.DefineManifestResource(name, mem, ResourceAttributes.Public); + moduleBuilder.DefineManifestResource(name, mem, System.Reflection.ResourceAttributes.Public); } } } - private static MethodAttributes MapMethodAccessModifiers(IKVM.Tools.Importer.MapXml.MapModifiers mod) + private static System.Reflection.MethodAttributes MapMethodAccessModifiers(IKVM.Tools.Importer.MapXml.MapModifiers mod) { const IKVM.Tools.Importer.MapXml.MapModifiers access = IKVM.Tools.Importer.MapXml.MapModifiers.Public | IKVM.Tools.Importer.MapXml.MapModifiers.Protected | IKVM.Tools.Importer.MapXml.MapModifiers.Private; switch (mod & access) { case IKVM.Tools.Importer.MapXml.MapModifiers.Public: - return MethodAttributes.Public; + return System.Reflection.MethodAttributes.Public; case IKVM.Tools.Importer.MapXml.MapModifiers.Protected: - return MethodAttributes.FamORAssem; + return System.Reflection.MethodAttributes.FamORAssem; case IKVM.Tools.Importer.MapXml.MapModifiers.Private: - return MethodAttributes.Private; + return System.Reflection.MethodAttributes.Private; default: - return MethodAttributes.Assembly; + return System.Reflection.MethodAttributes.Assembly; } } - private static FieldAttributes MapFieldAccessModifiers(IKVM.Tools.Importer.MapXml.MapModifiers mod) + private static System.Reflection.FieldAttributes MapFieldAccessModifiers(IKVM.Tools.Importer.MapXml.MapModifiers mod) { const IKVM.Tools.Importer.MapXml.MapModifiers access = IKVM.Tools.Importer.MapXml.MapModifiers.Public | IKVM.Tools.Importer.MapXml.MapModifiers.Protected | IKVM.Tools.Importer.MapXml.MapModifiers.Private; switch (mod & access) { case IKVM.Tools.Importer.MapXml.MapModifiers.Public: - return FieldAttributes.Public; + return System.Reflection.FieldAttributes.Public; case IKVM.Tools.Importer.MapXml.MapModifiers.Protected: - return FieldAttributes.FamORAssem; + return System.Reflection.FieldAttributes.FamORAssem; case IKVM.Tools.Importer.MapXml.MapModifiers.Private: - return FieldAttributes.Private; + return System.Reflection.FieldAttributes.Private; default: - return FieldAttributes.Assembly; + return System.Reflection.FieldAttributes.Assembly; } } private sealed class RemapperTypeWrapper : RuntimeJavaType { private ImportClassLoader classLoader; - private TypeBuilder typeBuilder; - private TypeBuilder helperTypeBuilder; - private Type shadowType; + private ITypeSymbolBuilder typeBuilder; + private ITypeSymbolBuilder helperTypeBuilder; + private ITypeSymbol shadowType; private IKVM.Tools.Importer.MapXml.Class classDef; private RuntimeJavaType baseTypeWrapper; private RuntimeJavaType[] interfaceWrappers; @@ -917,32 +904,32 @@ internal RemapperTypeWrapper(RuntimeContext context, ImportClassLoader classLoad this.baseTypeWrapper = GetBaseWrapper(context, c); classDef = c; bool baseIsSealed = false; - shadowType = context.StaticCompiler.Universe.GetType(c.Shadows, true); + shadowType = context.Resolver.ResolveType(context.StaticCompiler.Universe.GetType(c.Shadows, true)); classLoader.SetRemappedType(shadowType, this); - Type baseType = shadowType; - Type baseInterface = null; + var baseType = shadowType; + ITypeSymbol baseInterface = null; if (baseType.IsInterface) { baseInterface = baseType; } - TypeAttributes attrs = TypeAttributes.Public; + var attrs = System.Reflection.TypeAttributes.Public; if ((c.Modifiers & IKVM.Tools.Importer.MapXml.MapModifiers.Interface) == 0) { - attrs |= TypeAttributes.Class; + attrs |= System.Reflection.TypeAttributes.Class; if (baseType.IsSealed) { baseIsSealed = true; - attrs |= TypeAttributes.Abstract | TypeAttributes.Sealed; + attrs |= System.Reflection.TypeAttributes.Abstract | System.Reflection.TypeAttributes.Sealed; } } else { - attrs |= TypeAttributes.Interface | TypeAttributes.Abstract; + attrs |= System.Reflection.TypeAttributes.Interface | System.Reflection.TypeAttributes.Abstract; baseType = null; } if ((c.Modifiers & IKVM.Tools.Importer.MapXml.MapModifiers.Abstract) != 0) { - attrs |= TypeAttributes.Abstract; + attrs |= System.Reflection.TypeAttributes.Abstract; } string name = c.Name.Replace('/', '.'); typeBuilder = classLoader.GetTypeWrapperFactory().ModuleBuilder.DefineType(name, attrs, baseIsSealed ? Context.Types.Object : baseType); @@ -1068,7 +1055,7 @@ internal RemappedMethodBaseWrapper(RemapperTypeWrapper typeWrapper, string name, } - internal abstract MethodBase DoLink(); + internal abstract IMethodBaseSymbol DoLink(); internal abstract void Finish(); @@ -1078,7 +1065,7 @@ sealed class RemappedConstructorWrapper : RemappedMethodBaseWrapper { private IKVM.Tools.Importer.MapXml.Constructor m; - private MethodBuilder mbHelper; + private IMethodSymbolBuilder mbHelper; internal RemappedConstructorWrapper(RemapperTypeWrapper typeWrapper, IKVM.Tools.Importer.MapXml.Constructor m) : base(typeWrapper, "", m.Sig, (Modifiers)m.Modifiers) @@ -1088,32 +1075,32 @@ internal RemappedConstructorWrapper(RemapperTypeWrapper typeWrapper, IKVM.Tools. internal override void EmitCall(CodeEmitter ilgen) { - ilgen.Emit(OpCodes.Call, GetMethod()); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, GetMethod()); } internal override void EmitNewobj(CodeEmitter ilgen) { if (mbHelper != null) { - ilgen.Emit(OpCodes.Call, mbHelper); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, mbHelper); } else { - ilgen.Emit(OpCodes.Newobj, GetMethod()); + ilgen.Emit(System.Reflection.Emit.OpCodes.Newobj, GetMethod()); } } - internal override MethodBase DoLink() + internal override IMethodBaseSymbol DoLink() { - MethodAttributes attr = MapMethodAccessModifiers(m.Modifiers); - RemapperTypeWrapper typeWrapper = (RemapperTypeWrapper)DeclaringType; - Type[] paramTypes = typeWrapper.ClassLoader.ArgTypeListFromSig(m.Sig); + var attr = MapMethodAccessModifiers(m.Modifiers); + var typeWrapper = (RemapperTypeWrapper)DeclaringType; + var paramTypes = typeWrapper.ClassLoader.ArgTypeListFromSig(m.Sig); - MethodBuilder cbCore = null; + IConstructorSymbolBuilder cbCore = null; if (typeWrapper.shadowType.IsSealed) { - mbHelper = typeWrapper.typeBuilder.DefineMethod("newhelper", attr | MethodAttributes.Static, CallingConventions.Standard, typeWrapper.shadowType, paramTypes); + mbHelper = typeWrapper.typeBuilder.DefineMethod("newhelper", attr | System.Reflection.MethodAttributes.Static, System.Reflection.CallingConventions.Standard, typeWrapper.shadowType, paramTypes); if (m.Attributes != null) { foreach (IKVM.Tools.Importer.MapXml.Attribute custattr in m.Attributes) @@ -1121,6 +1108,7 @@ internal override MethodBase DoLink() DeclaringType.Context.AttributeHelper.SetCustomAttribute(DeclaringType.ClassLoader, mbHelper, custattr); } } + SetParameters(DeclaringType.ClassLoader, mbHelper, m.Parameters); DeclaringType.Context.AttributeHelper.SetModifiers(mbHelper, (Modifiers)m.Modifiers, false); DeclaringType.Context.AttributeHelper.SetNameSig(mbHelper, "", m.Sig); @@ -1136,9 +1124,11 @@ internal override MethodBase DoLink() DeclaringType.Context.AttributeHelper.SetCustomAttribute(DeclaringType.ClassLoader, cbCore, custattr); } } + SetParameters(DeclaringType.ClassLoader, cbCore, m.Parameters); AddDeclaredExceptions(DeclaringType.Context, cbCore, m.Throws); } + return cbCore; } @@ -1146,9 +1136,9 @@ internal override void Finish() { // TODO we should insert method tracing (if enabled) - Type[] paramTypes = this.GetParametersForDefineMethod(); + var paramTypes = this.GetParametersForDefineMethod(); - MethodBuilder cbCore = GetMethod() as MethodBuilder; + var cbCore = GetMethod() as IMethodSymbolBuilder; if (cbCore != null) { @@ -1161,7 +1151,7 @@ internal override void Finish() } else { - ilgen.Emit(OpCodes.Ldarg_0); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); for (int i = 0; i < paramTypes.Length; i++) { ilgen.EmitLdarg(i + 1); @@ -1172,15 +1162,15 @@ internal override void Finish() } else { - ConstructorInfo baseCon = DeclaringType.TypeAsTBD.GetConstructor(paramTypes); + var baseCon = DeclaringType.TypeAsTBD.GetConstructor(paramTypes); if (baseCon == null) { // TODO better error handling throw new InvalidOperationException("base class constructor not found: " + DeclaringType.Name + "." + m.Sig); } - ilgen.Emit(OpCodes.Call, baseCon); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, baseCon); } - ilgen.Emit(OpCodes.Ret); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ret); } ilgen.DoEmit(); if (this.DeclaringType.ClassLoader.EmitStackTraceInfo) @@ -1191,7 +1181,7 @@ internal override void Finish() if (mbHelper != null) { - CodeEmitter ilgen = DeclaringType.Context.CodeEmitterFactory.Create(mbHelper); + var ilgen = DeclaringType.Context.CodeEmitterFactory.Create(mbHelper); if (m.Redirect != null) { m.Redirect.Emit(DeclaringType.ClassLoader, ilgen); @@ -1207,7 +1197,7 @@ internal override void Finish() } else { - ConstructorInfo baseCon = DeclaringType.TypeAsTBD.GetConstructor(paramTypes); + var baseCon = DeclaringType.TypeAsTBD.GetConstructor(paramTypes); if (baseCon == null) { // TODO better error handling @@ -1217,8 +1207,8 @@ internal override void Finish() { ilgen.EmitLdarg(i); } - ilgen.Emit(OpCodes.Newobj, baseCon); - ilgen.Emit(OpCodes.Ret); + ilgen.Emit(System.Reflection.Emit.OpCodes.Newobj, baseCon); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ret); } ilgen.DoEmit(); if (this.DeclaringType.ClassLoader.EmitStackTraceInfo) @@ -1234,7 +1224,7 @@ sealed class RemappedMethodWrapper : RemappedMethodBaseWrapper private IKVM.Tools.Importer.MapXml.Method m; private IKVM.Tools.Importer.MapXml.Root map; - private MethodBuilder mbHelper; + private IMethodSymbolBuilder mbHelper; private List overriders = new List(); private bool inherited; @@ -1265,7 +1255,7 @@ internal override void EmitCall(CodeEmitter ilgen) } else { - ilgen.Emit(OpCodes.Call, (MethodInfo)GetMethod()); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, (IMethodSymbol)GetMethod()); } } @@ -1278,17 +1268,17 @@ private void EmitCallvirtImpl(CodeEmitter ilgen, bool cloneOrFinalizeHack) { if (mbHelper != null && !cloneOrFinalizeHack) { - ilgen.Emit(OpCodes.Call, mbHelper); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, mbHelper); } else { - ilgen.Emit(OpCodes.Callvirt, (MethodInfo)GetMethod()); + ilgen.Emit(System.Reflection.Emit.OpCodes.Callvirt, (IMethodSymbol)GetMethod()); } } - internal override MethodBase DoLink() + internal override IMethodBaseSymbol DoLink() { - RemapperTypeWrapper typeWrapper = (RemapperTypeWrapper)DeclaringType; + var typeWrapper = (RemapperTypeWrapper)DeclaringType; if (typeWrapper.IsInterface) { @@ -1296,11 +1286,13 @@ internal override MethodBase DoLink() { throw new InvalidOperationException(typeWrapper.Name + "." + m.Name + m.Sig); } - MethodInfo interfaceMethod = typeWrapper.shadowType.GetMethod(m.Override.Name, typeWrapper.ClassLoader.ArgTypeListFromSig(m.Sig)); + + var interfaceMethod = typeWrapper.shadowType.GetMethod(m.Override.Name, typeWrapper.ClassLoader.ArgTypeListFromSig(m.Sig)); if (interfaceMethod == null) { throw new InvalidOperationException(typeWrapper.Name + "." + m.Name + m.Sig); } + // if any of the remapped types has a body for this interface method, we need a helper method // to special invocation through this interface for that type List specialCases = null; @@ -1336,17 +1328,17 @@ internal override MethodBase DoLink() } } DeclaringType.Context.AttributeHelper.SetRemappedInterfaceMethod(typeWrapper.typeBuilder, m.Name, m.Override.Name, throws); - MethodBuilder helper = null; + IMethodSymbolBuilder helper = null; if (specialCases != null) { CodeEmitter ilgen; - Type[] argTypes = ArrayUtil.Concat(typeWrapper.shadowType, typeWrapper.ClassLoader.ArgTypeListFromSig(m.Sig)); + var argTypes = ArrayUtil.Concat(typeWrapper.shadowType, typeWrapper.ClassLoader.ArgTypeListFromSig(m.Sig)); if (typeWrapper.helperTypeBuilder == null) { - typeWrapper.helperTypeBuilder = typeWrapper.typeBuilder.DefineNestedType("__Helper", TypeAttributes.NestedPublic | TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.Abstract); + typeWrapper.helperTypeBuilder = typeWrapper.typeBuilder.DefineNestedType("__Helper", System.Reflection.TypeAttributes.NestedPublic | System.Reflection.TypeAttributes.Class | System.Reflection.TypeAttributes.Sealed | System.Reflection.TypeAttributes.Abstract); DeclaringType.Context.AttributeHelper.HideFromJava(typeWrapper.helperTypeBuilder); } - helper = typeWrapper.helperTypeBuilder.DefineMethod(m.Name, MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static, typeWrapper.ClassLoader.RetTypeWrapperFromSig(m.Sig, LoadMode.LoadOrThrow).TypeAsSignatureType, argTypes); + helper = typeWrapper.helperTypeBuilder.DefineMethod(m.Name, System.Reflection.MethodAttributes.HideBySig | System.Reflection.MethodAttributes.Public | System.Reflection.MethodAttributes.Static, typeWrapper.ClassLoader.RetTypeWrapperFromSig(m.Sig, LoadMode.LoadOrThrow).TypeAsSignatureType, argTypes); if (m.Attributes != null) { foreach (IKVM.Tools.Importer.MapXml.Attribute custattr in m.Attributes) @@ -1359,9 +1351,9 @@ internal override MethodBase DoLink() foreach (IKVM.Tools.Importer.MapXml.Class c in specialCases) { var tw = typeWrapper.ClassLoader.LoadClassByName(c.Name); - ilgen.Emit(OpCodes.Ldarg_0); - ilgen.Emit(OpCodes.Isinst, tw.TypeAsTBD); - ilgen.Emit(OpCodes.Dup); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); + ilgen.Emit(System.Reflection.Emit.OpCodes.Isinst, tw.TypeAsTBD); + ilgen.Emit(System.Reflection.Emit.OpCodes.Dup); CodeEmitterLabel label = ilgen.DefineLabel(); ilgen.EmitBrfalse(label); for (int i = 1; i < argTypes.Length; i++) @@ -1371,16 +1363,16 @@ internal override MethodBase DoLink() var mw = tw.GetMethodWrapper(m.Name, m.Sig, false); mw.Link(); mw.EmitCallvirt(ilgen); - ilgen.Emit(OpCodes.Ret); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ret); ilgen.MarkLabel(label); - ilgen.Emit(OpCodes.Pop); + ilgen.Emit(System.Reflection.Emit.OpCodes.Pop); } for (int i = 0; i < argTypes.Length; i++) { ilgen.EmitLdarg(i); } - ilgen.Emit(OpCodes.Callvirt, interfaceMethod); - ilgen.Emit(OpCodes.Ret); + ilgen.Emit(System.Reflection.Emit.OpCodes.Callvirt, interfaceMethod); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ret); ilgen.DoEmit(); } mbHelper = helper; @@ -1388,9 +1380,9 @@ internal override MethodBase DoLink() } else { - MethodBuilder mbCore = null; - Type[] paramTypes = typeWrapper.ClassLoader.ArgTypeListFromSig(m.Sig); - Type retType = typeWrapper.ClassLoader.RetTypeWrapperFromSig(m.Sig, LoadMode.LoadOrThrow).TypeAsSignatureType; + IMethodSymbolBuilder mbCore = null; + var paramTypes = typeWrapper.ClassLoader.ArgTypeListFromSig(m.Sig); + var retType = typeWrapper.ClassLoader.RetTypeWrapperFromSig(m.Sig, LoadMode.LoadOrThrow).TypeAsSignatureType; if (typeWrapper.shadowType.IsSealed && (m.Modifiers & IKVM.Tools.Importer.MapXml.MapModifiers.Static) == 0) { @@ -1412,33 +1404,35 @@ internal override MethodBase DoLink() } else { - MethodInfo overrideMethod = null; - MethodAttributes attr = m.MethodAttributes | MapMethodAccessModifiers(m.Modifiers) | MethodAttributes.HideBySig; + IMethodSymbol overrideMethod = null; + var attr = m.MethodAttributes | MapMethodAccessModifiers(m.Modifiers) | System.Reflection.MethodAttributes.HideBySig; if ((m.Modifiers & IKVM.Tools.Importer.MapXml.MapModifiers.Static) != 0) { - attr |= MethodAttributes.Static; + attr |= System.Reflection.MethodAttributes.Static; } else if ((m.Modifiers & IKVM.Tools.Importer.MapXml.MapModifiers.Private) == 0 && (m.Modifiers & IKVM.Tools.Importer.MapXml.MapModifiers.Final) == 0) { - attr |= MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.CheckAccessOnOverride; + attr |= System.Reflection.MethodAttributes.Virtual | System.Reflection.MethodAttributes.NewSlot | System.Reflection.MethodAttributes.CheckAccessOnOverride; + if (!typeWrapper.shadowType.IsSealed) { - MethodInfo autoOverride = typeWrapper.shadowType.GetMethod(m.Name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, paramTypes, null); + var autoOverride = typeWrapper.shadowType.GetMethod(m.Name, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic, paramTypes); if (autoOverride != null && autoOverride.ReturnType == retType && !autoOverride.IsFinal) { // the method we're processing is overriding a method in its shadowType (which is the actual base type) - attr &= ~MethodAttributes.NewSlot; + attr &= ~System.Reflection.MethodAttributes.NewSlot; } } + if (typeWrapper.BaseTypeWrapper != null) { - RemappedMethodWrapper baseMethod = typeWrapper.BaseTypeWrapper.GetMethodWrapper(m.Name, m.Sig, true) as RemappedMethodWrapper; + var baseMethod = typeWrapper.BaseTypeWrapper.GetMethodWrapper(m.Name, m.Sig, true) as RemappedMethodWrapper; if (baseMethod != null) { baseMethod.overriders.Add(typeWrapper); if (baseMethod.m.Override != null) { - overrideMethod = typeWrapper.BaseTypeWrapper.TypeAsTBD.GetMethod(baseMethod.m.Override.Name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, paramTypes, null); + overrideMethod = typeWrapper.BaseTypeWrapper.TypeAsTBD.GetMethod(baseMethod.m.Override.Name, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic, paramTypes); if (overrideMethod == null) { throw new InvalidOperationException(); @@ -1470,15 +1464,15 @@ internal override MethodBase DoLink() if ((m.Modifiers & IKVM.Tools.Importer.MapXml.MapModifiers.Static) == 0 && !IsHideFromJava(m)) { // instance methods must have an instancehelper method - MethodAttributes attr = MapMethodAccessModifiers(m.Modifiers) | MethodAttributes.HideBySig | MethodAttributes.Static; + var attr = MapMethodAccessModifiers(m.Modifiers) | System.Reflection.MethodAttributes.HideBySig | System.Reflection.MethodAttributes.Static; // NOTE instancehelpers for protected methods are made internal // and special cased in DotNetTypeWrapper.LazyPublishMembers if ((m.Modifiers & IKVM.Tools.Importer.MapXml.MapModifiers.Protected) != 0) { - attr &= ~MethodAttributes.MemberAccessMask; - attr |= MethodAttributes.Assembly; + attr &= ~System.Reflection.MethodAttributes.MemberAccessMask; + attr |= System.Reflection.MethodAttributes.Assembly; } - mbHelper = typeWrapper.typeBuilder.DefineMethod("instancehelper_" + m.Name, attr, CallingConventions.Standard, retType, ArrayUtil.Concat(typeWrapper.shadowType, paramTypes)); + mbHelper = typeWrapper.typeBuilder.DefineMethod("instancehelper_" + m.Name, attr, System.Reflection.CallingConventions.Standard, retType, ArrayUtil.Concat(typeWrapper.shadowType, paramTypes)); if (m.Attributes != null) { foreach (IKVM.Tools.Importer.MapXml.Attribute custattr in m.Attributes) @@ -1503,10 +1497,11 @@ internal override MethodBase DoLink() { DeclaringType.Context.AttributeHelper.SetEditorBrowsableNever(mbHelper); } + DeclaringType.Context.AttributeHelper.SetModifiers(mbHelper, (Modifiers)m.Modifiers, false); DeclaringType.Context.AttributeHelper.SetNameSig(mbHelper, m.Name, m.Sig); AddDeclaredExceptions(DeclaringType.Context, mbHelper, m.Throws); - mbHelper.SetCustomAttribute(new CustomAttributeBuilder(DeclaringType.Context.Resolver.ResolveCoreType(typeof(ObsoleteAttribute).FullName).AsReflection().GetConstructor([DeclaringType.Context.Types.String]), ["This function will be removed from future versions. Please use extension methods from ikvm.extensions namespace instead."])); + mbHelper.SetCustomAttribute(DeclaringType.Context.Resolver.Symbols.CreateCustomAttribute(DeclaringType.Context.Resolver.ResolveCoreType(typeof(ObsoleteAttribute).FullName).GetConstructor([DeclaringType.Context.Types.String]), ["This function will be removed from future versions. Please use extension methods from ikvm.extensions namespace instead."])); } return mbCore; } @@ -1530,23 +1525,22 @@ private static bool IsHideFromJava(IKVM.Tools.Importer.MapXml.Method m) internal override void Finish() { // TODO we should insert method tracing (if enabled) - Type[] paramTypes = this.GetParametersForDefineMethod(); + var paramTypes = this.GetParametersForDefineMethod(); - MethodBuilder mbCore = GetMethod() as MethodBuilder; + var mbCore = GetMethod() as IMethodSymbolBuilder; // NOTE sealed types don't have instance methods (only instancehelpers) if (mbCore != null) { - CodeEmitter ilgen = DeclaringType.Context.CodeEmitterFactory.Create(mbCore); - MethodInfo baseMethod = null; + var ilgen = DeclaringType.Context.CodeEmitterFactory.Create(mbCore); + IMethodSymbol baseMethod = null; if (m.Override != null) { - baseMethod = DeclaringType.TypeAsTBD.GetMethod(m.Override.Name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, paramTypes, null); + baseMethod = DeclaringType.TypeAsTBD.GetMethod(m.Override.Name, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic, paramTypes); if (baseMethod == null) - { throw new InvalidOperationException(); - } - ((TypeBuilder)DeclaringType.TypeAsBaseType).DefineMethodOverride(mbCore, baseMethod); + + ((ITypeSymbolBuilder)DeclaringType.TypeAsBaseType).DefineMethodOverride(mbCore, baseMethod); } // TODO we need to support ghost (and other funky?) parameter types if (m.Body != null) @@ -1571,7 +1565,7 @@ internal override void Finish() if ((m.Modifiers & IKVM.Tools.Importer.MapXml.MapModifiers.Static) == 0) { thisOffset = 1; - ilgen.Emit(OpCodes.Ldarg_0); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); } for (int i = 0; i < paramTypes.Length; i++) { @@ -1587,10 +1581,10 @@ internal override void Finish() { throw new InvalidOperationException(DeclaringType.Name + "." + m.Name + m.Sig); } - ilgen.Emit(OpCodes.Call, baseMethod); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, baseMethod); } this.ReturnType.EmitConvStackTypeToSignatureType(ilgen, null); - ilgen.Emit(OpCodes.Ret); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ret); } ilgen.DoEmit(); if (this.DeclaringType.ClassLoader.EmitStackTraceInfo) @@ -1613,7 +1607,7 @@ internal override void Finish() } else if (!m.NoNullCheck) { - ilgen.Emit(OpCodes.Ldarg_0); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); ilgen.EmitNullCheck(); } if (mbCore != null && @@ -1621,20 +1615,20 @@ internal override void Finish() (m.Modifiers & IKVM.Tools.Importer.MapXml.MapModifiers.Private) == 0 && (m.Modifiers & IKVM.Tools.Importer.MapXml.MapModifiers.Final) == 0) { // TODO we should have a way to supress this for overridden methods - ilgen.Emit(OpCodes.Ldarg_0); - ilgen.Emit(OpCodes.Isinst, DeclaringType.TypeAsBaseType); - ilgen.Emit(OpCodes.Dup); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); + ilgen.Emit(System.Reflection.Emit.OpCodes.Isinst, DeclaringType.TypeAsBaseType); + ilgen.Emit(System.Reflection.Emit.OpCodes.Dup); CodeEmitterLabel skip = ilgen.DefineLabel(); ilgen.EmitBrfalse(skip); for (int i = 0; i < paramTypes.Length; i++) { ilgen.EmitLdarg(i + 1); } - ilgen.Emit(OpCodes.Callvirt, mbCore); + ilgen.Emit(System.Reflection.Emit.OpCodes.Callvirt, mbCore); this.ReturnType.EmitConvStackTypeToSignatureType(ilgen, null); - ilgen.Emit(OpCodes.Ret); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ret); ilgen.MarkLabel(skip); - ilgen.Emit(OpCodes.Pop); + ilgen.Emit(System.Reflection.Emit.OpCodes.Pop); } foreach (RemapperTypeWrapper overrider in overriders) { @@ -1646,9 +1640,9 @@ internal override void Finish() } else { - ilgen.Emit(OpCodes.Ldarg_0); - ilgen.Emit(OpCodes.Isinst, overrider.TypeAsTBD); - ilgen.Emit(OpCodes.Dup); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); + ilgen.Emit(System.Reflection.Emit.OpCodes.Isinst, overrider.TypeAsTBD); + ilgen.Emit(System.Reflection.Emit.OpCodes.Dup); CodeEmitterLabel skip = ilgen.DefineLabel(); ilgen.EmitBrfalse(skip); for (int i = 0; i < paramTypes.Length; i++) @@ -1658,9 +1652,9 @@ internal override void Finish() mw.Link(); mw.EmitCallvirtImpl(ilgen, false); this.ReturnType.EmitConvStackTypeToSignatureType(ilgen, null); - ilgen.Emit(OpCodes.Ret); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ret); ilgen.MarkLabel(skip); - ilgen.Emit(OpCodes.Pop); + ilgen.Emit(System.Reflection.Emit.OpCodes.Pop); } } if (m.Body != null || m.AlternateBody != null) @@ -1694,11 +1688,11 @@ internal override void Finish() } else if (m.Override != null) { - var baseMethod = shadowType.GetMethod(m.Override.Name, BindingFlags.Instance | BindingFlags.Public, null, paramTypes, null); + var baseMethod = shadowType.GetMethod(m.Override.Name, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public, paramTypes); if (baseMethod == null) throw new InvalidOperationException(DeclaringType.Name + "." + m.Name + m.Sig); - ilgen.Emit(OpCodes.Callvirt, baseMethod); + ilgen.Emit(System.Reflection.Emit.OpCodes.Callvirt, baseMethod); } else { @@ -1706,15 +1700,15 @@ internal override void Finish() if (baseMethod == null || baseMethod.m.Override == null) throw new InvalidOperationException(DeclaringType.Name + "." + m.Name + m.Sig); - var overrideMethod = shadowType.GetMethod(baseMethod.m.Override.Name, BindingFlags.Instance | BindingFlags.Public, null, paramTypes, null); + var overrideMethod = shadowType.GetMethod(baseMethod.m.Override.Name, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public, paramTypes); if (overrideMethod == null) throw new InvalidOperationException(DeclaringType.Name + "." + m.Name + m.Sig); - ilgen.Emit(OpCodes.Callvirt, overrideMethod); + ilgen.Emit(System.Reflection.Emit.OpCodes.Callvirt, overrideMethod); } ReturnType.EmitConvStackTypeToSignatureType(ilgen, null); - ilgen.Emit(OpCodes.Ret); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ret); } ilgen.DoEmit(); @@ -1727,7 +1721,7 @@ internal override void Finish() if (m.NonVirtualAlternateBody != null || (m.Override != null && overriders.Count > 0)) { var tw = (RemapperTypeWrapper)DeclaringType; - var mb = tw.typeBuilder.DefineMethod("nonvirtualhelper/" + Name, MethodAttributes.Private | MethodAttributes.Static, ReturnTypeForDefineMethod, ArrayUtil.Concat(tw.TypeAsSignatureType, GetParametersForDefineMethod())); + var mb = tw.typeBuilder.DefineMethod("nonvirtualhelper/" + Name, System.Reflection.MethodAttributes.Private | System.Reflection.MethodAttributes.Static, ReturnTypeForDefineMethod, ArrayUtil.Concat(tw.TypeAsSignatureType, GetParametersForDefineMethod())); // apply custom attributes from map XML if (m.Attributes != null) @@ -1745,23 +1739,23 @@ internal override void Finish() else { var shadowType = ((RemapperTypeWrapper)DeclaringType).shadowType; - var baseMethod = shadowType.GetMethod(m.Override.Name, BindingFlags.Instance | BindingFlags.Public, null, paramTypes, null); + var baseMethod = shadowType.GetMethod(m.Override.Name, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public, paramTypes); if (baseMethod == null) throw new InvalidOperationException(DeclaringType.Name + "." + m.Name + m.Sig); - ilgen.Emit(OpCodes.Ldarg_0); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); for (int i = 0; i < paramTypes.Length; i++) ilgen.EmitLdarg(i + 1); - ilgen.Emit(OpCodes.Call, baseMethod); - ilgen.Emit(OpCodes.Ret); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, baseMethod); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ret); } ilgen.DoEmit(); } } - private void EmitRedirect(Type baseType, CodeEmitter ilgen) + private void EmitRedirect(ITypeSymbol baseType, CodeEmitter ilgen) { var redirName = m.Redirect.Name ?? m.Name; var redirSig = m.Redirect.Sig ?? m.Sig; @@ -1770,10 +1764,10 @@ private void EmitRedirect(Type baseType, CodeEmitter ilgen) // type specified, or class missing, assume loading .NET type if (m.Redirect.Type != null || m.Redirect.Class == null) { - var type = m.Redirect.Type != null ? DeclaringType.Context.StaticCompiler.Universe.GetType(m.Redirect.Type, true) : baseType; + var type = m.Redirect.Type != null ? DeclaringType.Context.Resolver.ResolveType(DeclaringType.Context.StaticCompiler.Universe.GetType(m.Redirect.Type, true)) : baseType; var redirParamTypes = classLoader.ArgTypeListFromSig(redirSig); var mi = type.GetMethod(m.Redirect.Name, redirParamTypes) ?? throw new InvalidOperationException(); - ilgen.Emit(OpCodes.Call, mi); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, mi); } else { @@ -1785,13 +1779,31 @@ private void EmitRedirect(Type baseType, CodeEmitter ilgen) } } - private static void SetParameters(RuntimeClassLoader loader, MethodBuilder mb, IKVM.Tools.Importer.MapXml.Parameter[] parameters) + static void SetParameters(RuntimeClassLoader loader, IConstructorSymbolBuilder mb, IKVM.Tools.Importer.MapXml.Parameter[] parameters) + { + if (parameters != null) + { + for (int i = 0; i < parameters.Length; i++) + { + var pb = mb.DefineParameter(i + 1, System.Reflection.ParameterAttributes.None, parameters[i].Name); + if (parameters[i].Attributes != null) + { + for (int j = 0; j < parameters[i].Attributes.Length; j++) + { + loader.Context.AttributeHelper.SetCustomAttribute(loader, pb, parameters[i].Attributes[j]); + } + } + } + } + } + + static void SetParameters(RuntimeClassLoader loader, IMethodSymbolBuilder mb, IKVM.Tools.Importer.MapXml.Parameter[] parameters) { if (parameters != null) { for (int i = 0; i < parameters.Length; i++) { - ParameterBuilder pb = mb.DefineParameter(i + 1, ParameterAttributes.None, parameters[i].Name); + var pb = mb.DefineParameter(i + 1, System.Reflection.ParameterAttributes.None, parameters[i].Name); if (parameters[i].Attributes != null) { for (int j = 0; j < parameters[i].Attributes.Length; j++) @@ -1828,20 +1840,21 @@ internal void Process2ndPassStep2(IKVM.Tools.Importer.MapXml.Root map) foreach (IKVM.Tools.Importer.MapXml.Field f in c.Fields) { { - FieldAttributes attr = MapFieldAccessModifiers(f.Modifiers); + var attr = MapFieldAccessModifiers(f.Modifiers); if (f.Constant != null) { - attr |= FieldAttributes.Literal; + attr |= System.Reflection.FieldAttributes.Literal; } else if ((f.Modifiers & IKVM.Tools.Importer.MapXml.MapModifiers.Final) != 0) { - attr |= FieldAttributes.InitOnly; + attr |= System.Reflection.FieldAttributes.InitOnly; } if ((f.Modifiers & IKVM.Tools.Importer.MapXml.MapModifiers.Static) != 0) { - attr |= FieldAttributes.Static; + attr |= System.Reflection.FieldAttributes.Static; } - FieldBuilder fb = tb.DefineField(f.Name, ClassLoader.FieldTypeWrapperFromSig(f.Sig, LoadMode.LoadOrThrow).TypeAsSignatureType, attr); + + var fb = tb.DefineField(f.Name, ClassLoader.FieldTypeWrapperFromSig(f.Sig, LoadMode.LoadOrThrow).TypeAsSignatureType, attr); if (f.Attributes != null) { foreach (IKVM.Tools.Importer.MapXml.Attribute custattr in f.Attributes) @@ -1849,6 +1862,7 @@ internal void Process2ndPassStep2(IKVM.Tools.Importer.MapXml.Root map) Context.AttributeHelper.SetCustomAttribute(classLoader, fb, custattr); } } + object constant; if (f.Constant != null) { @@ -1891,8 +1905,8 @@ internal void Process4thPass(ICollection remappedTypes) if (classDef.Clinit != null) { - MethodBuilder cb = ReflectUtil.DefineTypeInitializer(typeBuilder, classLoader); - CodeEmitter ilgen = Context.CodeEmitterFactory.Create(cb); + var cb = ReflectUtil.DefineTypeInitializer(typeBuilder, classLoader); + var ilgen = Context.CodeEmitterFactory.Create(cb); // TODO emit code to make sure super class is initialized classDef.Clinit.Body.Emit(classLoader, ilgen); ilgen.DoEmit(); @@ -1916,57 +1930,56 @@ internal void Process4thPass(ICollection remappedTypes) // For all inherited methods, we emit a method that hides the inherited method and // annotate it with EditorBrowsableAttribute(EditorBrowsableState.Never) to make // sure the inherited methods don't show up in Intellisense. - var methods = new Dictionary(); + var methods = new Dictionary(); foreach (var mw in GetMethods()) { - var mb = mw.GetMethod() as MethodBuilder; + var mb = mw.GetMethod() as IMethodSymbolBuilder; if (mb != null) methods.Add(MakeMethodKey(mb), mb); } - foreach (var mi in typeBuilder.BaseType.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.FlattenHierarchy)) + foreach (var mi in typeBuilder.BaseType.GetMethods(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.FlattenHierarchy)) { - string key = MakeMethodKey(mi); + var key = MakeMethodKey(mi); if (!methods.ContainsKey(key)) { - ParameterInfo[] paramInfo = mi.GetParameters(); - Type[] paramTypes = new Type[paramInfo.Length]; + var paramInfo = mi.GetParameters(); + var paramTypes = new ITypeSymbol[paramInfo.Length]; for (int i = 0; i < paramInfo.Length; i++) - { paramTypes[i] = paramInfo[i].ParameterType; - } - MethodBuilder mb = typeBuilder.DefineMethod(mi.Name, mi.Attributes & (MethodAttributes.MemberAccessMask | MethodAttributes.SpecialName | MethodAttributes.Static), mi.ReturnType, paramTypes); + + var mb = typeBuilder.DefineMethod(mi.Name, mi.Attributes & (System.Reflection.MethodAttributes.MemberAccessMask | System.Reflection.MethodAttributes.SpecialName | System.Reflection.MethodAttributes.Static), mi.ReturnType, paramTypes); Context.AttributeHelper.HideFromJava(mb); Context.AttributeHelper.SetEditorBrowsableNever(mb); - CodeEmitter ilgen = Context.CodeEmitterFactory.Create(mb); + + var ilgen = Context.CodeEmitterFactory.Create(mb); for (int i = 0; i < paramTypes.Length; i++) - { ilgen.EmitLdarg(i); - } + if (!mi.IsStatic) { ilgen.EmitLdarg(paramTypes.Length); - ilgen.Emit(OpCodes.Callvirt, mi); + ilgen.Emit(System.Reflection.Emit.OpCodes.Callvirt, mi); } else { - ilgen.Emit(OpCodes.Call, mi); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, mi); } - ilgen.Emit(OpCodes.Ret); + + ilgen.Emit(System.Reflection.Emit.OpCodes.Ret); ilgen.DoEmit(); methods[key] = mb; } } - foreach (var pi in typeBuilder.BaseType.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static)) + foreach (var pi in typeBuilder.BaseType.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Static)) { - ParameterInfo[] paramInfo = pi.GetIndexParameters(); - Type[] paramTypes = new Type[paramInfo.Length]; + var paramInfo = pi.GetIndexParameters(); + var paramTypes = new ITypeSymbol[paramInfo.Length]; for (int i = 0; i < paramInfo.Length; i++) - { paramTypes[i] = paramInfo[i].ParameterType; - } - PropertyBuilder pb = typeBuilder.DefineProperty(pi.Name, PropertyAttributes.None, pi.PropertyType, paramTypes); + + var pb = typeBuilder.DefineProperty(pi.Name, System.Reflection.PropertyAttributes.None, pi.PropertyType, paramTypes); if (pi.GetGetMethod() != null) { pb.SetGetMethod(methods[MakeMethodKey(pi.GetGetMethod())]); @@ -1979,17 +1992,17 @@ internal void Process4thPass(ICollection remappedTypes) } } - typeBuilder.CreateType(); + typeBuilder.Complete(); if (helperTypeBuilder != null) - helperTypeBuilder.CreateType(); + helperTypeBuilder.Complete(); } - private static string MakeMethodKey(MethodInfo method) + private static string MakeMethodKey(IMethodSymbol method) { var sb = new StringBuilder(); sb.Append(method.ReturnType.AssemblyQualifiedName).Append(":").Append(method.Name); var paramInfo = method.GetParameters(); - var paramTypes = new Type[paramInfo.Length]; + var paramTypes = new ITypeSymbol[paramInfo.Length]; for (int i = 0; i < paramInfo.Length; i++) { paramTypes[i] = paramInfo[i].ParameterType; @@ -2005,28 +2018,28 @@ private void CreateShadowInstanceOf(ICollection remappedTyp if (typeBuilder.IsInterface) return; - MethodAttributes attr = MethodAttributes.SpecialName | MethodAttributes.Public | MethodAttributes.Static; - MethodBuilder mb = typeBuilder.DefineMethod("__", attr, Context.Types.Boolean, new Type[] { Context.Types.Object }); + var attr = System.Reflection.MethodAttributes.SpecialName | System.Reflection.MethodAttributes.Public | System.Reflection.MethodAttributes.Static; + var mb = typeBuilder.DefineMethod("__", attr, Context.Types.Boolean, new[] { Context.Types.Object }); Context.AttributeHelper.HideFromJava(mb); Context.AttributeHelper.SetEditorBrowsableNever(mb); - CodeEmitter ilgen = Context.CodeEmitterFactory.Create(mb); + var ilgen = Context.CodeEmitterFactory.Create(mb); - ilgen.Emit(OpCodes.Ldarg_0); - ilgen.Emit(OpCodes.Isinst, shadowType); - CodeEmitterLabel retFalse = ilgen.DefineLabel(); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); + ilgen.Emit(System.Reflection.Emit.OpCodes.Isinst, shadowType); + var retFalse = ilgen.DefineLabel(); ilgen.EmitBrfalse(retFalse); if (!shadowType.IsSealed) { - ilgen.Emit(OpCodes.Ldarg_0); - ilgen.Emit(OpCodes.Isinst, typeBuilder); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); + ilgen.Emit(System.Reflection.Emit.OpCodes.Isinst, typeBuilder); ilgen.EmitBrtrue(retFalse); } if (shadowType == Context.Types.Object) { - ilgen.Emit(OpCodes.Ldarg_0); - ilgen.Emit(OpCodes.Isinst, Context.Types.Array); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); + ilgen.Emit(System.Reflection.Emit.OpCodes.Isinst, Context.Types.Array); ilgen.EmitBrtrue(retFalse); } @@ -2034,17 +2047,17 @@ private void CreateShadowInstanceOf(ICollection remappedTyp { if (!r.shadowType.IsInterface && r.shadowType.IsSubclassOf(shadowType)) { - ilgen.Emit(OpCodes.Ldarg_0); - ilgen.Emit(OpCodes.Isinst, r.shadowType); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); + ilgen.Emit(System.Reflection.Emit.OpCodes.Isinst, r.shadowType); ilgen.EmitBrtrue(retFalse); } } - ilgen.Emit(OpCodes.Ldc_I4_1); - ilgen.Emit(OpCodes.Ret); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_1); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ret); ilgen.MarkLabel(retFalse); - ilgen.Emit(OpCodes.Ldc_I4_0); - ilgen.Emit(OpCodes.Ret); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_0); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ret); ilgen.DoEmit(); } @@ -2056,27 +2069,28 @@ private void CreateShadowCheckCast(ICollection remappedType { return; } - MethodAttributes attr = MethodAttributes.SpecialName | MethodAttributes.Public | MethodAttributes.Static; - MethodBuilder mb = typeBuilder.DefineMethod("__", attr, shadowType, new Type[] { Context.Types.Object }); + + var attr = System.Reflection.MethodAttributes.SpecialName | System.Reflection.MethodAttributes.Public | System.Reflection.MethodAttributes.Static; + var mb = typeBuilder.DefineMethod("__", attr, shadowType, [Context.Types.Object]); Context.AttributeHelper.HideFromJava(mb); Context.AttributeHelper.SetEditorBrowsableNever(mb); - CodeEmitter ilgen = Context.CodeEmitterFactory.Create(mb); + var ilgen = Context.CodeEmitterFactory.Create(mb); - CodeEmitterLabel fail = ilgen.DefineLabel(); + var fail = ilgen.DefineLabel(); bool hasfail = false; if (!shadowType.IsSealed) { - ilgen.Emit(OpCodes.Ldarg_0); - ilgen.Emit(OpCodes.Isinst, typeBuilder); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); + ilgen.Emit(System.Reflection.Emit.OpCodes.Isinst, typeBuilder); ilgen.EmitBrtrue(fail); hasfail = true; } if (shadowType == Context.Types.Object) { - ilgen.Emit(OpCodes.Ldarg_0); - ilgen.Emit(OpCodes.Isinst, Context.Types.Array); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); + ilgen.Emit(System.Reflection.Emit.OpCodes.Isinst, Context.Types.Array); ilgen.EmitBrtrue(fail); hasfail = true; } @@ -2085,26 +2099,26 @@ private void CreateShadowCheckCast(ICollection remappedType { if (!r.shadowType.IsInterface && r.shadowType.IsSubclassOf(shadowType)) { - ilgen.Emit(OpCodes.Ldarg_0); - ilgen.Emit(OpCodes.Isinst, r.shadowType); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); + ilgen.Emit(System.Reflection.Emit.OpCodes.Isinst, r.shadowType); ilgen.EmitBrtrue(fail); hasfail = true; } } - ilgen.Emit(OpCodes.Ldarg_0); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); ilgen.EmitCastclass(shadowType); - ilgen.Emit(OpCodes.Ret); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ret); if (hasfail) { ilgen.MarkLabel(fail); - ilgen.ThrowException(Context.Resolver.ResolveCoreType(typeof(InvalidCastException).FullName).AsReflection()); + ilgen.ThrowException(Context.Resolver.ResolveCoreType(typeof(InvalidCastException).FullName)); } ilgen.DoEmit(); } - internal override MethodBase LinkMethod(RuntimeJavaMethod mw) + internal override IMethodBaseSymbol LinkMethod(RuntimeJavaMethod mw) { return ((RemappedMethodBaseWrapper)mw).DoLink(); } @@ -2148,15 +2162,26 @@ internal override bool IsFastClassLiteralSafe } } + internal static void AddDeclaredExceptions(RuntimeContext context, IConstructorSymbolBuilder cb, IKVM.Tools.Importer.MapXml.Throws[] throws) + { + if (throws != null) + { + var exceptions = new string[throws.Length]; + for (int i = 0; i < exceptions.Length; i++) + exceptions[i] = throws[i].Class; + + context.AttributeHelper.SetThrowsAttribute(cb, exceptions); + } + } + internal static void AddDeclaredExceptions(RuntimeContext context, IMethodSymbolBuilder mb, IKVM.Tools.Importer.MapXml.Throws[] throws) { if (throws != null) { - string[] exceptions = new string[throws.Length]; + var exceptions = new string[throws.Length]; for (int i = 0; i < exceptions.Length; i++) - { exceptions[i] = throws[i].Class; - } + context.AttributeHelper.SetThrowsAttribute(mb, exceptions); } } @@ -2282,21 +2307,21 @@ internal void Emit(MapXml.CodeGenContext context, CodeEmitter ilgen) { var mwSuppressFillInStackTrace = rcontext.JavaBase.TypeOfjavaLangThrowable.GetMethodWrapper("__", "()V", false); mwSuppressFillInStackTrace.Link(); - ilgen.Emit(OpCodes.Ldarg_0); - ilgen.Emit(OpCodes.Callvirt, rcontext.CompilerFactory.GetTypeMethod); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); + ilgen.Emit(System.Reflection.Emit.OpCodes.Callvirt, rcontext.CompilerFactory.GetTypeMethod); for (int i = 0; i < map.Length; i++) { - ilgen.Emit(OpCodes.Dup); - ilgen.Emit(OpCodes.Ldtoken, rcontext.Resolver.ResolveCoreType(map[i].Source).AsReflection()); - ilgen.Emit(OpCodes.Call, rcontext.CompilerFactory.GetTypeFromHandleMethod); - ilgen.Emit(OpCodes.Ceq); + ilgen.Emit(System.Reflection.Emit.OpCodes.Dup); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldtoken, rcontext.Resolver.ResolveCoreType(map[i].Source)); + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, rcontext.CompilerFactory.GetTypeFromHandleMethod); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ceq); var label = ilgen.DefineLabel(); ilgen.EmitBrfalse(label); - ilgen.Emit(OpCodes.Pop); + ilgen.Emit(System.Reflection.Emit.OpCodes.Pop); if (map[i].Code != null) { - ilgen.Emit(OpCodes.Ldarg_0); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); if (map[i].Code.Instructions.Length > 0) { @@ -2310,7 +2335,7 @@ internal void Emit(MapXml.CodeGenContext context, CodeEmitter ilgen) } } - ilgen.Emit(OpCodes.Ret); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ret); } else { @@ -2319,15 +2344,15 @@ internal void Emit(MapXml.CodeGenContext context, CodeEmitter ilgen) mw.Link(); mwSuppressFillInStackTrace.EmitCall(ilgen); mw.EmitNewobj(ilgen); - ilgen.Emit(OpCodes.Ret); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ret); } ilgen.MarkLabel(label); } - ilgen.Emit(OpCodes.Pop); - ilgen.Emit(OpCodes.Ldarg_0); - ilgen.Emit(OpCodes.Ret); + ilgen.Emit(System.Reflection.Emit.OpCodes.Pop); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ret); } } @@ -2493,7 +2518,7 @@ internal void FinishRemappedTypes() Context.AttributeHelper.SetCustomAttribute(this, assemblyBuilder, attr); } - private static bool IsSigned(Assembly asm) + private static bool IsSigned(IAssemblySymbol asm) { byte[] key = asm.GetName().GetPublicKey(); return key != null && key.Length != 0; @@ -2536,21 +2561,23 @@ internal static int Compile(ImportContext importer, RuntimeContext context, Stat foreach (var loader in loaders) loader.CompilePass0(); - var mainAssemblyTypes = new Dictionary(); + var mainAssemblyTypes = new Dictionary(); foreach (var loader in loaders) { if (loader.state.sharedclassloader != null) { if (!mainAssemblyTypes.TryGetValue(loader.state.sharedclassloader[0], out var mainAssemblyType)) { - var tb = loader.state.sharedclassloader[0].GetTypeWrapperFactory().ModuleBuilder.DefineType("__", TypeAttributes.NotPublic | TypeAttributes.Abstract | TypeAttributes.SpecialName); + var tb = loader.state.sharedclassloader[0].GetTypeWrapperFactory().ModuleBuilder.DefineType("__", System.Reflection.TypeAttributes.NotPublic | System.Reflection.TypeAttributes.Abstract | System.Reflection.TypeAttributes.SpecialName); loader.Context.AttributeHelper.HideFromJava(tb); - mainAssemblyType = tb.CreateType(); + tb.Complete(); + + mainAssemblyType = tb; mainAssemblyTypes.Add(loader.state.sharedclassloader[0], mainAssemblyType); } if (loader.state.sharedclassloader[0] != loader) { - ((AssemblyBuilder)loader.GetTypeWrapperFactory().ModuleBuilder.Assembly).__AddTypeForwarder(mainAssemblyType); + ((IAssemblySymbolBuilder)loader.GetTypeWrapperFactory().ModuleBuilder.Assembly).AddTypeForwarder(mainAssemblyType); } } @@ -2591,13 +2618,13 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, IDiag { diagnostics.GenericCompilerInfo($"JVM.Compile path: {options.path}, assembly: {options.assembly}"); - AssemblyName runtimeAssemblyName = compiler.runtimeAssembly.GetName(); + var runtimeAssemblyName = compiler.runtimeAssembly.GetName(); bool allReferencesAreStrongNamed = IsSigned(compiler.runtimeAssembly); List references = new List(); - foreach (Assembly reference in options.references ?? new Assembly[0]) + foreach (var reference in options.references ?? []) { references.Add(reference); - allReferencesAreStrongNamed &= IsSigned(reference); + allReferencesAreStrongNamed &= IsSigned(context.Resolver.ResolveAssembly(reference)); diagnostics.GenericCompilerInfo($"Loaded reference assembly: {reference.FullName}"); // if it's an IKVM compiled assembly, make sure that it was compiled @@ -2699,7 +2726,7 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, IDiag } // now look for a main method - if (options.mainClass == null && (options.guessFileKind || options.target != PEFileKinds.Dll)) + if (options.mainClass == null && (options.guessFileKind || options.target != IKVM.CoreLib.Symbols.Emit.PEFileKinds.Dll)) { foreach (string className in classNames) { @@ -2729,22 +2756,22 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, IDiag if (options.guessFileKind && options.mainClass == null) { - options.target = PEFileKinds.Dll; + options.target = IKVM.CoreLib.Symbols.Emit.PEFileKinds.Dll; } - if (options.target != PEFileKinds.Dll && options.mainClass == null) + if (options.target != IKVM.CoreLib.Symbols.Emit.PEFileKinds.Dll && options.mainClass == null) { throw new FatalCompilerErrorException(DiagnosticEvent.ExeRequiresMainClass()); } - if (options.target == PEFileKinds.Dll && options.props.Count != 0) + if (options.target == IKVM.CoreLib.Symbols.Emit.PEFileKinds.Dll && options.props.Count != 0) { throw new FatalCompilerErrorException(DiagnosticEvent.PropertiesRequireExe()); } if (options.path == null) { - if (options.target == PEFileKinds.Dll) + if (options.target == IKVM.CoreLib.Symbols.Emit.PEFileKinds.Dll) { if (options.targetIsModule) { @@ -2778,10 +2805,10 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, IDiag for (int i = 0; i < references.Count; i++) { // if reference is to base assembly, set it explicitly for resolution - if (compiler.baseAssembly == null && options.bootstrap == false && IsBaseAssembly(context, references[i])) - compiler.baseAssembly = references[i]; + if (compiler.baseAssembly == null && options.bootstrap == false && IsBaseAssembly(context, context.Resolver.ResolveAssembly(references[i]))) + compiler.baseAssembly = context.Resolver.ResolveAssembly(references[i]); - var acl = context.AssemblyClassLoaderFactory.FromAssembly(references[i]); + var acl = context.AssemblyClassLoaderFactory.FromAssembly(context.Resolver.ResolveAssembly(references[i])); if (referencedAssemblies.Contains(acl)) diagnostics.DuplicateAssemblyReference(acl.MainAssembly.FullName); @@ -2837,7 +2864,7 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, IDiag { foreach (var name in compiler.runtimeAssembly.GetReferencedAssemblies()) { - Assembly asm = null; + IAssemblySymbol asm = null; try { @@ -2869,8 +2896,8 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, IDiag if (options.bootstrap == false) { - allReferencesAreStrongNamed &= IsSigned(context.Resolver.ResolveBaseAssembly().AsReflection()); - loader.AddReference(context.AssemblyClassLoaderFactory.FromAssembly(context.Resolver.ResolveBaseAssembly().AsReflection())); + allReferencesAreStrongNamed &= IsSigned(context.Resolver.ResolveBaseAssembly()); + loader.AddReference(context.AssemblyClassLoaderFactory.FromAssembly(context.Resolver.ResolveBaseAssembly())); } if ((options.keyPair != null || options.publicKey != null) && !allReferencesAreStrongNamed) @@ -2886,21 +2913,20 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, IDiag if (options.bootstrap == false) { loader.fakeTypes = context.FakeTypes; - loader.fakeTypes.Load(context.Resolver.ResolveBaseAssembly().AsReflection()); + loader.fakeTypes.Load(context.Resolver.ResolveBaseAssembly()); } return 0; } - static bool IsBaseAssembly(RuntimeContext context, Assembly asm) + static bool IsBaseAssembly(RuntimeContext context, IAssemblySymbol asm) { - return asm.IsDefined(context.Resolver.ResolveRuntimeType(typeof(IKVM.Attributes.RemappedClassAttribute).FullName).AsReflection(), false); + return asm.IsDefined(context.Resolver.ResolveRuntimeType(typeof(IKVM.Attributes.RemappedClassAttribute).FullName), false); } - private static Assembly LoadReferencedAssembly(StaticCompiler compiler, string r) + private static IAssemblySymbol LoadReferencedAssembly(StaticCompiler compiler, string r) { - Assembly asm = compiler.LoadFile(r); - return asm; + return compiler.LoadFile(r); } private void CompilePass0() @@ -2971,7 +2997,7 @@ int CompilePass3() Diagnostics.GenericCompilerInfo("Compiling class files (3)"); // emits the IL required for module initialization - var moduleInitBuilders = new List>(); + var moduleInitBuilders = new List>(); // bootstrap mode introduces fake types if (map != null && state.bootstrap) @@ -3008,7 +3034,7 @@ int CompilePass3() mw.Link(); - var method = mw.GetMethod() as MethodInfo; + var method = mw.GetMethod() as IMethodSymbol; if (method == null) throw new FatalCompilerErrorException(DiagnosticEvent.UnsupportedMainMethod()); @@ -3025,7 +3051,7 @@ int CompilePass3() _ => throw new NotImplementedException(), }; - SetMain(wrapper, state.target, state.props, state.noglobbing, apartmentAttributeType.AsReflection()); + SetMain(wrapper, state.target, state.props, state.noglobbing, apartmentAttributeType); } // complete map @@ -3040,7 +3066,7 @@ int CompilePass3() } catch (IKVM.Reflection.MissingMemberException x) { - Context.StaticCompiler.IssueMissingTypeMessage((Type)x.MemberInfo); + Context.StaticCompiler.IssueMissingTypeMessage((ITypeSymbol)Context.Resolver.ResolveMember(x.MemberInfo)); return 1; } } @@ -3056,7 +3082,7 @@ int CompilePass3() // configure Win32 file version if (state.fileversion != null) { - var filever = new CustomAttributeBuilder(Context.Resolver.ResolveCoreType(typeof(System.Reflection.AssemblyFileVersionAttribute).FullName).AsReflection().GetConstructor([Context.Types.String]), [state.fileversion]); + var filever = Context.Resolver.Symbols.CreateCustomAttribute(Context.Resolver.ResolveCoreType(typeof(System.Reflection.AssemblyFileVersionAttribute).FullName).GetConstructor([Context.Types.String]), [state.fileversion]); assemblyBuilder.SetCustomAttribute(filever); } @@ -3101,8 +3127,8 @@ int CompilePass3() throw new FatalCompilerErrorException(DiagnosticEvent.ClassLoaderConstructorMissing()); // apply custom attribute specifying custom class loader - var ci = Context.Resolver.ResolveRuntimeType(typeof(CustomAssemblyClassLoaderAttribute).FullName).AsReflection().GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new[] { Context.Types.Type }, null); - assemblyBuilder.SetCustomAttribute(new CustomAttributeBuilder(ci, new object[] { classLoaderType.TypeAsTBD })); + var ci = Context.Resolver.ResolveRuntimeType(typeof(CustomAssemblyClassLoaderAttribute).FullName).GetConstructor(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic, new[] { Context.Types.Type }); + assemblyBuilder.SetCustomAttribute(Context.Resolver.Symbols.CreateCustomAttribute(ci, new object[] { classLoaderType.TypeAsTBD })); // the class loader type defines a module initialize method, ensure we call it upon module load var mwModuleInit = classLoaderType.GetMethodWrapper("InitializeModule", "(Lcli.System.Reflection.Module;)V", false); @@ -3110,22 +3136,22 @@ int CompilePass3() { moduleInitBuilders.Add((mb, il) => { - il.Emit(OpCodes.Ldtoken, mb); - il.Emit(OpCodes.Call, Context.Resolver.ResolveCoreType(typeof(System.Reflection.MethodBase).FullName).GetMethod("GetMethodFromHandle", new[] { Context.Resolver.ResolveCoreType(typeof(RuntimeMethodHandle).FullName) }).AsReflection()); - il.Emit(OpCodes.Callvirt, Context.Resolver.ResolveCoreType(typeof(System.Reflection.MemberInfo).FullName).GetProperty("Module").GetGetMethod().AsReflection()); - il.Emit(OpCodes.Call, Context.Resolver.ResolveRuntimeType("IKVM.Runtime.ByteCodeHelper").GetMethod("InitializeModule").AsReflection()); + il.Emit(System.Reflection.Emit.OpCodes.Ldtoken, mb); + il.Emit(System.Reflection.Emit.OpCodes.Call, Context.Resolver.ResolveCoreType(typeof(System.Reflection.MethodBase).FullName).GetMethod("GetMethodFromHandle", new[] { Context.Resolver.ResolveCoreType(typeof(RuntimeMethodHandle).FullName) })); + il.Emit(System.Reflection.Emit.OpCodes.Callvirt, Context.Resolver.ResolveCoreType(typeof(System.Reflection.MemberInfo).FullName).GetProperty("Module").GetGetMethod()); + il.Emit(System.Reflection.Emit.OpCodes.Call, Context.Resolver.ResolveRuntimeType("IKVM.Runtime.ByteCodeHelper").GetMethod("InitializeModule")); }); } } if (state.iconfile != null) { - assemblyBuilder.__DefineIconResource(ImportContext.ReadAllBytes(state.iconfile)); + assemblyBuilder.DefineIconResource(ImportContext.ReadAllBytes(state.iconfile)); } if (state.manifestFile != null) { - assemblyBuilder.__DefineManifestResource(ImportContext.ReadAllBytes(state.manifestFile)); + assemblyBuilder.DefineManifestResource(ImportContext.ReadAllBytes(state.manifestFile)); } assemblyBuilder.DefineVersionInfoResource(); @@ -3141,7 +3167,7 @@ int CompilePass3() if (moduleInitBuilders.Count > 0) { // begin a module initializer - var moduleInit = GetTypeWrapperFactory().ModuleBuilder.DefineGlobalMethod(".cctor", MethodAttributes.Private | MethodAttributes.Static | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, null, Type.EmptyTypes); + var moduleInit = GetTypeWrapperFactory().ModuleBuilder.DefineGlobalMethod(".cctor", System.Reflection.MethodAttributes.Private | System.Reflection.MethodAttributes.Static | System.Reflection.MethodAttributes.SpecialName | System.Reflection.MethodAttributes.RTSpecialName, null, []); var moduleInitIL = Context.CodeEmitterFactory.Create(moduleInit); // allow builders to append IL @@ -3149,7 +3175,7 @@ int CompilePass3() moduleInitBuilder(moduleInit, moduleInitIL); // finish method - moduleInitIL.Emit(OpCodes.Ret); + moduleInitIL.Emit(System.Reflection.Emit.OpCodes.Ret); moduleInitIL.DoEmit(); } @@ -3243,16 +3269,17 @@ static bool IsValidSig(string sig, bool field) return sig != null && (field ? IKVM.Runtime.ClassFile.IsValidFieldSig(sig) : IKVM.Runtime.ClassFile.IsValidMethodSig(sig)); } - internal Type GetTypeFromReferencedAssembly(string name) + internal ITypeSymbol GetTypeFromReferencedAssembly(string name) { foreach (RuntimeAssemblyClassLoader acl in referencedAssemblies) { - Type type = acl.MainAssembly.GetType(name, false); + var type = acl.MainAssembly.GetType(name, false); if (type != null) { return type; } } + return null; } @@ -3273,6 +3300,7 @@ protected override void CheckProhibitedPackage(string className) base.CheckProhibitedPackage(className); } } + } -} +} \ No newline at end of file diff --git a/src/IKVM.Tools.Importer/ImportContext.cs b/src/IKVM.Tools.Importer/ImportContext.cs index 1ef1ea8e7..b8d0f8f5b 100644 --- a/src/IKVM.Tools.Importer/ImportContext.cs +++ b/src/IKVM.Tools.Importer/ImportContext.cs @@ -26,14 +26,15 @@ Jeroen Frijters using System.IO; using System.IO.Compression; using System.Linq; +using System.Reflection.Metadata; +using System.Reflection.PortableExecutable; using System.Text.RegularExpressions; using System.Threading; using IKVM.ByteCode; using IKVM.CoreLib.Diagnostics; -using IKVM.CoreLib.Symbols; using IKVM.Reflection; -using IKVM.Reflection.Emit; +using IKVM.Reflection.Diagnostics; using IKVM.Runtime; using IKVM.Tools.Core.Diagnostics; @@ -100,6 +101,7 @@ public override void Report(in DiagnosticEvent @event) } readonly ImportOptions _options; + static readonly AssemblyResolver resolver = new AssemblyResolver(); string manifestMainClass; string defaultAssemblyName; static bool time; @@ -108,7 +110,6 @@ public override void Report(in DiagnosticEvent @event) static bool nonDeterministicOutput; static DebugMode debugMode; static readonly List libpaths = new List(); - internal static readonly AssemblyResolver resolver = new AssemblyResolver(); public static int Execute(ImportOptions options) { @@ -179,27 +180,58 @@ static IDiagnosticHandler GetDiagnostics(IServiceProvider services, ImportState return ActivatorUtilities.CreateInstance(services, options, spec); } + /// + /// Initiates a compilation with the given options. + /// + /// + /// + /// + /// static int Compile(ImportOptions options) { + // use a service collection to initialize core services var rootTarget = new ImportState(); var services = new ServiceCollection(); services.AddToolsDiagnostics(); services.AddSingleton(p => GetDiagnostics(p, rootTarget, options.Log)); - services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); using var provider = services.BuildServiceProvider(); var diagnostics = provider.GetRequiredService(); var compiler = provider.GetRequiredService(); var targets = new List(); - var context = new RuntimeContext(new RuntimeContextOptions(), diagnostics, provider.GetRequiredService(), options.Bootstrap, compiler); + var context = new RuntimeContext(new RuntimeContextOptions(), diagnostics, provider.GetRequiredService(), options.Bootstrap, compiler); + + // discover the core lib from the references + var coreLibName = FindCoreLibName(rootTarget.unresolvedReferences, libpaths); + if (coreLibName == null) + { + diagnostics.CoreClassesMissing(); + throw new Exception(); + } + + var universeOptions = UniverseOptions.ResolveMissingMembers | UniverseOptions.EnableFunctionPointers; + if (nonDeterministicOutput == false) + universeOptions |= UniverseOptions.DeterministicOutput; + + // configure the universe of types + var universe = new Universe(universeOptions, coreLibName); + universe.ResolvedMissingMember += (requestingModule, member) => + { + if (requestingModule != null && member is IKVM.Reflection.Type type) + diagnostics.UnableToResolveType(requestingModule.Name, type.FullName, member.Module.FullyQualifiedName); + }; + + // enable embedded symbol writer if debug mode is enabled + if (rootTarget.debugMode == DebugMode.Portable) + universe.SetSymbolWriterFactory(module => new PortablePdbSymbolWriter(module)); compiler.rootTarget = rootTarget; var importer = new ImportContext(); importer.ParseCommandLine(context, compiler, diagnostics, options, targets, rootTarget); - compiler.Init(nonDeterministicOutput, rootTarget.debugMode, libpaths); resolver.Warning += (warning, message, parameters) => loader_Warning(compiler, diagnostics, warning, message, parameters); - resolver.Init(compiler.Universe, nostdlib, rootTarget.unresolvedReferences, libpaths); + resolver.Init(universe, nostdlib, rootTarget.unresolvedReferences, libpaths); ResolveReferences(compiler, diagnostics, targets); ResolveStrongNameKeys(targets); @@ -219,6 +251,64 @@ static int Compile(ImportOptions options) } } + /// + /// Finds the first potential core library in the reference set. + /// + /// + /// + /// + static string FindCoreLibName(IList references, IList libpaths) + { + if (references != null) + foreach (var reference in references) + if (GetAssemblyNameIfCoreLib(reference) is string coreLibName) + return coreLibName; + + if (libpaths != null) + foreach (var libpath in libpaths) + foreach (var dll in Directory.GetFiles(libpath, "*.dll")) + if (GetAssemblyNameIfCoreLib(dll) is string coreLibName) + return coreLibName; + + return null; + } + + /// + /// Returns true if the given assembly is a core library. + /// + /// + /// + static string GetAssemblyNameIfCoreLib(string path) + { + if (File.Exists(path) == false) + return null; + + using var st = File.OpenRead(path); + using var pe = new PEReader(st); + var mr = pe.GetMetadataReader(); + + foreach (var handle in mr.TypeDefinitions) + if (IsSystemObject(mr, handle)) + return mr.GetString(mr.GetAssemblyDefinition().Name); + + return null; + } + + /// + /// Returns true if the given type definition handle refers to "System.Object". + /// + /// + /// + /// + static bool IsSystemObject(MetadataReader reader, TypeDefinitionHandle th) + { + var td = reader.GetTypeDefinition(th); + var ns = reader.GetString(td.Namespace); + var nm = reader.GetString(td.Name); + + return ns == "System" && nm == "Object"; + } + static void loader_Warning(StaticCompiler compiler, IDiagnosticHandler diagnostics, AssemblyResolver.WarningId warning, string message, string[] parameters) { switch (warning) @@ -302,7 +392,7 @@ internal static byte[] ReadAllBytes(FileInfo path) void ParseCommandLine(RuntimeContext context, StaticCompiler compiler, IDiagnosticHandler diagnostics, ImportOptions options, List targets, ImportState compilerOptions) { - compilerOptions.target = PEFileKinds.ConsoleApplication; + compilerOptions.target = IKVM.CoreLib.Symbols.Emit.PEFileKinds.ConsoleApplication; compilerOptions.guessFileKind = true; compilerOptions.version = new Version(0, 0, 0, 0); compilerOptions.apartment = ApartmentState.STA; @@ -321,21 +411,21 @@ void ContinueParseCommandLine(RuntimeContext context, StaticCompiler compiler, I switch (options.Target) { case ImportTarget.Exe: - compilerOptions.target = PEFileKinds.ConsoleApplication; + compilerOptions.target = IKVM.CoreLib.Symbols.Emit.PEFileKinds.ConsoleApplication; compilerOptions.guessFileKind = false; break; case ImportTarget.WinExe: - compilerOptions.target = PEFileKinds.WindowApplication; + compilerOptions.target = IKVM.CoreLib.Symbols.Emit.PEFileKinds.WindowApplication; compilerOptions.guessFileKind = false; break; case ImportTarget.Module: compilerOptions.targetIsModule = true; - compilerOptions.target = PEFileKinds.Dll; + compilerOptions.target = IKVM.CoreLib.Symbols.Emit.PEFileKinds.Dll; compilerOptions.guessFileKind = false; nonDeterministicOutput = true; break; case ImportTarget.Library: - compilerOptions.target = PEFileKinds.Dll; + compilerOptions.target = IKVM.CoreLib.Symbols.Emit.PEFileKinds.Dll; compilerOptions.guessFileKind = false; break; default: @@ -345,28 +435,28 @@ void ContinueParseCommandLine(RuntimeContext context, StaticCompiler compiler, I switch (options.Platform) { case ImportPlatform.X86: - compilerOptions.pekind = PortableExecutableKinds.ILOnly | PortableExecutableKinds.Required32Bit; - compilerOptions.imageFileMachine = ImageFileMachine.I386; + compilerOptions.pekind = System.Reflection.PortableExecutableKinds.ILOnly | System.Reflection.PortableExecutableKinds.Required32Bit; + compilerOptions.imageFileMachine = IKVM.CoreLib.Symbols.ImageFileMachine.I386; break; case ImportPlatform.X64: - compilerOptions.pekind = PortableExecutableKinds.ILOnly | PortableExecutableKinds.PE32Plus; - compilerOptions.imageFileMachine = ImageFileMachine.AMD64; + compilerOptions.pekind = System.Reflection.PortableExecutableKinds.ILOnly | System.Reflection.PortableExecutableKinds.PE32Plus; + compilerOptions.imageFileMachine = IKVM.CoreLib.Symbols.ImageFileMachine.AMD64; break; case ImportPlatform.ARM: - compilerOptions.pekind = PortableExecutableKinds.ILOnly; - compilerOptions.imageFileMachine = ImageFileMachine.ARM; + compilerOptions.pekind = System.Reflection.PortableExecutableKinds.ILOnly; + compilerOptions.imageFileMachine = IKVM.CoreLib.Symbols.ImageFileMachine.ARM; break; case ImportPlatform.ARM64: - compilerOptions.pekind = PortableExecutableKinds.ILOnly; - compilerOptions.imageFileMachine = ImageFileMachine.ARM64; + compilerOptions.pekind = System.Reflection.PortableExecutableKinds.ILOnly; + compilerOptions.imageFileMachine = IKVM.CoreLib.Symbols.ImageFileMachine.ARM64; break; case ImportPlatform.AnyCpu32BitPreferred: - compilerOptions.pekind = PortableExecutableKinds.ILOnly | PortableExecutableKinds.Preferred32Bit; - compilerOptions.imageFileMachine = ImageFileMachine.UNKNOWN; + compilerOptions.pekind = System.Reflection.PortableExecutableKinds.ILOnly | System.Reflection.PortableExecutableKinds.Preferred32Bit; + compilerOptions.imageFileMachine = IKVM.CoreLib.Symbols.ImageFileMachine.Unknown; break; case ImportPlatform.AnyCpu: - compilerOptions.pekind = PortableExecutableKinds.ILOnly; - compilerOptions.imageFileMachine = ImageFileMachine.UNKNOWN; + compilerOptions.pekind = System.Reflection.PortableExecutableKinds.ILOnly; + compilerOptions.imageFileMachine = IKVM.CoreLib.Symbols.ImageFileMachine.Unknown; break; default: throw new FatalCompilerErrorException(DiagnosticEvent.UnrecognizedPlatform(options.Platform.ToString())); @@ -698,12 +788,12 @@ void ContinueParseCommandLine(RuntimeContext context, StaticCompiler compiler, I if (compilerOptions.path != null && compilerOptions.guessFileKind) { if (compilerOptions.path.Extension.Equals(".dll", StringComparison.OrdinalIgnoreCase)) - compilerOptions.target = PEFileKinds.Dll; + compilerOptions.target = IKVM.CoreLib.Symbols.Emit.PEFileKinds.Dll; compilerOptions.guessFileKind = false; } - if (compilerOptions.mainClass == null && manifestMainClass != null && (compilerOptions.guessFileKind || compilerOptions.target != PEFileKinds.Dll)) + if (compilerOptions.mainClass == null && manifestMainClass != null && (compilerOptions.guessFileKind || compilerOptions.target != IKVM.CoreLib.Symbols.Emit.PEFileKinds.Dll)) { diagnostics.MainMethodFromManifest(manifestMainClass); compilerOptions.mainClass = manifestMainClass; @@ -857,7 +947,7 @@ static void SetStrongNameKeyPair(ref StrongNameKeyPair strongNameKeyPair, FileIn static void ResolveReferences(StaticCompiler compiler, IDiagnosticHandler diagnostics, List targets) { - var cache = new Dictionary(); + var cache = new Dictionary(); foreach (var target in targets) { @@ -873,6 +963,7 @@ static void ResolveReferences(StaticCompiler compiler, IDiagnosticHandler diagno goto next_reference; } } + if (!resolver.ResolveReference(cache, ref target.references, reference)) { throw new FatalCompilerErrorException(DiagnosticEvent.ReferenceNotFound(reference)); @@ -905,10 +996,10 @@ static void ResolveReferences(StaticCompiler compiler, IDiagnosticHandler diagno foreach (var target in targets) if (target.references != null) foreach (var asm in target.references) - RuntimeAssemblyClassLoader.PreloadExportedAssemblies(compiler, asm); + RuntimeAssemblyClassLoader.PreloadExportedAssemblies(compiler, compiler.Symbols.GetOrCreateAssemblySymbol(asm)); } - private static void ArrayAppend(ref T[] array, T element) + static void ArrayAppend(ref T[] array, T element) { if (array == null) array = [element]; @@ -916,7 +1007,7 @@ private static void ArrayAppend(ref T[] array, T element) array = ArrayUtil.Concat(array, element); } - private static void ArrayAppend(ref T[] array, T[] append) + static void ArrayAppend(ref T[] array, T[] append) { if (array == null) { diff --git a/src/IKVM.Tools.Importer/ImportOptions.cs b/src/IKVM.Tools.Importer/ImportOptions.cs index 7967508d4..9ad497ff9 100644 --- a/src/IKVM.Tools.Importer/ImportOptions.cs +++ b/src/IKVM.Tools.Importer/ImportOptions.cs @@ -268,4 +268,4 @@ object ICloneable.Clone() } -} +} \ No newline at end of file diff --git a/src/IKVM.Tools.Importer/ImportRuntimeSymbolResolver.cs b/src/IKVM.Tools.Importer/ImportRuntimeSymbolResolver.cs new file mode 100644 index 000000000..7f3eeecb8 --- /dev/null +++ b/src/IKVM.Tools.Importer/ImportRuntimeSymbolResolver.cs @@ -0,0 +1,141 @@ +/* + Copyright (C) 2002-2014 Jeroen Frijters + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jeroen Frijters + jeroen@frijters.net + +*/ +using System; + +using IKVM.CoreLib.Symbols; +using IKVM.CoreLib.Symbols.Emit; +using IKVM.CoreLib.Symbols.IkvmReflection; +using IKVM.Reflection; +using IKVM.Reflection.Emit; +using IKVM.Runtime; + +using Type = IKVM.Reflection.Type; + +namespace IKVM.Tools.Importer +{ + + class ImportRuntimeSymbolResolver : IRuntimeSymbolResolver + { + + readonly StaticCompiler compiler; + readonly IkvmReflectionSymbolContext context; + + /// + public ISymbolContext Symbols => context; + + /// + /// Initializes a new instance. + /// + /// + public ImportRuntimeSymbolResolver(StaticCompiler compiler) + { + this.compiler = compiler ?? throw new ArgumentNullException(nameof(compiler)); + this.context = new IkvmReflectionSymbolContext(compiler.Universe); + } + + /// + public IAssemblySymbol ResolveBaseAssembly() + { + return compiler.baseAssembly; + } + + /// + public IAssemblySymbol ResolveAssembly(string assemblyName) + { + return compiler.Universe.Load(assemblyName) is { } a ? context.GetOrCreateAssemblySymbol(a) : null; + } + + /// + public ITypeSymbol ResolveCoreType(string typeName) + { + foreach (var assembly in compiler.Universe.GetAssemblies()) + if (assembly.GetType(typeName) is Type t) + return context.GetOrCreateTypeSymbol(t); + + return null; + } + + /// + public ITypeSymbol ResolveRuntimeType(string typeName) + { + return compiler.GetRuntimeType(typeName); + } + + /// + public IAssemblySymbol ResolveAssembly(Assembly assembly) + { + return context.GetOrCreateAssemblySymbol(assembly); + } + + /// + public IAssemblySymbolBuilder ResolveAssembly(AssemblyBuilder assembly) + { + return context.GetOrCreateAssemblySymbol(assembly); + } + + /// + public IModuleSymbol ResolveModule(Module module) + { + return context.GetOrCreateModuleSymbol(module); + } + + /// + public IModuleSymbolBuilder ResolveModule(ModuleBuilder module) + { + return context.GetOrCreateModuleSymbol(module); + } + + /// + public ITypeSymbol ResolveType(Type type) + { + return context.GetOrCreateTypeSymbol(type); + } + + /// + public IMemberSymbol ResolveMember(MemberInfo memberInfo) + { + return context.GetOrCreateMemberSymbol(memberInfo); + } + + /// + public IMethodBaseSymbol ResolveMethodBase(MethodBase type) + { + return context.GetOrCreateMethodBaseSymbol(type); + } + + /// + public IConstructorSymbol ResolveConstructor(ConstructorInfo ctor) + { + return context.GetOrCreateConstructorSymbol(ctor); + } + + /// + public IMethodSymbol ResolveMethod(MethodInfo method) + { + return context.GetOrCreateMethodSymbol(method); + } + + } + +} \ No newline at end of file diff --git a/src/IKVM.Tools.Importer/ImportState.cs b/src/IKVM.Tools.Importer/ImportState.cs index fd8a2ceaa..38ef6f368 100644 --- a/src/IKVM.Tools.Importer/ImportState.cs +++ b/src/IKVM.Tools.Importer/ImportState.cs @@ -1,25 +1,25 @@ /* - Copyright (C) 2002-2014 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - + Copyright (C) 2002-2014 Jeroen Frijters + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jeroen Frijters + jeroen@frijters.net + */ using System; using System.Collections.Generic; @@ -59,7 +59,7 @@ sealed class ImportState internal string assembly; internal string mainClass; internal ApartmentState apartment; - internal PEFileKinds target; + internal IKVM.CoreLib.Symbols.Emit.PEFileKinds target; internal bool guessFileKind; internal string[] unresolvedReferences; // only used during command line parsing internal Dictionary legacyStubReferences = new Dictionary(); // only used during command line parsing @@ -79,8 +79,8 @@ sealed class ImportState internal string sourcepath; internal Dictionary externalResources; internal string classLoader; - internal PortableExecutableKinds pekind = PortableExecutableKinds.ILOnly; - internal ImageFileMachine imageFileMachine = ImageFileMachine.I386; + internal System.Reflection.PortableExecutableKinds pekind = System.Reflection.PortableExecutableKinds.ILOnly; + internal IKVM.CoreLib.Symbols.ImageFileMachine imageFileMachine = IKVM.CoreLib.Symbols.ImageFileMachine.I386; internal ulong baseAddress; internal uint fileAlignment; internal bool highentropyva; @@ -195,4 +195,4 @@ internal bool IsExcludedClass(string className) } -} +} \ No newline at end of file diff --git a/src/IKVM.Tools.Importer/ImportTarget.cs b/src/IKVM.Tools.Importer/ImportTarget.cs index 475c272a7..a2eae1b97 100644 --- a/src/IKVM.Tools.Importer/ImportTarget.cs +++ b/src/IKVM.Tools.Importer/ImportTarget.cs @@ -12,4 +12,4 @@ enum ImportTarget } -} \ No newline at end of file +} diff --git a/src/IKVM.Tools.Importer/ManagedResolver.cs b/src/IKVM.Tools.Importer/ManagedResolver.cs deleted file mode 100644 index 2b6ec0e4e..000000000 --- a/src/IKVM.Tools.Importer/ManagedResolver.cs +++ /dev/null @@ -1,75 +0,0 @@ -/* - Copyright (C) 2002-2014 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; - -using IKVM.CoreLib.Symbols; -using IKVM.CoreLib.Symbols.IkvmReflection; - -using Type = IKVM.Reflection.Type; - -namespace IKVM.Tools.Importer -{ - - class ManagedResolver : ISymbolResolver - { - - readonly StaticCompiler compiler; - readonly IkvmReflectionSymbolContext context = new(); - - /// - /// Initializes a new instance. - /// - /// - public ManagedResolver(StaticCompiler compiler) - { - this.compiler = compiler ?? throw new ArgumentNullException(nameof(compiler)); - } - - public IAssemblySymbol ResolveBaseAssembly() - { - return compiler.baseAssembly != null ? context.GetOrCreateAssemblySymbol(compiler.baseAssembly) : null; - } - - public IAssemblySymbol ResolveAssembly(string assemblyName) - { - return compiler.Universe.Load(assemblyName) is { } a ? context.GetOrCreateAssemblySymbol(a) : null; - } - - public ITypeSymbol ResolveCoreType(string typeName) - { - foreach (var assembly in compiler.Universe.GetAssemblies()) - if (assembly.GetType(typeName) is Type t) - return context.GetOrCreateTypeSymbol(t); - - return null; - } - - public ITypeSymbol ResolveRuntimeType(string typeName) - { - return compiler.GetRuntimeType(typeName) is { } t ? context.GetOrCreateTypeSymbol(t) : null; - } - - } - -} diff --git a/src/IKVM.Tools.Importer/MapXml/Add.cs b/src/IKVM.Tools.Importer/MapXml/Add.cs index 8d16993d0..7541d6ad8 100644 --- a/src/IKVM.Tools.Importer/MapXml/Add.cs +++ b/src/IKVM.Tools.Importer/MapXml/Add.cs @@ -22,10 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/And.cs b/src/IKVM.Tools.Importer/MapXml/And.cs index e0b869ce6..4829dedbf 100644 --- a/src/IKVM.Tools.Importer/MapXml/And.cs +++ b/src/IKVM.Tools.Importer/MapXml/And.cs @@ -22,10 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Box.cs b/src/IKVM.Tools.Importer/MapXml/Box.cs index 989b8a28d..6c11c315a 100644 --- a/src/IKVM.Tools.Importer/MapXml/Box.cs +++ b/src/IKVM.Tools.Importer/MapXml/Box.cs @@ -22,10 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Call.cs b/src/IKVM.Tools.Importer/MapXml/Call.cs index f0f135ef5..b2049a101 100644 --- a/src/IKVM.Tools.Importer/MapXml/Call.cs +++ b/src/IKVM.Tools.Importer/MapXml/Call.cs @@ -25,14 +25,13 @@ Jeroen Frijters using System; using System.Diagnostics; using System.Linq; +using System.Reflection; +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection; -using IKVM.Reflection.Emit; +using IKVM.CoreLib.Symbols; using IKVM.Runtime; -using Type = IKVM.Reflection.Type; - namespace IKVM.Tools.Importer.MapXml { @@ -102,11 +101,10 @@ internal sealed override void Generate(CodeGenContext context, CodeEmitter ilgen Debug.Assert(Class == null && Type != null); var argTypes = context.ClassLoader.ArgTypeListFromSig(Sig); - var ci = context.ClassLoader.Context.Resolver.ResolveCoreType(Type).AsReflection().GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, CallingConventions.Standard, argTypes, null); + var ci = context.ClassLoader.Context.Resolver.ResolveCoreType(Type).GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, argTypes); if (ci == null) - { throw new InvalidOperationException("Missing .ctor: " + Type + "..ctor" + Sig); - } + ilgen.Emit(opcode, ci); } else @@ -176,37 +174,37 @@ internal sealed override void Generate(CodeGenContext context, CodeEmitter ilgen else { // ldftn or ldvirtftn - ilgen.Emit(opcode, (MethodInfo)method.GetMethod()); + ilgen.Emit(opcode, (IMethodSymbol)method.GetMethod()); } } else { - Type[] argTypes; + ITypeSymbol[] argTypes; if (Sig.StartsWith("(")) { argTypes = context.ClassLoader.ArgTypeListFromSig(Sig); } else if (Sig == "") { - argTypes = Reflection.Type.EmptyTypes; + argTypes = []; } else { - string[] types = Sig.Split(';'); - argTypes = new Type[types.Length]; + var types = Sig.Split(';'); + argTypes = new ITypeSymbol[types.Length]; for (int i = 0; i < types.Length; i++) { - argTypes[i] = context.ClassLoader.Context.Resolver.ResolveCoreType(types[i]).AsReflection(); + argTypes[i] = context.ClassLoader.Context.Resolver.ResolveCoreType(types[i]); } } - var ti = context.ClassLoader.Context.Resolver.ResolveCoreType(Type).AsReflection(); + var ti = context.ClassLoader.Context.Resolver.ResolveCoreType(Type); if (ti == null) { throw new InvalidOperationException("Missing type: " + Type); } - var mi = ti.GetMethod(Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static, null, argTypes, null); + var mi = ti.GetMethod(Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static, argTypes); if (mi == null) { var ta = argTypes.Select(i => i.AssemblyQualifiedName).ToArray(); diff --git a/src/IKVM.Tools.Importer/MapXml/Callvirt.cs b/src/IKVM.Tools.Importer/MapXml/Callvirt.cs index 3e235dcee..7070bb7da 100644 --- a/src/IKVM.Tools.Importer/MapXml/Callvirt.cs +++ b/src/IKVM.Tools.Importer/MapXml/Callvirt.cs @@ -22,10 +22,8 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using System.Xml.Serialization; - -using IKVM.Reflection.Emit; namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Castclass.cs b/src/IKVM.Tools.Importer/MapXml/Castclass.cs index d7f3ff7fc..c318013a6 100644 --- a/src/IKVM.Tools.Importer/MapXml/Castclass.cs +++ b/src/IKVM.Tools.Importer/MapXml/Castclass.cs @@ -22,9 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; using IKVM.Runtime; namespace IKVM.Tools.Importer.MapXml diff --git a/src/IKVM.Tools.Importer/MapXml/Castclass_impl.cs b/src/IKVM.Tools.Importer/MapXml/Castclass_impl.cs index e2c5d65a2..a7a2a6e7b 100644 --- a/src/IKVM.Tools.Importer/MapXml/Castclass_impl.cs +++ b/src/IKVM.Tools.Importer/MapXml/Castclass_impl.cs @@ -22,9 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; using IKVM.Runtime; namespace IKVM.Tools.Importer.MapXml diff --git a/src/IKVM.Tools.Importer/MapXml/Ceq.cs b/src/IKVM.Tools.Importer/MapXml/Ceq.cs index 8c6e1708a..79f488102 100644 --- a/src/IKVM.Tools.Importer/MapXml/Ceq.cs +++ b/src/IKVM.Tools.Importer/MapXml/Ceq.cs @@ -22,10 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Conv_I.cs b/src/IKVM.Tools.Importer/MapXml/Conv_I.cs index 73749adda..a7a8234bf 100644 --- a/src/IKVM.Tools.Importer/MapXml/Conv_I.cs +++ b/src/IKVM.Tools.Importer/MapXml/Conv_I.cs @@ -22,10 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Conv_I1.cs b/src/IKVM.Tools.Importer/MapXml/Conv_I1.cs index 856a49a39..e21e58b93 100644 --- a/src/IKVM.Tools.Importer/MapXml/Conv_I1.cs +++ b/src/IKVM.Tools.Importer/MapXml/Conv_I1.cs @@ -22,10 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Conv_I2.cs b/src/IKVM.Tools.Importer/MapXml/Conv_I2.cs index 29c660e99..d3ae5cd46 100644 --- a/src/IKVM.Tools.Importer/MapXml/Conv_I2.cs +++ b/src/IKVM.Tools.Importer/MapXml/Conv_I2.cs @@ -22,11 +22,10 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; using System.Xml.Serialization; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Conv_I4.cs b/src/IKVM.Tools.Importer/MapXml/Conv_I4.cs index c0dbd48d2..e17b6f0d0 100644 --- a/src/IKVM.Tools.Importer/MapXml/Conv_I4.cs +++ b/src/IKVM.Tools.Importer/MapXml/Conv_I4.cs @@ -22,10 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Conv_I8.cs b/src/IKVM.Tools.Importer/MapXml/Conv_I8.cs index 0072cb2e9..45dd0baf8 100644 --- a/src/IKVM.Tools.Importer/MapXml/Conv_I8.cs +++ b/src/IKVM.Tools.Importer/MapXml/Conv_I8.cs @@ -22,11 +22,10 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; using System.Xml.Serialization; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Conv_U1.cs b/src/IKVM.Tools.Importer/MapXml/Conv_U1.cs index 83d6dd75b..4d773cd86 100644 --- a/src/IKVM.Tools.Importer/MapXml/Conv_U1.cs +++ b/src/IKVM.Tools.Importer/MapXml/Conv_U1.cs @@ -22,11 +22,10 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; using System.Xml.Serialization; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Conv_U2.cs b/src/IKVM.Tools.Importer/MapXml/Conv_U2.cs index 6299552b2..be9d0ef06 100644 --- a/src/IKVM.Tools.Importer/MapXml/Conv_U2.cs +++ b/src/IKVM.Tools.Importer/MapXml/Conv_U2.cs @@ -22,11 +22,10 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; using System.Xml.Serialization; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Conv_U4.cs b/src/IKVM.Tools.Importer/MapXml/Conv_U4.cs index e91580b72..bb57703b7 100644 --- a/src/IKVM.Tools.Importer/MapXml/Conv_U4.cs +++ b/src/IKVM.Tools.Importer/MapXml/Conv_U4.cs @@ -22,11 +22,10 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; using System.Xml.Serialization; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Conv_U8.cs b/src/IKVM.Tools.Importer/MapXml/Conv_U8.cs index 37626248f..39a80a528 100644 --- a/src/IKVM.Tools.Importer/MapXml/Conv_U8.cs +++ b/src/IKVM.Tools.Importer/MapXml/Conv_U8.cs @@ -22,10 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Cpblk.cs b/src/IKVM.Tools.Importer/MapXml/Cpblk.cs index f10e19ea4..91e760075 100644 --- a/src/IKVM.Tools.Importer/MapXml/Cpblk.cs +++ b/src/IKVM.Tools.Importer/MapXml/Cpblk.cs @@ -22,11 +22,10 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; using System.Xml.Serialization; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Div_Un.cs b/src/IKVM.Tools.Importer/MapXml/Div_Un.cs index b625ecc83..9b19f11ec 100644 --- a/src/IKVM.Tools.Importer/MapXml/Div_Un.cs +++ b/src/IKVM.Tools.Importer/MapXml/Div_Un.cs @@ -22,11 +22,10 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; using System.Xml.Serialization; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Dup.cs b/src/IKVM.Tools.Importer/MapXml/Dup.cs index 2b6760e04..00b4bb568 100644 --- a/src/IKVM.Tools.Importer/MapXml/Dup.cs +++ b/src/IKVM.Tools.Importer/MapXml/Dup.cs @@ -22,11 +22,10 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; using System.Xml.Serialization; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Endfinally.cs b/src/IKVM.Tools.Importer/MapXml/Endfinally.cs index fac18f2ee..996c163d9 100644 --- a/src/IKVM.Tools.Importer/MapXml/Endfinally.cs +++ b/src/IKVM.Tools.Importer/MapXml/Endfinally.cs @@ -22,10 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/ExceptionBlock.cs b/src/IKVM.Tools.Importer/MapXml/ExceptionBlock.cs index 3658898d6..5f212b237 100644 --- a/src/IKVM.Tools.Importer/MapXml/ExceptionBlock.cs +++ b/src/IKVM.Tools.Importer/MapXml/ExceptionBlock.cs @@ -25,10 +25,9 @@ Jeroen Frijters using System.Linq; using System.Xml.Linq; +using IKVM.CoreLib.Symbols; using IKVM.Runtime; -using Type = IKVM.Reflection.Type; - namespace IKVM.Tools.Importer.MapXml { @@ -75,7 +74,7 @@ internal override void Generate(CodeGenContext context, CodeEmitter ilgen) if (Catch != null) { - Type type; + ITypeSymbol type; if (Catch.Type != null) { type = context.ClassLoader.Context.StaticCompiler.GetTypeForMapXml(context.ClassLoader, Catch.Type); diff --git a/src/IKVM.Tools.Importer/MapXml/IsInst.cs b/src/IKVM.Tools.Importer/MapXml/IsInst.cs index feecfa389..0f870a641 100644 --- a/src/IKVM.Tools.Importer/MapXml/IsInst.cs +++ b/src/IKVM.Tools.Importer/MapXml/IsInst.cs @@ -22,9 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; using IKVM.Runtime; namespace IKVM.Tools.Importer.MapXml diff --git a/src/IKVM.Tools.Importer/MapXml/LdArg_0.cs b/src/IKVM.Tools.Importer/MapXml/LdArg_0.cs index 5aa356dff..2b5b1d6f6 100644 --- a/src/IKVM.Tools.Importer/MapXml/LdArg_0.cs +++ b/src/IKVM.Tools.Importer/MapXml/LdArg_0.cs @@ -22,10 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/LdArg_1.cs b/src/IKVM.Tools.Importer/MapXml/LdArg_1.cs index 598cc5153..5ee7231e4 100644 --- a/src/IKVM.Tools.Importer/MapXml/LdArg_1.cs +++ b/src/IKVM.Tools.Importer/MapXml/LdArg_1.cs @@ -22,11 +22,10 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; using System.Xml.Serialization; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/LdArg_2.cs b/src/IKVM.Tools.Importer/MapXml/LdArg_2.cs index 7997962de..248938108 100644 --- a/src/IKVM.Tools.Importer/MapXml/LdArg_2.cs +++ b/src/IKVM.Tools.Importer/MapXml/LdArg_2.cs @@ -22,10 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/LdArg_3.cs b/src/IKVM.Tools.Importer/MapXml/LdArg_3.cs index b93ca145d..1e956278f 100644 --- a/src/IKVM.Tools.Importer/MapXml/LdArg_3.cs +++ b/src/IKVM.Tools.Importer/MapXml/LdArg_3.cs @@ -22,10 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/LdLoc.cs b/src/IKVM.Tools.Importer/MapXml/LdLoc.cs index 566a14310..d6b397069 100644 --- a/src/IKVM.Tools.Importer/MapXml/LdLoc.cs +++ b/src/IKVM.Tools.Importer/MapXml/LdLoc.cs @@ -22,9 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; using IKVM.Runtime; namespace IKVM.Tools.Importer.MapXml diff --git a/src/IKVM.Tools.Importer/MapXml/Ldc_I4_0.cs b/src/IKVM.Tools.Importer/MapXml/Ldc_I4_0.cs index afe746b5e..331f7c3b1 100644 --- a/src/IKVM.Tools.Importer/MapXml/Ldc_I4_0.cs +++ b/src/IKVM.Tools.Importer/MapXml/Ldc_I4_0.cs @@ -22,10 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Ldc_I4_1.cs b/src/IKVM.Tools.Importer/MapXml/Ldc_I4_1.cs index 2e055bd77..3d7e060e4 100644 --- a/src/IKVM.Tools.Importer/MapXml/Ldc_I4_1.cs +++ b/src/IKVM.Tools.Importer/MapXml/Ldc_I4_1.cs @@ -22,10 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Ldc_I4_M1.cs b/src/IKVM.Tools.Importer/MapXml/Ldc_I4_M1.cs index c9cb248b5..408ef0651 100644 --- a/src/IKVM.Tools.Importer/MapXml/Ldc_I4_M1.cs +++ b/src/IKVM.Tools.Importer/MapXml/Ldc_I4_M1.cs @@ -22,11 +22,10 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; using System.Xml.Serialization; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Ldelema.cs b/src/IKVM.Tools.Importer/MapXml/Ldelema.cs index 1b4688cda..90b99fccb 100644 --- a/src/IKVM.Tools.Importer/MapXml/Ldelema.cs +++ b/src/IKVM.Tools.Importer/MapXml/Ldelema.cs @@ -22,10 +22,10 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; using IKVM.Runtime; -using IKVM.Reflection.Emit; namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Ldfld.cs b/src/IKVM.Tools.Importer/MapXml/Ldfld.cs index 5a8869a54..d3659e7b7 100644 --- a/src/IKVM.Tools.Importer/MapXml/Ldfld.cs +++ b/src/IKVM.Tools.Importer/MapXml/Ldfld.cs @@ -22,10 +22,10 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; using IKVM.Runtime; -using IKVM.Reflection.Emit; namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Ldflda.cs b/src/IKVM.Tools.Importer/MapXml/Ldflda.cs index b8b7bbc10..fded0165d 100644 --- a/src/IKVM.Tools.Importer/MapXml/Ldflda.cs +++ b/src/IKVM.Tools.Importer/MapXml/Ldflda.cs @@ -22,9 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; using IKVM.Runtime; namespace IKVM.Tools.Importer.MapXml diff --git a/src/IKVM.Tools.Importer/MapXml/Ldftn.cs b/src/IKVM.Tools.Importer/MapXml/Ldftn.cs index 0c3395bae..f415d93a0 100644 --- a/src/IKVM.Tools.Importer/MapXml/Ldftn.cs +++ b/src/IKVM.Tools.Importer/MapXml/Ldftn.cs @@ -22,10 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Ldind_i1.cs b/src/IKVM.Tools.Importer/MapXml/Ldind_i1.cs index 5ee93d4cb..3e0e9dd4a 100644 --- a/src/IKVM.Tools.Importer/MapXml/Ldind_i1.cs +++ b/src/IKVM.Tools.Importer/MapXml/Ldind_i1.cs @@ -22,10 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Ldind_i2.cs b/src/IKVM.Tools.Importer/MapXml/Ldind_i2.cs index 02f96718c..d45bf0908 100644 --- a/src/IKVM.Tools.Importer/MapXml/Ldind_i2.cs +++ b/src/IKVM.Tools.Importer/MapXml/Ldind_i2.cs @@ -22,11 +22,10 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; using System.Xml.Serialization; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Ldind_i4.cs b/src/IKVM.Tools.Importer/MapXml/Ldind_i4.cs index d2631f1a8..19c9dfcf6 100644 --- a/src/IKVM.Tools.Importer/MapXml/Ldind_i4.cs +++ b/src/IKVM.Tools.Importer/MapXml/Ldind_i4.cs @@ -22,10 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Ldind_i8.cs b/src/IKVM.Tools.Importer/MapXml/Ldind_i8.cs index 4dc7dee7d..2eb4c82af 100644 --- a/src/IKVM.Tools.Importer/MapXml/Ldind_i8.cs +++ b/src/IKVM.Tools.Importer/MapXml/Ldind_i8.cs @@ -22,10 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Ldind_r4.cs b/src/IKVM.Tools.Importer/MapXml/Ldind_r4.cs index 9e9194e72..d6b32a66c 100644 --- a/src/IKVM.Tools.Importer/MapXml/Ldind_r4.cs +++ b/src/IKVM.Tools.Importer/MapXml/Ldind_r4.cs @@ -22,11 +22,10 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; using System.Xml.Serialization; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Ldind_r8.cs b/src/IKVM.Tools.Importer/MapXml/Ldind_r8.cs index 638c8254d..e7edaee8e 100644 --- a/src/IKVM.Tools.Importer/MapXml/Ldind_r8.cs +++ b/src/IKVM.Tools.Importer/MapXml/Ldind_r8.cs @@ -22,11 +22,10 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; using System.Xml.Serialization; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Ldind_ref.cs b/src/IKVM.Tools.Importer/MapXml/Ldind_ref.cs index 2e1e04878..3efc3151d 100644 --- a/src/IKVM.Tools.Importer/MapXml/Ldind_ref.cs +++ b/src/IKVM.Tools.Importer/MapXml/Ldind_ref.cs @@ -22,10 +22,8 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using System.Xml.Serialization; - -using IKVM.Reflection.Emit; namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Ldlen.cs b/src/IKVM.Tools.Importer/MapXml/Ldlen.cs index e134943bf..d1453c6ed 100644 --- a/src/IKVM.Tools.Importer/MapXml/Ldlen.cs +++ b/src/IKVM.Tools.Importer/MapXml/Ldlen.cs @@ -22,10 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Ldnull.cs b/src/IKVM.Tools.Importer/MapXml/Ldnull.cs index 6034da1d3..3f6a09831 100644 --- a/src/IKVM.Tools.Importer/MapXml/Ldnull.cs +++ b/src/IKVM.Tools.Importer/MapXml/Ldnull.cs @@ -22,10 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Ldobj.cs b/src/IKVM.Tools.Importer/MapXml/Ldobj.cs index 6977dbbe7..0342abe9f 100644 --- a/src/IKVM.Tools.Importer/MapXml/Ldobj.cs +++ b/src/IKVM.Tools.Importer/MapXml/Ldobj.cs @@ -22,10 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Ldsfld.cs b/src/IKVM.Tools.Importer/MapXml/Ldsfld.cs index e656ad8b2..6b5e24425 100644 --- a/src/IKVM.Tools.Importer/MapXml/Ldsfld.cs +++ b/src/IKVM.Tools.Importer/MapXml/Ldsfld.cs @@ -22,10 +22,10 @@ Jeroen Frijters */ +using System.Reflection; +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection; -using IKVM.Reflection.Emit; using IKVM.Runtime; namespace IKVM.Tools.Importer.MapXml diff --git a/src/IKVM.Tools.Importer/MapXml/Ldstr.cs b/src/IKVM.Tools.Importer/MapXml/Ldstr.cs index 3cc6e13ce..31652d7bf 100644 --- a/src/IKVM.Tools.Importer/MapXml/Ldstr.cs +++ b/src/IKVM.Tools.Importer/MapXml/Ldstr.cs @@ -22,9 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; using IKVM.Runtime; namespace IKVM.Tools.Importer.MapXml diff --git a/src/IKVM.Tools.Importer/MapXml/Ldtoken.cs b/src/IKVM.Tools.Importer/MapXml/Ldtoken.cs index 57aa18b15..ede00503d 100644 --- a/src/IKVM.Tools.Importer/MapXml/Ldtoken.cs +++ b/src/IKVM.Tools.Importer/MapXml/Ldtoken.cs @@ -23,15 +23,12 @@ Jeroen Frijters */ using System; +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.CoreLib.Diagnostics; -using IKVM.Reflection; -using IKVM.Reflection.Emit; +using IKVM.CoreLib.Symbols; using IKVM.Runtime; -using Type = IKVM.Reflection.Type; - namespace IKVM.Tools.Importer.MapXml { @@ -79,15 +76,13 @@ public static void Load(Ldtoken inst, XElement element) internal override void Generate(CodeGenContext context, CodeEmitter ilgen) { if (!Validate(context)) - { return; - } - MemberInfo member = Resolve(context); - Type type = member as Type; - MethodInfo method = member as MethodInfo; - ConstructorInfo constructor = member as ConstructorInfo; - FieldInfo field = member as FieldInfo; + var member = Resolve(context); + var type = member as ITypeSymbol; + var method = member as IMethodSymbol; + var constructor = member as IConstructorSymbol; + var field = member as IFieldSymbol; if (type != null) { @@ -146,14 +141,13 @@ private bool Validate(CodeGenContext context) } } - private MemberInfo Resolve(CodeGenContext context) + private IMemberSymbol Resolve(CodeGenContext context) { if (Type != null) { if (Class != null || Method != null || Field != null || Sig != null) - { throw new NotImplementedException(); - } + return context.ClassLoader.Context.StaticCompiler.GetTypeForMapXml(context.ClassLoader, Type); } else if (Class != null) @@ -167,18 +161,16 @@ private MemberInfo Resolve(CodeGenContext context) { var mw = tw.GetMethodWrapper(Method, Sig, false); if (mw == null) - { return null; - } + return mw.GetMethod(); } else if (Field != null) { var fw = tw.GetFieldWrapper(Field, Sig); if (fw == null) - { return null; - } + return fw.GetField(); } else diff --git a/src/IKVM.Tools.Importer/MapXml/Ldvirtftn.cs b/src/IKVM.Tools.Importer/MapXml/Ldvirtftn.cs index 27737ce64..32c147931 100644 --- a/src/IKVM.Tools.Importer/MapXml/Ldvirtftn.cs +++ b/src/IKVM.Tools.Importer/MapXml/Ldvirtftn.cs @@ -21,11 +21,8 @@ Jeroen Frijters jeroen@frijters.net */ - +using System.Reflection.Emit; using System.Xml.Linq; -using System.Xml.Serialization; - -using IKVM.Reflection.Emit; namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/MapXmlSerializer.cs b/src/IKVM.Tools.Importer/MapXml/MapXmlSerializer.cs index 865777f23..46e178106 100644 --- a/src/IKVM.Tools.Importer/MapXml/MapXmlSerializer.cs +++ b/src/IKVM.Tools.Importer/MapXml/MapXmlSerializer.cs @@ -1,9 +1,8 @@ using System; using System.Linq; +using System.Reflection; using System.Xml.Linq; -using IKVM.Reflection; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/MethodBase.cs b/src/IKVM.Tools.Importer/MapXml/MethodBase.cs index fb710de50..407a70a64 100644 --- a/src/IKVM.Tools.Importer/MapXml/MethodBase.cs +++ b/src/IKVM.Tools.Importer/MapXml/MethodBase.cs @@ -23,9 +23,9 @@ Jeroen Frijters */ using System.Linq; +using System.Reflection; using System.Xml.Linq; -using IKVM.Reflection; using IKVM.Runtime; namespace IKVM.Tools.Importer.MapXml diff --git a/src/IKVM.Tools.Importer/MapXml/Mul.cs b/src/IKVM.Tools.Importer/MapXml/Mul.cs index dabdba106..666aaa5a8 100644 --- a/src/IKVM.Tools.Importer/MapXml/Mul.cs +++ b/src/IKVM.Tools.Importer/MapXml/Mul.cs @@ -22,10 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/NewObj.cs b/src/IKVM.Tools.Importer/MapXml/NewObj.cs index 3cea26ab5..68db92fbf 100644 --- a/src/IKVM.Tools.Importer/MapXml/NewObj.cs +++ b/src/IKVM.Tools.Importer/MapXml/NewObj.cs @@ -22,10 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Newarr.cs b/src/IKVM.Tools.Importer/MapXml/Newarr.cs index 5b3223ade..d517252ab 100644 --- a/src/IKVM.Tools.Importer/MapXml/Newarr.cs +++ b/src/IKVM.Tools.Importer/MapXml/Newarr.cs @@ -22,10 +22,10 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; using IKVM.Runtime; -using IKVM.Reflection.Emit; namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Not.cs b/src/IKVM.Tools.Importer/MapXml/Not.cs index 1890f95e3..674875372 100644 --- a/src/IKVM.Tools.Importer/MapXml/Not.cs +++ b/src/IKVM.Tools.Importer/MapXml/Not.cs @@ -22,11 +22,10 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; using System.Xml.Serialization; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Or.cs b/src/IKVM.Tools.Importer/MapXml/Or.cs index 9f397086e..13c6de5fd 100644 --- a/src/IKVM.Tools.Importer/MapXml/Or.cs +++ b/src/IKVM.Tools.Importer/MapXml/Or.cs @@ -22,10 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Pop.cs b/src/IKVM.Tools.Importer/MapXml/Pop.cs index 9a6ac8092..cd275e7b0 100644 --- a/src/IKVM.Tools.Importer/MapXml/Pop.cs +++ b/src/IKVM.Tools.Importer/MapXml/Pop.cs @@ -22,9 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; using IKVM.Runtime; namespace IKVM.Tools.Importer.MapXml diff --git a/src/IKVM.Tools.Importer/MapXml/Redirect.cs b/src/IKVM.Tools.Importer/MapXml/Redirect.cs index 57951eaef..18096da63 100644 --- a/src/IKVM.Tools.Importer/MapXml/Redirect.cs +++ b/src/IKVM.Tools.Importer/MapXml/Redirect.cs @@ -23,14 +23,11 @@ Jeroen Frijters */ using System; +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection; -using IKVM.Reflection.Emit; using IKVM.Runtime; -using Type = IKVM.Reflection.Type; - namespace IKVM.Tools.Importer.MapXml { @@ -85,12 +82,11 @@ internal void Emit(RuntimeClassLoader loader, CodeEmitter ilgen) // HACK if the class name contains a comma, we assume it is a .NET type if (Type != null) { - var type = loader.Context.Resolver.ResolveCoreType(Type).AsReflection(); + var type = loader.Context.Resolver.ResolveCoreType(Type); var mi = type.GetMethod(Name, redirParamTypes); if (mi == null) - { throw new InvalidOperationException(); - } + ilgen.Emit(OpCodes.Call, mi); } else diff --git a/src/IKVM.Tools.Importer/MapXml/Rem_Un.cs b/src/IKVM.Tools.Importer/MapXml/Rem_Un.cs index 8b6a21f6c..6ece91caa 100644 --- a/src/IKVM.Tools.Importer/MapXml/Rem_Un.cs +++ b/src/IKVM.Tools.Importer/MapXml/Rem_Un.cs @@ -22,10 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Ret.cs b/src/IKVM.Tools.Importer/MapXml/Ret.cs index 5241e3283..37fb3e5e5 100644 --- a/src/IKVM.Tools.Importer/MapXml/Ret.cs +++ b/src/IKVM.Tools.Importer/MapXml/Ret.cs @@ -22,10 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Simple.cs b/src/IKVM.Tools.Importer/MapXml/Simple.cs index 7d2a9db17..bcaba124d 100644 --- a/src/IKVM.Tools.Importer/MapXml/Simple.cs +++ b/src/IKVM.Tools.Importer/MapXml/Simple.cs @@ -21,10 +21,9 @@ Jeroen Frijters jeroen@frijters.net */ - +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; using IKVM.Runtime; namespace IKVM.Tools.Importer.MapXml diff --git a/src/IKVM.Tools.Importer/MapXml/StLoc.cs b/src/IKVM.Tools.Importer/MapXml/StLoc.cs index d2fb66850..b97b89d44 100644 --- a/src/IKVM.Tools.Importer/MapXml/StLoc.cs +++ b/src/IKVM.Tools.Importer/MapXml/StLoc.cs @@ -23,13 +23,12 @@ Jeroen Frijters */ using System.Diagnostics; +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; +using IKVM.CoreLib.Symbols; using IKVM.Runtime; -using Type = IKVM.Reflection.Type; - namespace IKVM.Tools.Importer.MapXml { @@ -63,7 +62,7 @@ public static void Load(StLoc inst, XElement element) } RuntimeJavaType typeWrapper; - Type typeType; + ITypeSymbol typeType; public string Name { get; set; } diff --git a/src/IKVM.Tools.Importer/MapXml/Stfld.cs b/src/IKVM.Tools.Importer/MapXml/Stfld.cs index 2f658147e..4f5a26019 100644 --- a/src/IKVM.Tools.Importer/MapXml/Stfld.cs +++ b/src/IKVM.Tools.Importer/MapXml/Stfld.cs @@ -22,9 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; using IKVM.Runtime; namespace IKVM.Tools.Importer.MapXml diff --git a/src/IKVM.Tools.Importer/MapXml/Stind_i1.cs b/src/IKVM.Tools.Importer/MapXml/Stind_i1.cs index a58f813db..bcefaa6dc 100644 --- a/src/IKVM.Tools.Importer/MapXml/Stind_i1.cs +++ b/src/IKVM.Tools.Importer/MapXml/Stind_i1.cs @@ -22,11 +22,10 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; using System.Xml.Serialization; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Stind_i2.cs b/src/IKVM.Tools.Importer/MapXml/Stind_i2.cs index dc1bb863a..a4b7858bb 100644 --- a/src/IKVM.Tools.Importer/MapXml/Stind_i2.cs +++ b/src/IKVM.Tools.Importer/MapXml/Stind_i2.cs @@ -22,10 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Stind_i4.cs b/src/IKVM.Tools.Importer/MapXml/Stind_i4.cs index 67f423153..d5e61f885 100644 --- a/src/IKVM.Tools.Importer/MapXml/Stind_i4.cs +++ b/src/IKVM.Tools.Importer/MapXml/Stind_i4.cs @@ -22,11 +22,10 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; using System.Xml.Serialization; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Stind_i8.cs b/src/IKVM.Tools.Importer/MapXml/Stind_i8.cs index 36fb4abec..c0de5001d 100644 --- a/src/IKVM.Tools.Importer/MapXml/Stind_i8.cs +++ b/src/IKVM.Tools.Importer/MapXml/Stind_i8.cs @@ -22,11 +22,10 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; using System.Xml.Serialization; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Stind_ref.cs b/src/IKVM.Tools.Importer/MapXml/Stind_ref.cs index 1d653482b..b30e8b40b 100644 --- a/src/IKVM.Tools.Importer/MapXml/Stind_ref.cs +++ b/src/IKVM.Tools.Importer/MapXml/Stind_ref.cs @@ -22,10 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Stsfld.cs b/src/IKVM.Tools.Importer/MapXml/Stsfld.cs index 9d95d93e9..0233b8cd5 100644 --- a/src/IKVM.Tools.Importer/MapXml/Stsfld.cs +++ b/src/IKVM.Tools.Importer/MapXml/Stsfld.cs @@ -22,9 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; using IKVM.Runtime; namespace IKVM.Tools.Importer.MapXml diff --git a/src/IKVM.Tools.Importer/MapXml/Sub.cs b/src/IKVM.Tools.Importer/MapXml/Sub.cs index 1c2af5ec3..a5080691c 100644 --- a/src/IKVM.Tools.Importer/MapXml/Sub.cs +++ b/src/IKVM.Tools.Importer/MapXml/Sub.cs @@ -22,11 +22,10 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; using System.Xml.Serialization; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Throw.cs b/src/IKVM.Tools.Importer/MapXml/Throw.cs index 0f384cf82..8995e5b90 100644 --- a/src/IKVM.Tools.Importer/MapXml/Throw.cs +++ b/src/IKVM.Tools.Importer/MapXml/Throw.cs @@ -22,10 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/TypeInstruction.cs b/src/IKVM.Tools.Importer/MapXml/TypeInstruction.cs index 5da986a1c..3c39e1fe9 100644 --- a/src/IKVM.Tools.Importer/MapXml/TypeInstruction.cs +++ b/src/IKVM.Tools.Importer/MapXml/TypeInstruction.cs @@ -23,13 +23,12 @@ Jeroen Frijters */ using System.Diagnostics; +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; +using IKVM.CoreLib.Symbols; using IKVM.Runtime; -using Type = IKVM.Reflection.Type; - namespace IKVM.Tools.Importer.MapXml { @@ -42,7 +41,7 @@ public static void Load(TypeInstruction inst, XElement element) } readonly OpCode opcode; - Type typeType; + ITypeSymbol typeType; public string Type { get; set; } diff --git a/src/IKVM.Tools.Importer/MapXml/TypeOrTypeWrapperInstruction.cs b/src/IKVM.Tools.Importer/MapXml/TypeOrTypeWrapperInstruction.cs index 035722356..7e1fcdcbc 100644 --- a/src/IKVM.Tools.Importer/MapXml/TypeOrTypeWrapperInstruction.cs +++ b/src/IKVM.Tools.Importer/MapXml/TypeOrTypeWrapperInstruction.cs @@ -25,10 +25,9 @@ Jeroen Frijters using System.Diagnostics; using System.Xml.Linq; +using IKVM.CoreLib.Symbols; using IKVM.Runtime; -using Type = IKVM.Reflection.Type; - namespace IKVM.Tools.Importer.MapXml { @@ -49,7 +48,7 @@ public static void Load(TypeOrTypeWrapperInstruction inst, XElement element) } internal RuntimeJavaType typeWrapper; - internal Type typeType; + internal ITypeSymbol typeType; public string Class { get; set; } diff --git a/src/IKVM.Tools.Importer/MapXml/Unbox.cs b/src/IKVM.Tools.Importer/MapXml/Unbox.cs index cdf4c43bc..a23f7c0a7 100644 --- a/src/IKVM.Tools.Importer/MapXml/Unbox.cs +++ b/src/IKVM.Tools.Importer/MapXml/Unbox.cs @@ -22,10 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Volatile.cs b/src/IKVM.Tools.Importer/MapXml/Volatile.cs index e27751f58..77492c13c 100644 --- a/src/IKVM.Tools.Importer/MapXml/Volatile.cs +++ b/src/IKVM.Tools.Importer/MapXml/Volatile.cs @@ -22,10 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/MapXml/Xor.cs b/src/IKVM.Tools.Importer/MapXml/Xor.cs index 07087346a..d014fdb12 100644 --- a/src/IKVM.Tools.Importer/MapXml/Xor.cs +++ b/src/IKVM.Tools.Importer/MapXml/Xor.cs @@ -22,10 +22,9 @@ Jeroen Frijters */ +using System.Reflection.Emit; using System.Xml.Linq; -using IKVM.Reflection.Emit; - namespace IKVM.Tools.Importer.MapXml { diff --git a/src/IKVM.Tools.Importer/Proxy.cs b/src/IKVM.Tools.Importer/Proxy.cs index e1cd97095..2c1717e7e 100644 --- a/src/IKVM.Tools.Importer/Proxy.cs +++ b/src/IKVM.Tools.Importer/Proxy.cs @@ -23,14 +23,14 @@ Jeroen Frijters */ using System; using System.Collections.Generic; +using System.Reflection; +using System.Reflection.Emit; using IKVM.Attributes; -using IKVM.Reflection; -using IKVM.Reflection.Emit; +using IKVM.CoreLib.Symbols; +using IKVM.CoreLib.Symbols.Emit; using IKVM.Runtime; -using Type = IKVM.Reflection.Type; - namespace IKVM.Tools.Importer { @@ -230,7 +230,7 @@ static RuntimeJavaType[] Merge(RuntimeJavaType[] newExceptionTypes, RuntimeJavaT void CreateNoFail(ImportClassLoader loader, RuntimeJavaType[] interfaces, List methods) { var ispublic = true; - var interfaceTypes = new Type[interfaces.Length]; + var interfaceTypes = new ITypeSymbol[interfaces.Length]; for (int i = 0; i < interfaceTypes.Length; i++) { ispublic &= interfaces[i].IsPublic; @@ -253,9 +253,9 @@ void CreateNoFail(ImportClassLoader loader, RuntimeJavaType[] interfaces, List

(); @@ -358,14 +358,15 @@ void CreateMethod(ImportClassLoader loader, TypeBuilder tb, ProxyMethod pm) ilgen.DoEmit(); } - void CreateStaticInitializer(TypeBuilder tb, List methods, ImportClassLoader loader) + void CreateStaticInitializer(ITypeSymbolBuilder tb, List methods, ImportClassLoader loader) { var ilgen = loader.Context.CodeEmitterFactory.Create(ReflectUtil.DefineTypeInitializer(tb, loader)); var callerID = ilgen.DeclareLocal(loader.Context.JavaBase.TypeOfIkvmInternalCallerID.TypeAsSignatureType); var tbCallerID = RuntimeByteCodeJavaType.FinishContext.EmitCreateCallerID(loader.Context, tb, ilgen); ilgen.Emit(OpCodes.Stloc, callerID); // HACK we shouldn't create the nested type here (the outer type must be created first) - tbCallerID.CreateType(); + tbCallerID.Complete(); + ilgen.BeginExceptionBlock(); foreach (ProxyMethod method in methods) { @@ -405,7 +406,7 @@ sealed class ProxyMethod internal readonly RuntimeJavaMethod mw; internal readonly RuntimeJavaType[] exceptions; - internal FieldBuilder fb; + internal IFieldSymbolBuilder fb; internal ProxyMethod(RuntimeJavaMethod mw, RuntimeJavaType[] exceptions) { diff --git a/src/IKVM.Tools.Importer/RuntimeImportByteCodeJavaType.cs b/src/IKVM.Tools.Importer/RuntimeImportByteCodeJavaType.cs index 9712f24ac..f6b342afd 100644 --- a/src/IKVM.Tools.Importer/RuntimeImportByteCodeJavaType.cs +++ b/src/IKVM.Tools.Importer/RuntimeImportByteCodeJavaType.cs @@ -24,18 +24,16 @@ Jeroen Frijters using System; using System.Collections.Generic; +using System.Reflection; +using System.Reflection.Emit; using IKVM.Attributes; using IKVM.CoreLib.Diagnostics; using IKVM.CoreLib.Symbols; using IKVM.CoreLib.Symbols.Emit; -using IKVM.Reflection; -using IKVM.Reflection.Emit; using IKVM.Runtime; using IKVM.Tools.Importer.MapXml; -using Type = IKVM.Reflection.Type; - namespace IKVM.Tools.Importer { @@ -131,7 +129,7 @@ internal void GetParameterNamesFromXml(string methodName, string methodSig, stri parameterNames[i] = parameters[i].Name; } - internal void AddXmlMapParameterAttributes(IMethodSymbolBuilder method, string className, string methodName, string methodSig, ref ParameterBuilder[] parameterBuilders) + internal void AddXmlMapParameterAttributes(IMethodSymbolBuilder method, string className, string methodName, string methodSig, ref IParameterSymbolBuilder[] parameterBuilders) { var parameters = classLoader.GetXmlMapParameters(className, methodName, methodSig); if (parameters != null) @@ -149,7 +147,7 @@ internal void AddXmlMapParameterAttributes(IMethodSymbolBuilder method, string c private void AddParameterMetadata(IMethodSymbolBuilder method, RuntimeJavaMethod mw) { - ParameterBuilder[] pbs; + IParameterSymbolBuilder[] pbs; if ((mw.DeclaringType.IsPublic && (mw.IsPublic || mw.IsProtected)) || classLoader.EmitSymbols) { string[] parameterNames = new string[mw.GetParameters().Length]; @@ -323,16 +321,14 @@ private void PublishProperties(ITypeSymbolBuilder typeBuilder, Class clazz) if (m == null || m.DeclaringType != typeBuilder || (!m.IsFinal && final)) { var mb = typeBuilder.DefineMethod("get_" + prop.Name, GetPropertyMethodAttributes(mw, final), typeWrapper.TypeAsSignatureType, indexer); - m = mb.Symbol; Context.AttributeHelper.HideFromJava(mb); var ilgen = Context.CodeEmitterFactory.Create(mb); if (mw.IsStatic) { for (int i = 0; i < indexer.Length; i++) - { ilgen.EmitLdarg(i); - } + mw.EmitCall(ilgen); } else @@ -363,7 +359,6 @@ private void PublishProperties(ITypeSymbolBuilder typeBuilder, Class clazz) if (m == null || m.DeclaringType != typeBuilder || (!m.IsFinal && final)) { var mb = typeBuilder.DefineMethod("set_" + prop.Name, GetPropertyMethodAttributes(mw, final), mw.ReturnTypeForDefineMethod, args); - m = mb.Symbol; Context.AttributeHelper.HideFromJava(mb); var ilgen = Context.CodeEmitterFactory.Create(mb); @@ -371,6 +366,7 @@ private void PublishProperties(ITypeSymbolBuilder typeBuilder, Class clazz) { for (int i = 0; i <= indexer.Length; i++) ilgen.EmitLdarg(i); + mw.EmitCall(ilgen); } else @@ -378,6 +374,7 @@ private void PublishProperties(ITypeSymbolBuilder typeBuilder, Class clazz) ilgen.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); for (int i = 0; i <= indexer.Length; i++) ilgen.EmitLdarg(i + 1); + mw.EmitCallvirt(ilgen); } @@ -489,7 +486,7 @@ protected override void EmitMapXmlMetadata(ITypeSymbolBuilder typeBuilder, Class { if (fw.Name == field.Name && fw.Signature == field.Sig) { - var fb = fw.GetField() as FieldBuilder; + var fb = fw.GetField() as IFieldSymbolBuilder; if (fb != null) foreach (var attr in field.Attributes) Context.AttributeHelper.SetCustomAttribute(classLoader, fb, attr); @@ -537,7 +534,7 @@ protected override void EmitMapXmlMetadata(ITypeSymbolBuilder typeBuilder, Class { if (mw.Name == "" && mw.Signature == constructor.Sig) { - var mb = mw.GetMethod() as MethodBuilder; + var mb = mw.GetMethod() as IMethodSymbolBuilder; if (mb != null) foreach (var attr in constructor.Attributes) Context.AttributeHelper.SetCustomAttribute(classLoader, mb, attr); @@ -573,7 +570,7 @@ protected override void EmitMapXmlMetadata(ITypeSymbolBuilder typeBuilder, Class { var mw = ClassLoader.LoadClassByName(method.Override.Class).GetMethodWrapper(method.Override.Name, method.Sig, true); mw.Link(); - typeBuilder.DefineMethodOverride(mb, (MethodInfo)mw.GetMethod()); + typeBuilder.DefineMethodOverride(mb, (IMethodSymbol)mw.GetMethod()); } ImportClassLoader.AddDeclaredExceptions(Context, mb, method.Throws); @@ -598,7 +595,7 @@ protected override void EmitMapXmlMetadata(ITypeSymbolBuilder typeBuilder, Class { if (mw.Name == method.Name && mw.Signature == method.Sig) { - MethodBuilder mb = mw.GetMethod() as MethodBuilder; + var mb = mw.GetMethod() as IMethodSymbolBuilder; if (mb != null) { foreach (IKVM.Tools.Importer.MapXml.Attribute attr in method.Attributes) @@ -611,6 +608,7 @@ protected override void EmitMapXmlMetadata(ITypeSymbolBuilder typeBuilder, Class } } } + if (clazz.Interfaces != null) { foreach (var iface in clazz.Interfaces) @@ -631,7 +629,7 @@ protected override void EmitMapXmlMetadata(ITypeSymbolBuilder typeBuilder, Class var mb = mw.GetDefineMethodHelper().DefineMethod(this, typeBuilder, tw.Name + "/" + m.Name, System.Reflection.MethodAttributes.Private | System.Reflection.MethodAttributes.NewSlot | System.Reflection.MethodAttributes.Virtual | System.Reflection.MethodAttributes.Final | System.Reflection.MethodAttributes.CheckAccessOnOverride); Context.AttributeHelper.HideFromJava(mb); typeBuilder.DefineMethodOverride(mb, (IMethodSymbol)mw.GetMethod()); - CodeEmitter ilgen = Context.CodeEmitterFactory.Create(mb); + var ilgen = Context.CodeEmitterFactory.Create(mb); m.Emit(classLoader, ilgen); ilgen.DoEmit(); } @@ -642,7 +640,7 @@ protected override void EmitMapXmlMetadata(ITypeSymbolBuilder typeBuilder, Class } } - protected override MethodBuilder DefineGhostMethod(ITypeSymbolBuilder typeBuilder, string name, System.Reflection.MethodAttributes attribs, RuntimeJavaMethod mw) + protected override IMethodSymbolBuilder DefineGhostMethod(ITypeSymbolBuilder typeBuilder, string name, System.Reflection.MethodAttributes attribs, RuntimeJavaMethod mw) { if (typeBuilderGhostInterface != null && mw.IsVirtual) { @@ -733,14 +731,14 @@ protected override void FinishGhost(ITypeSymbolBuilder typeBuilder, RuntimeJavaM // HACK create a scope to enable reuse of "implementers" name if (true) { - MethodBuilder mb; + IMethodSymbolBuilder mb; CodeEmitter ilgen; CodeEmitterLocal local; // add implicit conversions for all the ghost implementers var implementers = classLoader.GetGhostImplementers(this); for (int i = 0; i < implementers.Length; i++) { - mb = typeBuilder.DefineMethod("op_Implicit", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.SpecialName, TypeAsSignatureType, new Type[] { implementers[i].TypeAsSignatureType }); + mb = typeBuilder.DefineMethod("op_Implicit", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.SpecialName, TypeAsSignatureType, new[] { implementers[i].TypeAsSignatureType }); Context.AttributeHelper.HideFromJava(mb); ilgen = Context.CodeEmitterFactory.Create(mb); local = ilgen.DeclareLocal(TypeAsSignatureType); @@ -752,21 +750,23 @@ protected override void FinishGhost(ITypeSymbolBuilder typeBuilder, RuntimeJavaM ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); } + // Implement the "IsInstance" method mb = ghostIsInstanceMethod; Context.AttributeHelper.HideFromJava(mb); ilgen = Context.CodeEmitterFactory.Create(mb); - CodeEmitterLabel end = ilgen.DefineLabel(); + var end = ilgen.DefineLabel(); for (int i = 0; i < implementers.Length; i++) { ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Isinst, implementers[i].TypeAsTBD); - CodeEmitterLabel label = ilgen.DefineLabel(); + var label = ilgen.DefineLabel(); ilgen.EmitBrfalse(label); ilgen.Emit(OpCodes.Ldc_I4_1); ilgen.EmitBr(end); ilgen.MarkLabel(label); } + ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Isinst, typeBuilderGhostInterface); ilgen.Emit(OpCodes.Ldnull); @@ -774,6 +774,7 @@ protected override void FinishGhost(ITypeSymbolBuilder typeBuilder, RuntimeJavaM ilgen.MarkLabel(end); ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); + // Implement the "IsInstanceArray" method mb = ghostIsInstanceArrayMethod; Context.AttributeHelper.HideFromJava(mb); @@ -864,7 +865,7 @@ protected override void FinishGhost(ITypeSymbolBuilder typeBuilder, RuntimeJavaM ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); // Add "ToObject" methods - mb = typeBuilder.DefineMethod("ToObject", MethodAttributes.HideBySig | MethodAttributes.Public, Context.Types.Object, Type.EmptyTypes); + mb = typeBuilder.DefineMethod("ToObject", MethodAttributes.HideBySig | MethodAttributes.Public, Context.Types.Object, []); Context.AttributeHelper.HideFromJava(mb); ilgen = Context.CodeEmitterFactory.Create(mb); ilgen.Emit(OpCodes.Ldarg_0); @@ -889,13 +890,13 @@ protected override void FinishGhost(ITypeSymbolBuilder typeBuilder, RuntimeJavaM ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Ldtoken, typeBuilder); ilgen.Emit(OpCodes.Ldarg_1); - ilgen.Emit(OpCodes.Call, Context.Resolver.ResolveRuntimeType(typeof(IKVM.Runtime.GhostTag).FullName).AsReflection().GetMethod("ThrowClassCastException", BindingFlags.NonPublic | BindingFlags.Static)); + ilgen.Emit(OpCodes.Call, Context.Resolver.ResolveRuntimeType(typeof(IKVM.Runtime.GhostTag).FullName).GetMethod("ThrowClassCastException", BindingFlags.NonPublic | BindingFlags.Static)); ilgen.MarkLabel(end); ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); // Implement the "Equals" method - mb = typeBuilder.DefineMethod("Equals", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Virtual, Context.Types.Boolean, new Type[] { Context.Types.Object }); + mb = typeBuilder.DefineMethod("Equals", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Virtual, Context.Types.Boolean, [Context.Types.Object]); Context.AttributeHelper.HideFromJava(mb); ilgen = Context.CodeEmitterFactory.Create(mb); ilgen.Emit(OpCodes.Ldarg_0); @@ -906,7 +907,7 @@ protected override void FinishGhost(ITypeSymbolBuilder typeBuilder, RuntimeJavaM ilgen.DoEmit(); // Implement the "GetHashCode" method - mb = typeBuilder.DefineMethod("GetHashCode", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Virtual, Context.Types.Int32, Type.EmptyTypes); + mb = typeBuilder.DefineMethod("GetHashCode", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Virtual, Context.Types.Int32, []); Context.AttributeHelper.HideFromJava(mb); ilgen = Context.CodeEmitterFactory.Create(mb); ilgen.Emit(OpCodes.Ldarg_0); @@ -916,7 +917,7 @@ protected override void FinishGhost(ITypeSymbolBuilder typeBuilder, RuntimeJavaM ilgen.DoEmit(); // Implement the "op_Equality" method - mb = typeBuilder.DefineMethod("op_Equality", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.SpecialName, Context.Types.Boolean, new Type[] { typeBuilder, typeBuilder }); + mb = typeBuilder.DefineMethod("op_Equality", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.SpecialName, Context.Types.Boolean, [typeBuilder, typeBuilder]); Context.AttributeHelper.HideFromJava(mb); ilgen = Context.CodeEmitterFactory.Create(mb); ilgen.EmitLdarga(0); @@ -928,7 +929,7 @@ protected override void FinishGhost(ITypeSymbolBuilder typeBuilder, RuntimeJavaM ilgen.DoEmit(); // Implement the "op_Inequality" method - mb = typeBuilder.DefineMethod("op_Inequality", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.SpecialName, Context.Types.Boolean, new Type[] { typeBuilder, typeBuilder }); + mb = typeBuilder.DefineMethod("op_Inequality", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.SpecialName, Context.Types.Boolean, [typeBuilder, typeBuilder]); Context.AttributeHelper.HideFromJava(mb); ilgen = Context.CodeEmitterFactory.Create(mb); ilgen.EmitLdarga(0); @@ -946,27 +947,27 @@ protected override void FinishGhost(ITypeSymbolBuilder typeBuilder, RuntimeJavaM protected override void FinishGhostStep2() { - typeBuilderGhostInterface?.CreateType(); + typeBuilderGhostInterface?.Complete(); } - protected override TypeBuilder DefineGhostType(string mangledTypeName, TypeAttributes typeAttribs) + protected override ITypeSymbolBuilder DefineGhostType(string mangledTypeName, TypeAttributes typeAttribs) { typeAttribs &= ~(TypeAttributes.Interface | TypeAttributes.Abstract); typeAttribs |= TypeAttributes.Class | TypeAttributes.Sealed; - TypeBuilder typeBuilder = classLoader.GetTypeWrapperFactory().ModuleBuilder.DefineType(mangledTypeName, typeAttribs, Context.Types.ValueType); + var typeBuilder = classLoader.GetTypeWrapperFactory().ModuleBuilder.DefineType(mangledTypeName, typeAttribs, Context.Types.ValueType); Context.AttributeHelper.SetGhostInterface(typeBuilder); Context.AttributeHelper.SetModifiers(typeBuilder, Modifiers, IsInternal); ghostRefField = typeBuilder.DefineField("__", Context.Types.Object, FieldAttributes.Public | FieldAttributes.SpecialName); typeBuilderGhostInterface = typeBuilder.DefineNestedType("__Interface", TypeAttributes.Interface | TypeAttributes.Abstract | TypeAttributes.NestedPublic); Context.AttributeHelper.HideFromJava(typeBuilderGhostInterface); - ghostIsInstanceMethod = typeBuilder.DefineMethod("IsInstance", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static, Context.Types.Boolean, new Type[] { Context.Types.Object }); + ghostIsInstanceMethod = typeBuilder.DefineMethod("IsInstance", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static, Context.Types.Boolean, [Context.Types.Object]); ghostIsInstanceMethod.DefineParameter(1, ParameterAttributes.None, "obj"); - ghostIsInstanceArrayMethod = typeBuilder.DefineMethod("IsInstanceArray", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static, Context.Types.Boolean, new Type[] { Context.Types.Object, Context.Types.Int32 }); + ghostIsInstanceArrayMethod = typeBuilder.DefineMethod("IsInstanceArray", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static, Context.Types.Boolean, [Context.Types.Object, Context.Types.Int32]); ghostIsInstanceArrayMethod.DefineParameter(1, ParameterAttributes.None, "obj"); ghostIsInstanceArrayMethod.DefineParameter(2, ParameterAttributes.None, "rank"); - ghostCastMethod = typeBuilder.DefineMethod("Cast", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static, typeBuilder, new Type[] { Context.Types.Object }); + ghostCastMethod = typeBuilder.DefineMethod("Cast", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static, typeBuilder, [Context.Types.Object]); ghostCastMethod.DefineParameter(1, ParameterAttributes.None, "obj"); - ghostCastArrayMethod = typeBuilder.DefineMethod("CastArray", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static, Context.Types.Void, new Type[] { Context.Types.Object, Context.Types.Int32 }); + ghostCastArrayMethod = typeBuilder.DefineMethod("CastArray", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static, Context.Types.Void, [Context.Types.Object, Context.Types.Int32]); ghostCastArrayMethod.DefineParameter(1, ParameterAttributes.None, "obj"); ghostCastArrayMethod.DefineParameter(2, ParameterAttributes.None, "rank"); return typeBuilder; @@ -994,7 +995,7 @@ internal override void EmitCheckcast(CodeEmitter ilgen) } ilgen.EmitLdc_I4(rank); ilgen.Emit(System.Reflection.Emit.OpCodes.Call, ghostCastArrayMethod); - ilgen.Emit(System.Reflection.Emit.OpCodes.Castclass, RuntimeArrayJavaType.MakeArrayType(Context.Types.Object, rank)); + ilgen.Emit(System.Reflection.Emit.OpCodes.Castclass, rank == 1 ? Context.Types.Object.MakeArrayType() : Context.Types.Object.MakeArrayType(rank)); } else { diff --git a/src/IKVM.Tools.Importer/StaticCompiler.cs b/src/IKVM.Tools.Importer/StaticCompiler.cs index f5e3f7cb7..795568db5 100644 --- a/src/IKVM.Tools.Importer/StaticCompiler.cs +++ b/src/IKVM.Tools.Importer/StaticCompiler.cs @@ -1,25 +1,25 @@ /* - Copyright (C) 2002-2014 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - + Copyright (C) 2002-2014 Jeroen Frijters + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jeroen Frijters + jeroen@frijters.net + */ using System; @@ -31,6 +31,7 @@ Jeroen Frijters using IKVM.CoreLib.Diagnostics; using IKVM.CoreLib.Symbols; +using IKVM.CoreLib.Symbols.IkvmReflection; using IKVM.Reflection; using IKVM.Reflection.Diagnostics; using IKVM.Runtime; @@ -43,24 +44,29 @@ namespace IKVM.Tools.Importer class StaticCompiler { - readonly ConcurrentDictionary runtimeTypeCache = new(); + readonly ConcurrentDictionary runtimeTypeCache = new(); readonly IDiagnosticHandler diagnostics; + readonly IkvmReflectionSymbolContext symbols; internal Universe universe; - internal Assembly runtimeAssembly; - internal Assembly baseAssembly; + internal IAssemblySymbol runtimeAssembly; + internal IAssemblySymbol baseAssembly; internal ImportState rootTarget; internal int errorCount; internal Universe Universe => universe; + internal IkvmReflectionSymbolContext Symbols => symbols; + ///

/// Initializes a new instance. /// /// - public StaticCompiler(IDiagnosticHandler diagnostics) + /// + public StaticCompiler(IDiagnosticHandler diagnostics, IkvmReflectionSymbolContext symbols) { this.diagnostics = diagnostics ?? throw new ArgumentNullException(nameof(diagnostics)); + this.symbols = symbols ?? throw new ArgumentNullException(nameof(symbols)); } /// @@ -167,17 +173,17 @@ internal Assembly Load(string assemblyString) return asm; } - internal Assembly LoadFile(string path) + internal IAssemblySymbol LoadFile(string path) { - return universe.LoadFile(path); + return symbols.GetOrCreateAssemblySymbol( universe.LoadFile(path)); } - internal Type GetRuntimeType(string name) + internal ITypeSymbol GetRuntimeType(string name) { return runtimeTypeCache.GetOrAdd(name, runtimeAssembly.GetType); } - internal Type GetTypeForMapXml(RuntimeClassLoader loader, string name) + internal ITypeSymbol GetTypeForMapXml(RuntimeClassLoader loader, string name) { return GetType(loader, name) ?? throw new FatalCompilerErrorException(DiagnosticEvent.MapFileTypeNotFound(name)); } @@ -197,7 +203,7 @@ internal RuntimeJavaField GetFieldForMapXml(RuntimeClassLoader loader, string cl return fw; } - internal Type GetType(RuntimeClassLoader loader, string name) + internal ITypeSymbol GetType(RuntimeClassLoader loader, string name) { var ccl = (ImportClassLoader)loader; return ccl.GetTypeFromReferencedAssembly(name); @@ -205,14 +211,15 @@ internal Type GetType(RuntimeClassLoader loader, string name) internal static void LinkageError(string msg, RuntimeJavaType actualType, RuntimeJavaType expectedType, params object[] values) { - var args = new object[values.Length + 2]; + object[] args = new object[values.Length + 2]; values.CopyTo(args, 2); args[0] = AssemblyQualifiedName(actualType); args[1] = AssemblyQualifiedName(expectedType); - - var str = string.Format(msg, args); + string str = string.Format(msg, args); if (actualType is RuntimeUnloadableJavaType && (expectedType is RuntimeManagedByteCodeJavaType || expectedType is RuntimeManagedJavaType)) - str += string.Format("\n\t(Please add a reference to {0})", expectedType.TypeAsBaseType.Assembly.AsReflection().Location); + { + str += string.Format("\n\t(Please add a reference to {0})", expectedType.TypeAsBaseType.Assembly.Location); + } throw new FatalCompilerErrorException(DiagnosticEvent.LinkageError(str)); } @@ -247,4 +254,4 @@ internal void SuppressWarning(ImportState options, Diagnostic diagnostic, string } -} +} \ No newline at end of file From 2f8e098f878d053ff62bed094755d30f12c0f299 Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Thu, 26 Sep 2024 13:41:11 -0500 Subject: [PATCH 13/51] Almost. --- src/IKVM.CoreLib/Diagnostics/Diagnostic.g.cs | 11 + src/IKVM.CoreLib/Diagnostics/Diagnostic.json | 15 + .../Diagnostics/DiagnosticEvent.g.cs | 8 + .../Diagnostics/DiagnosticEventHandler.g.cs | 12 + .../Diagnostics/IDiagnosticHandler.g.cs | 8 + .../Diagnostics/NullDiagnosticHandler.g.cs | 11 + .../Tracing/DiagnosticEventSource.g.cs | 10 + .../Tracing/DiagnosticEventSource.g.tt | 2 + .../Reflection/ReflectionExtensions.cs | 14 + .../Symbols/AssemblyNameFormatter.cs | 146 ++ src/IKVM.CoreLib/Symbols/AssemblyNameInfo.cs | 159 ++ .../Symbols/Emit/IConstructorSymbolBuilder.cs | 43 +- .../Symbols/Emit/IMethodBaseSymbolBuilder.cs | 43 +- .../Symbols/Emit/IMethodSymbolBuilder.cs | 41 - .../Symbols/Emit/IModuleSymbolBuilder.cs | 6 +- src/IKVM.CoreLib/Symbols/IAssemblySymbol.cs | 17 +- src/IKVM.CoreLib/Symbols/ISymbolContext.cs | 4 +- src/IKVM.CoreLib/Symbols/ISymbolResolver.cs | 20 +- .../IIkvmReflectionMemberSymbolBuilder.cs | 1 + .../IIkvmReflectionModuleSymbolBuilder.cs | 3 +- .../IIkvmReflectionPropertySymbolBuilder.cs | 7 + .../Emit/IIkvmReflectionSymbolBuilder.cs | 8 - .../IkvmReflectionAssemblySymbolBuilder.cs | 10 +- .../IkvmReflectionConstructorSymbolBuilder.cs | 18 +- .../Emit/IkvmReflectionEventSymbolBuilder.cs | 1 - .../Emit/IkvmReflectionFieldSymbolBuilder.cs | 1 - ...ectionGenericTypeParameterSymbolBuilder.cs | 2 +- .../Emit/IkvmReflectionILGenerator.cs | 1 + .../Emit/IkvmReflectionMemberSymbolBuilder.cs | 21 +- .../IkvmReflectionMethodBaseSymbolBuilder.cs | 29 +- .../Emit/IkvmReflectionMethodSymbolBuilder.cs | 65 +- .../Emit/IkvmReflectionModuleSymbolBuilder.cs | 26 +- .../IkvmReflectionParameterBuilderInfo.cs | 10 +- .../IkvmReflectionParameterSymbolBuilder.cs | 20 +- .../IkvmReflectionPropertySymbolBuilder.cs | 16 +- .../Emit/IkvmReflectionTypeSymbolBuilder.cs | 31 +- .../IIkvmReflectionMethodSymbol.cs | 7 + .../IkvmReflectionAssemblySymbol.cs | 10 +- ...IkvmReflectionGenericTypeParameterTable.cs | 6 +- .../IkvmReflectionMemberSymbol.cs | 46 +- .../IkvmReflectionMethodSpecTable.cs | 6 +- .../IkvmReflectionMethodSymbol.cs | 9 + .../IkvmReflectionMethodTable.cs | 10 +- .../IkvmReflectionParameterTable.cs | 9 +- .../IkvmReflection/IkvmReflectionSymbol.cs | 34 +- .../IkvmReflectionSymbolContext.cs | 55 +- .../IkvmReflectionTypeSymbol.cs | 12 +- .../IkvmReflection/IkvmReflectionUtil.cs | 45 +- .../Emit/ReflectionAssemblySymbolBuilder.cs | 20 +- .../ReflectionConstructorSymbolBuilder.cs | 18 +- .../Emit/ReflectionMethodBaseSymbolBuilder.cs | 22 + .../Emit/ReflectionMethodSymbolBuilder.cs | 56 +- .../Emit/ReflectionModuleSymbolBuilder.cs | 12 +- .../Reflection/ReflectionAssemblySymbol.cs | 20 +- .../Reflection/ReflectionSymbolContext.cs | 8 +- .../Symbols/Reflection/ReflectionUtil.cs | 44 + src/IKVM.CoreLib/Text/HexConverter.cs | 443 ++++++ src/IKVM.CoreLib/Text/ValueStringBuilder.cs | 339 ++++ src/IKVM.Reflection/Universe.cs | 2 +- src/IKVM.Runtime/Annotation.cs | 8 +- src/IKVM.Runtime/AttributeHelper.cs | 168 +- .../CustomAssemblyClassLoaderAttribute.cs | 4 - src/IKVM.Runtime/ByteCodeHelper.cs | 33 +- src/IKVM.Runtime/CodeEmitter.cs | 23 +- src/IKVM.Runtime/DefineMethodHelper.cs | 37 +- src/IKVM.Runtime/DynamicClassLoader.cs | 26 +- src/IKVM.Runtime/DynamicMethodUtil.cs | 2 +- src/IKVM.Runtime/ExceptionHelper.cs | 4 +- src/IKVM.Runtime/IRuntimeSymbolResolver.cs | 44 +- src/IKVM.Runtime/JVM.Resolver.cs | 2 +- .../Java/Externs/ikvm/runtime/Util.cs | 8 +- .../Java/Externs/java/lang/Class.cs | 2 +- src/IKVM.Runtime/ReflectUtil.cs | 27 +- .../RuntimeAssemblyClassLoader.cs | 14 +- .../RuntimeAssemblyClassLoaderFactory.cs | 5 +- .../RuntimeByteCodeJavaType.FinishContext.cs | 49 +- .../RuntimeByteCodeJavaType.JavaTypeImpl.cs | 6 +- src/IKVM.Runtime/RuntimeByteCodeJavaType.cs | 7 +- src/IKVM.Runtime/RuntimeClassLoaderFactory.cs | 10 +- src/IKVM.Runtime/RuntimeContext.cs | 17 +- src/IKVM.Runtime/RuntimeContextOptions.cs | 10 +- src/IKVM.Runtime/RuntimeJavaType.cs | 2 +- ...anagedByteCodeJavaType.RemappedJavaType.cs | 2 +- .../RuntimeManagedByteCodeJavaType.cs | 10 +- ...tionJavaType.MultipleAnnotationJavaType.cs | 2 +- ...nJavaType.ReturnValueAnnotationJavaType.cs | 4 +- ...gedJavaType.AttributeAnnotationJavaType.cs | 6 +- ...agedJavaType.DelegateInnerClassJavaType.cs | 2 +- ...RuntimeManagedJavaType.EnumEnumJavaType.cs | 2 +- src/IKVM.Runtime/RuntimeManagedJavaType.cs | 2 +- src/IKVM.Runtime/StubGen/StubGenerator.cs | 2 +- src/IKVM.Runtime/atomic.cs | 2 +- .../AssemblyResolver.cs | 8 +- src/IKVM.Tools.Exporter/ExportImpl.cs | 9 +- .../IKVM.Tools.Exporter.csproj | 4 - .../ManagedTypeResolver.cs | 98 +- src/IKVM.Tools.Exporter/StaticCompiler.cs | 1 - .../ExecutionContext.NetFramework.cs | 2 +- src/IKVM.Tools.Importer/FakeTypes.cs | 4 - .../ImportAssemblyResolver.cs | 359 +++++ src/IKVM.Tools.Importer/ImportClassLoader.cs | 295 ++-- src/IKVM.Tools.Importer/ImportContext.cs | 1391 ++--------------- .../ImportContextFactory.cs | 1096 +++++++++++++ .../ImportRuntimeSymbolResolver.cs | 149 +- src/IKVM.Tools.Importer/ImportState.cs | 198 --- src/IKVM.Tools.Importer/ImportTool.cs | 159 +- src/IKVM.Tools.Importer/MapXml/Call.cs | 13 +- .../RuntimeImportByteCodeJavaType.cs | 4 +- src/IKVM.Tools.Importer/StaticCompiler.cs | 120 +- 109 files changed, 3977 insertions(+), 2548 deletions(-) create mode 100644 src/IKVM.CoreLib/Symbols/AssemblyNameFormatter.cs create mode 100644 src/IKVM.CoreLib/Symbols/AssemblyNameInfo.cs create mode 100644 src/IKVM.CoreLib/Text/HexConverter.cs create mode 100644 src/IKVM.CoreLib/Text/ValueStringBuilder.cs rename src/{IKVM.Tools.Importer => IKVM.Tools.Exporter}/AssemblyResolver.cs (98%) create mode 100644 src/IKVM.Tools.Importer/ImportAssemblyResolver.cs create mode 100644 src/IKVM.Tools.Importer/ImportContextFactory.cs delete mode 100644 src/IKVM.Tools.Importer/ImportState.cs diff --git a/src/IKVM.CoreLib/Diagnostics/Diagnostic.g.cs b/src/IKVM.CoreLib/Diagnostics/Diagnostic.g.cs index 9f7f9e73d..36c9374bf 100644 --- a/src/IKVM.CoreLib/Diagnostics/Diagnostic.g.cs +++ b/src/IKVM.CoreLib/Diagnostics/Diagnostic.g.cs @@ -285,6 +285,8 @@ partial record class Diagnostic return ModuleInitializerMethodRequirements; case 5060: return InvalidZip; + case 5061: + return CoreAssemblyVersionMismatch; case 6000: return GenericRuntimeTrace; case 6001: @@ -1396,6 +1398,15 @@ partial record class Diagnostic /// public static readonly Diagnostic InvalidZip = new Diagnostic(5060, nameof(InvalidZip), "Invalid zip: {0}.", DiagnosticLevel.Fatal); + /// + /// The 'CoreAssemblyVersionMismatch' diagnostic. + /// + /// +/// Unable to load assembly '{0}' as it depends on a higher version of {1} than the one currently loaded. + /// + public static readonly Diagnostic CoreAssemblyVersionMismatch = new Diagnostic(5061, nameof(CoreAssemblyVersionMismatch), "Unable to load assembly \'{-1}\' as it depends on a higher version of {-1} than the" + + " one currently loaded.", DiagnosticLevel.Fatal); + /// /// The 'GenericRuntimeTrace' diagnostic. /// diff --git a/src/IKVM.CoreLib/Diagnostics/Diagnostic.json b/src/IKVM.CoreLib/Diagnostics/Diagnostic.json index 3979a699a..833477aef 100644 --- a/src/IKVM.CoreLib/Diagnostics/Diagnostic.json +++ b/src/IKVM.CoreLib/Diagnostics/Diagnostic.json @@ -1631,6 +1631,21 @@ } ] }, + "CoreAssemblyVersionMismatch": { + "id": 5061, + "level": "Fatal", + "message": "Unable to load assembly '{0}' as it depends on a higher version of {1} than the one currently loaded.", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + } + ] + }, "GenericRuntimeTrace": { "id": 6000, "level": "Trace", diff --git a/src/IKVM.CoreLib/Diagnostics/DiagnosticEvent.g.cs b/src/IKVM.CoreLib/Diagnostics/DiagnosticEvent.g.cs index 1b84ae701..3dde983f2 100644 --- a/src/IKVM.CoreLib/Diagnostics/DiagnosticEvent.g.cs +++ b/src/IKVM.CoreLib/Diagnostics/DiagnosticEvent.g.cs @@ -1096,6 +1096,14 @@ readonly partial struct DiagnosticEvent /// public static DiagnosticEvent InvalidZip(string name, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.InvalidZip.Event([name], exception, location); + /// + /// The 'CoreAssemblyVersionMismatch' diagnostic. + /// + /// +/// Unable to load assembly '{0}' as it depends on a higher version of {1} than the one currently loaded. + /// + public static DiagnosticEvent CoreAssemblyVersionMismatch(string arg0, string arg1, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.CoreAssemblyVersionMismatch.Event([arg0, arg1], exception, location); + /// /// The 'GenericRuntimeTrace' diagnostic. /// diff --git a/src/IKVM.CoreLib/Diagnostics/DiagnosticEventHandler.g.cs b/src/IKVM.CoreLib/Diagnostics/DiagnosticEventHandler.g.cs index 3e9ecb9d1..53fc27600 100644 --- a/src/IKVM.CoreLib/Diagnostics/DiagnosticEventHandler.g.cs +++ b/src/IKVM.CoreLib/Diagnostics/DiagnosticEventHandler.g.cs @@ -1638,6 +1638,18 @@ public void InvalidZip(string name) Report(Diagnostic.InvalidZip.Event([name])); } + /// + /// The 'CoreAssemblyVersionMismatch' diagnostic. + /// + /// +/// Unable to load assembly '{0}' as it depends on a higher version of {1} than the one currently loaded. + /// + public void CoreAssemblyVersionMismatch(string arg0, string arg1) + { + if (IsEnabled(Diagnostic.CoreAssemblyVersionMismatch)) + Report(Diagnostic.CoreAssemblyVersionMismatch.Event([arg0, arg1])); + } + /// /// The 'GenericRuntimeTrace' diagnostic. /// diff --git a/src/IKVM.CoreLib/Diagnostics/IDiagnosticHandler.g.cs b/src/IKVM.CoreLib/Diagnostics/IDiagnosticHandler.g.cs index bfa84e116..1bac0acbc 100644 --- a/src/IKVM.CoreLib/Diagnostics/IDiagnosticHandler.g.cs +++ b/src/IKVM.CoreLib/Diagnostics/IDiagnosticHandler.g.cs @@ -1094,6 +1094,14 @@ partial interface IDiagnosticHandler /// void InvalidZip(string name); + /// + /// The 'CoreAssemblyVersionMismatch' diagnostic. + /// + /// +/// Unable to load assembly '{0}' as it depends on a higher version of {1} than the one currently loaded. + /// + void CoreAssemblyVersionMismatch(string arg0, string arg1); + /// /// The 'GenericRuntimeTrace' diagnostic. /// diff --git a/src/IKVM.CoreLib/Diagnostics/NullDiagnosticHandler.g.cs b/src/IKVM.CoreLib/Diagnostics/NullDiagnosticHandler.g.cs index 8a20d769a..1283a9557 100644 --- a/src/IKVM.CoreLib/Diagnostics/NullDiagnosticHandler.g.cs +++ b/src/IKVM.CoreLib/Diagnostics/NullDiagnosticHandler.g.cs @@ -1502,6 +1502,17 @@ public void InvalidZip(string name) } + /// + /// The 'CoreAssemblyVersionMismatch' diagnostic. + /// + /// +/// Unable to load assembly '{0}' as it depends on a higher version of {1} than the one currently loaded. + /// + public void CoreAssemblyVersionMismatch(string arg0, string arg1) + { + + } + /// /// The 'GenericRuntimeTrace' diagnostic. /// diff --git a/src/IKVM.CoreLib/Diagnostics/Tracing/DiagnosticEventSource.g.cs b/src/IKVM.CoreLib/Diagnostics/Tracing/DiagnosticEventSource.g.cs index f6559bc13..8d447587b 100644 --- a/src/IKVM.CoreLib/Diagnostics/Tracing/DiagnosticEventSource.g.cs +++ b/src/IKVM.CoreLib/Diagnostics/Tracing/DiagnosticEventSource.g.cs @@ -1244,6 +1244,16 @@ partial class DiagnosticEventSource [Event(5060, Message = "Invalid zip: {0}.", Level = EventLevel.Critical)] public void InvalidZip(string name) => WriteEvent(5060, name); + /// + /// The 'CoreAssemblyVersionMismatch' diagnostic. + /// + /// +/// Unable to load assembly '{0}' as it depends on a higher version of {1} than the one currently loaded. + /// + [Event(5061, Message = "Unable to load assembly \'{-1}\' as it depends on a higher version of {-1} than the" + + " one currently loaded.", Level = EventLevel.Critical)] + public void CoreAssemblyVersionMismatch(string arg0, string arg1) => WriteEvent(5061, arg0, arg1); + /// /// The 'GenericRuntimeTrace' diagnostic. /// diff --git a/src/IKVM.CoreLib/Diagnostics/Tracing/DiagnosticEventSource.g.tt b/src/IKVM.CoreLib/Diagnostics/Tracing/DiagnosticEventSource.g.tt index 8bf9d174f..3e266cf33 100644 --- a/src/IKVM.CoreLib/Diagnostics/Tracing/DiagnosticEventSource.g.tt +++ b/src/IKVM.CoreLib/Diagnostics/Tracing/DiagnosticEventSource.g.tt @@ -38,6 +38,8 @@ foreach (var kvp in DiagnosticFile.Read(Host.ResolvePath(Path.Combine("..", "Dia var level = kvp.Value.Level; if (level == "Fatal") level = "Critical"; + if (level == "Info") + level = "Informational"; if (level == "Trace") level = "Verbose"; diff --git a/src/IKVM.CoreLib/Reflection/ReflectionExtensions.cs b/src/IKVM.CoreLib/Reflection/ReflectionExtensions.cs index 0defa18ab..7ce0795da 100644 --- a/src/IKVM.CoreLib/Reflection/ReflectionExtensions.cs +++ b/src/IKVM.CoreLib/Reflection/ReflectionExtensions.cs @@ -576,6 +576,20 @@ public static MethodBuilder GetMethodBuilder(this ParameterBuilder parameter) return _getParameterMethodBuilderFunc(parameter); } + /// + /// Returns true if the is a SZArray. + /// + /// + /// + public static bool IsSZArray(this Type type) + { +#if NET + return type.IsSZArray; +#else + return type.IsArray && type.Name.EndsWith("[]"); +#endif + } + } } \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/AssemblyNameFormatter.cs b/src/IKVM.CoreLib/Symbols/AssemblyNameFormatter.cs new file mode 100644 index 000000000..08c41a9c6 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/AssemblyNameFormatter.cs @@ -0,0 +1,146 @@ +using System; +using System.Diagnostics; +using System.Reflection; + +using IKVM.CoreLib.Text; + +namespace IKVM.CoreLib.Symbols +{ + + internal static class AssemblyNameFormatter + { + + public static string ComputeDisplayName(string name, Version? version, string? cultureName, byte[]? pkt, AssemblyNameFlags flags = 0, AssemblyContentType contentType = 0, byte[]? pk = null) + { + const int PUBLIC_KEY_TOKEN_LEN = 8; + Debug.Assert(name.Length != 0); + + var vsb = new ValueStringBuilder(stackalloc char[256]); + vsb.AppendQuoted(name); + + if (version != null) + { + ushort major = (ushort)version.Major; + if (major != ushort.MaxValue) + { + vsb.Append(", Version="); + vsb.AppendSpanFormattable(major); + + ushort minor = (ushort)version.Minor; + if (minor != ushort.MaxValue) + { + vsb.Append('.'); + vsb.AppendSpanFormattable(minor); + + ushort build = (ushort)version.Build; + if (build != ushort.MaxValue) + { + vsb.Append('.'); + vsb.AppendSpanFormattable(build); + + ushort revision = (ushort)version.Revision; + if (revision != ushort.MaxValue) + { + vsb.Append('.'); + vsb.AppendSpanFormattable(revision); + } + } + } + } + } + + if (cultureName != null) + { + if (cultureName.Length == 0) + cultureName = "neutral"; + vsb.Append(", Culture="); + vsb.AppendQuoted(cultureName); + } + + byte[]? keyOrToken = pkt ?? pk; + if (keyOrToken != null) + { + if (pkt != null) + { + if (pkt.Length > PUBLIC_KEY_TOKEN_LEN) + throw new ArgumentException(); + + vsb.Append(", PublicKeyToken="); + } + else + { + vsb.Append(", PublicKey="); + } + + if (keyOrToken.Length == 0) + { + vsb.Append("null"); + } + else + { + HexConverter.EncodeToUtf16(keyOrToken, vsb.AppendSpan(keyOrToken.Length * 2), HexConverter.Casing.Lower); + } + } + + if (0 != (flags & AssemblyNameFlags.Retargetable)) + vsb.Append(", Retargetable=Yes"); + + if (contentType == AssemblyContentType.WindowsRuntime) + vsb.Append(", ContentType=WindowsRuntime"); + + // NOTE: By design (desktop compat) AssemblyName.FullName and ToString() do not include ProcessorArchitecture. + + return vsb.ToString(); + } + + private static void AppendQuoted(this ref ValueStringBuilder vsb, string s) + { + bool needsQuoting = false; + const char quoteChar = '\"'; + + // App-compat: You can use double or single quotes to quote a name, and Fusion (or rather the IdentityAuthority) picks one + // by some algorithm. Rather than guess at it, we use double quotes consistently. + ReadOnlySpan span = s.AsSpan(); + if (s.Length != span.Trim().Length || span.IndexOfAny('\"', '\'') >= 0) + needsQuoting = true; + + if (needsQuoting) + vsb.Append(quoteChar); + + for (int i = 0; i < s.Length; i++) + { + switch (s[i]) + { + case '\\': + case ',': + case '=': + case '\'': + case '"': + vsb.Append('\\'); + break; + case '\t': + vsb.Append("\\t"); + continue; + case '\r': + vsb.Append("\\r"); + continue; + case '\n': + vsb.Append("\\n"); + continue; + } + + vsb.Append(s[i]); + } + + if (needsQuoting) + vsb.Append(quoteChar); + } + + private static void AppendSpanFormattable(this ref ValueStringBuilder vsb, ushort value) + { + vsb.Append(value.ToString()); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/AssemblyNameInfo.cs b/src/IKVM.CoreLib/Symbols/AssemblyNameInfo.cs new file mode 100644 index 000000000..b92ecd28f --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/AssemblyNameInfo.cs @@ -0,0 +1,159 @@ +using System; +using System.Collections.Immutable; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Reflection; + +namespace IKVM.CoreLib.Symbols +{ + + class AssemblyNameInfo + { + + readonly AssemblyNameFlags _flags; + string? _fullName; + + /// + /// Initializes a new instance of the AssemblyNameInfo class. + /// + /// The simple name of the assembly. + /// The version of the assembly. + /// The name of the culture associated with the assembly. + /// The attributes of the assembly. + /// The public key or its token. Set to when it's public key. + /// is null. + public AssemblyNameInfo(string name, Version? version = null, string? cultureName = null, AssemblyNameFlags flags = AssemblyNameFlags.None, ImmutableArray publicKeyOrToken = default) + { + Name = name ?? throw new ArgumentNullException(nameof(name)); + Version = version; + CultureName = cultureName; + _flags = flags; + PublicKeyOrToken = publicKeyOrToken; + } + + /// + /// Gets the simple name of the assembly. + /// + public string Name { get; } + + /// + /// Gets the version of the assembly. + /// + public Version? Version { get; } + + /// + /// Gets the name of the culture associated with the assembly. + /// + /// + /// Do not create a instance from this string unless + /// you know the string has originated from a trustworthy source. + /// + public string? CultureName { get; } + + /// + /// Gets the attributes of the assembly. + /// + public AssemblyNameFlags Flags => _flags; + + /// + /// Gets the public key or the public key token of the assembly. + /// + /// Check for flag to see whether it's public key or its token. +#if SYSTEM_PRIVATE_CORELIB + public byte[]? PublicKeyOrToken { get; } +#else + public ImmutableArray PublicKeyOrToken { get; } +#endif + + + /// + /// Gets the full name of the assembly, also known as the display name. + /// + /// In contrary to it does not validate public key token neither computes it based on the provided public key. + public string FullName + { + get + { + if (_fullName is null) + { + bool isPublicKey = (Flags & AssemblyNameFlags.PublicKey) != 0; + + byte[]? publicKeyOrToken = +#if SYSTEM_PRIVATE_CORELIB + PublicKeyOrToken; +#elif NET8_0_OR_GREATER + !PublicKeyOrToken.IsDefault ? System.Runtime.InteropServices.ImmutableCollectionsMarshal.AsArray(PublicKeyOrToken) : null; +#else + !PublicKeyOrToken.IsDefault ? PublicKeyOrToken.ToArray() : null; +#endif + _fullName = AssemblyNameFormatter.ComputeDisplayName(Name, Version, CultureName, + pkt: isPublicKey ? null : publicKeyOrToken, + ExtractAssemblyNameFlags(_flags), ExtractAssemblyContentType(_flags), + pk: isPublicKey ? publicKeyOrToken : null); + } + + return _fullName; + } + } + + /// + /// Initializes a new instance of the class based on the stored information. + /// + /// + /// Do not create an instance with string unless + /// you know the string has originated from a trustworthy source. + /// + public AssemblyName ToAssemblyName() + { + AssemblyName assemblyName = new(); + assemblyName.Name = Name; + assemblyName.CultureName = CultureName; + assemblyName.Version = Version; + assemblyName.Flags = Flags; + assemblyName.ContentType = ExtractAssemblyContentType(_flags); +#pragma warning disable SYSLIB0037 // Type or member is obsolete + assemblyName.ProcessorArchitecture = ExtractProcessorArchitecture(_flags); +#pragma warning restore SYSLIB0037 // Type or member is obsolete + +#if SYSTEM_PRIVATE_CORELIB + if (PublicKeyOrToken is not null) + { + if ((Flags & AssemblyNameFlags.PublicKey) != 0) + { + assemblyName.SetPublicKey(PublicKeyOrToken); + } + else + { + assemblyName.SetPublicKeyToken(PublicKeyOrToken); + } + } +#else + if (!PublicKeyOrToken.IsDefault) + { + // A copy of the array needs to be created, as AssemblyName allows for the mutation of provided array. + if ((Flags & AssemblyNameFlags.PublicKey) != 0) + { + assemblyName.SetPublicKey(PublicKeyOrToken.ToArray()); + } + else + { + assemblyName.SetPublicKeyToken(PublicKeyOrToken.ToArray()); + } + } +#endif + + return assemblyName; + } + + internal static AssemblyNameFlags ExtractAssemblyNameFlags(AssemblyNameFlags combinedFlags) + => combinedFlags & unchecked((AssemblyNameFlags)0xFFFFF10F); + + internal static AssemblyContentType ExtractAssemblyContentType(AssemblyNameFlags flags) + => (AssemblyContentType)((((int)flags) >> 9) & 0x7); + + internal static ProcessorArchitecture ExtractProcessorArchitecture(AssemblyNameFlags flags) + => (ProcessorArchitecture)((((int)flags) >> 4) & 0x7); + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Emit/IConstructorSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IConstructorSymbolBuilder.cs index e3ca76885..a099d7d06 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/IConstructorSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/IConstructorSymbolBuilder.cs @@ -1,51 +1,10 @@ -using System.Reflection; - -namespace IKVM.CoreLib.Symbols.Emit +namespace IKVM.CoreLib.Symbols.Emit { interface IConstructorSymbolBuilder : ISymbolBuilder, IMethodBaseSymbolBuilder, IConstructorSymbol { - /// - /// Sets the method implementation flags for this constructor. - /// - /// - void SetImplementationFlags(MethodImplAttributes attributes); - - /// - /// Defines a parameter of this constructor. - /// - /// - /// - /// - /// - IParameterSymbolBuilder DefineParameter(int iSequence, ParameterAttributes attributes, string? strParamName); - - /// - /// Gets an ILGenerator object, with the specified MSIL stream size, that can be used to build a method body for this constructor. - /// - /// - /// - IILGenerator GetILGenerator(int streamSize); - - /// - /// Gets an ILGenerator for this constructor. - /// - /// - IILGenerator GetILGenerator(); - - /// - /// Set a custom attribute using a custom attribute builder. - /// - /// - void SetCustomAttribute(ICustomAttributeBuilder customBuilder); - /// - /// Sets a custom attribute using a specified custom attribute blob. - /// - /// - /// - void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute); } diff --git a/src/IKVM.CoreLib/Symbols/Emit/IMethodBaseSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IMethodBaseSymbolBuilder.cs index 894c8e9b1..c3173daf1 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/IMethodBaseSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/IMethodBaseSymbolBuilder.cs @@ -1,10 +1,51 @@ -namespace IKVM.CoreLib.Symbols.Emit +using System.Reflection; + +namespace IKVM.CoreLib.Symbols.Emit { interface IMethodBaseSymbolBuilder : ISymbolBuilder, IMemberSymbolBuilder, IMethodBaseSymbol { + /// + /// Sets the implementation flags for this method. + /// + /// + void SetImplementationFlags(MethodImplAttributes attributes); + + /// + /// Defines a parameter of this method. + /// + /// + /// + /// + /// + IParameterSymbolBuilder DefineParameter(int iSequence, ParameterAttributes attributes, string? strParamName); + + /// + /// Gets an ILGenerator object, with the specified MSIL stream size, that can be used to build a method body for this method. + /// + /// + /// + IILGenerator GetILGenerator(int streamSize); + + /// + /// Gets an ILGenerator for this method. + /// + /// + IILGenerator GetILGenerator(); + + /// + /// Set a custom attribute using a custom attribute builder. + /// + /// + void SetCustomAttribute(ICustomAttributeBuilder customBuilder); + /// + /// Sets a custom attribute using a specified custom attribute blob. + /// + /// + /// + void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute); } diff --git a/src/IKVM.CoreLib/Symbols/Emit/IMethodSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IMethodSymbolBuilder.cs index 8220de296..8ae9770eb 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/IMethodSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/IMethodSymbolBuilder.cs @@ -4,12 +4,6 @@ interface IMethodSymbolBuilder : ISymbolBuilder, IMethodBaseSymbolBuilder, IMethodSymbol { - /// - /// Sets the implementation flags for this method. - /// - /// - void SetImplementationFlags(System.Reflection.MethodImplAttributes attributes); - /// /// Sets the number and types of parameters for a method. /// @@ -40,41 +34,6 @@ interface IMethodSymbolBuilder : ISymbolBuilder, IMethodBaseSymbo /// IGenericTypeParameterSymbolBuilder[] DefineGenericParameters(params string[] names); - /// - /// Sets the parameter attributes and the name of a parameter of this method, or of the return value of this method. Returns a ParameterBuilder that can be used to apply custom attributes. - /// - /// - /// - /// - /// - IParameterSymbolBuilder DefineParameter(int position, System.Reflection.ParameterAttributes attributes, string? strParamName); - - /// - /// Returns an ILGenerator for this method with a default Microsoft intermediate language (MSIL) stream size of 64 bytes. - /// - /// - IILGenerator GetILGenerator(); - - /// - /// Returns an ILGenerator for this method with the specified Microsoft intermediate language (MSIL) stream size. - /// - /// - /// - IILGenerator GetILGenerator(int size); - - /// - /// Set a custom attribute using a custom attribute builder. - /// - /// - void SetCustomAttribute(ICustomAttributeBuilder customBuilder); - - /// - /// Sets a custom attribute using a specified custom attribute blob. - /// - /// - /// - void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute); - } } diff --git a/src/IKVM.CoreLib/Symbols/Emit/IModuleSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IModuleSymbolBuilder.cs index 79737a176..f030d9e2e 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/IModuleSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/IModuleSymbolBuilder.cs @@ -71,7 +71,7 @@ interface IModuleSymbolBuilder : ISymbolBuilder, IModuleSymbol /// /// /// - IMethodSymbolBuilder DefineGlobalMethod(string name, MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, ITypeSymbol returnType, ITypeSymbol[] parameterTypes); + IMethodSymbolBuilder DefineGlobalMethod(string name, MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes); /// /// Defines a global method with the specified name, attributes, calling convention, return type, custom modifiers for the return type, parameter types, and custom modifiers for the parameter types. @@ -86,7 +86,7 @@ interface IModuleSymbolBuilder : ISymbolBuilder, IModuleSymbol /// /// /// - IMethodSymbolBuilder DefineGlobalMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol returnType, ITypeSymbol[] requiredReturnTypeCustomModifiers, ITypeSymbol[] optionalReturnTypeCustomModifiers, ITypeSymbol[] parameterTypes, ITypeSymbol[][] requiredParameterTypeCustomModifiers, ITypeSymbol[][] optionalParameterTypeCustomModifiers); + IMethodSymbolBuilder DefineGlobalMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? requiredReturnTypeCustomModifiers, ITypeSymbol[]? optionalReturnTypeCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? requiredParameterTypeCustomModifiers, ITypeSymbol[][]? optionalParameterTypeCustomModifiers); /// /// Defines a global method with the specified name, attributes, return type, and parameter types. @@ -96,7 +96,7 @@ interface IModuleSymbolBuilder : ISymbolBuilder, IModuleSymbol /// /// /// - IMethodSymbolBuilder DefineGlobalMethod(string name, MethodAttributes attributes, ITypeSymbol returnType, ITypeSymbol[] parameterTypes); + IMethodSymbolBuilder DefineGlobalMethod(string name, MethodAttributes attributes, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes); /// /// Constructs a TypeBuilder for a private type with the specified name in this module. diff --git a/src/IKVM.CoreLib/Symbols/IAssemblySymbol.cs b/src/IKVM.CoreLib/Symbols/IAssemblySymbol.cs index 4e14036ab..17fecec18 100644 --- a/src/IKVM.CoreLib/Symbols/IAssemblySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IAssemblySymbol.cs @@ -1,8 +1,5 @@ using System.Collections.Generic; using System.IO; -using System.Reflection; - -using IKVM.CoreLib.Symbols.Emit; namespace IKVM.CoreLib.Symbols { @@ -68,11 +65,17 @@ interface IAssemblySymbol : ISymbol, ICustomAttributeProvider IModuleSymbol[] GetModules(bool getResourceModules); - AssemblyName GetName(); - - AssemblyName GetName(bool copiedName); + /// + /// Gets an for this assembly. + /// + /// + AssemblyNameInfo GetName(); - AssemblyName[] GetReferencedAssemblies(); + /// + /// Gets the objects for all the assemblies referenced by this assembly. + /// + /// + AssemblyNameInfo[] GetReferencedAssemblies(); ITypeSymbol? GetType(string name, bool throwOnError); diff --git a/src/IKVM.CoreLib/Symbols/ISymbolContext.cs b/src/IKVM.CoreLib/Symbols/ISymbolContext.cs index 47a832f04..37440c21b 100644 --- a/src/IKVM.CoreLib/Symbols/ISymbolContext.cs +++ b/src/IKVM.CoreLib/Symbols/ISymbolContext.cs @@ -14,14 +14,14 @@ interface ISymbolContext /// /// /// - IAssemblySymbolBuilder DefineAssembly(AssemblyName name); + IAssemblySymbolBuilder DefineAssembly(AssemblyNameInfo name); /// /// Defines a dynamic assembly that has the specified name and access rights. /// /// /// - IAssemblySymbolBuilder DefineAssembly(AssemblyName name, ICustomAttributeBuilder[]? assemblyAttributes); + IAssemblySymbolBuilder DefineAssembly(AssemblyNameInfo name, ICustomAttributeBuilder[]? assemblyAttributes); /// /// Initializes an instance of the interface given the constructor for the custom attribute and the arguments to the constructor. diff --git a/src/IKVM.CoreLib/Symbols/ISymbolResolver.cs b/src/IKVM.CoreLib/Symbols/ISymbolResolver.cs index 2976d5bbb..fab954603 100644 --- a/src/IKVM.CoreLib/Symbols/ISymbolResolver.cs +++ b/src/IKVM.CoreLib/Symbols/ISymbolResolver.cs @@ -2,17 +2,23 @@ { /// - /// Provides an interface to resolve a managed type symbols. + /// Provides an interface to resolve managed type symbols. /// interface ISymbolResolver { /// - /// Resolves the named type from the IKVM runtime assembly. + /// Gets the known core assembly. + /// + /// + IAssemblySymbol ResolveCoreAssembly(); + + /// + /// Resolves the named type from the core assembly. /// /// /// - ITypeSymbol? ResolveRuntimeType(string typeName); + ITypeSymbol ResolveCoreType(string typeName); /// /// Resolves the named assembly from any reference source. @@ -26,13 +32,7 @@ interface ISymbolResolver /// /// /// - ITypeSymbol? ResolveCoreType(string typeName); - - /// - /// Resolves the known Java base assembly. - /// - /// - IAssemblySymbol? ResolveBaseAssembly(); + ITypeSymbol? ResolveType(string typeName); } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionMemberSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionMemberSymbolBuilder.cs index 7e936c529..3008c8e06 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionMemberSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionMemberSymbolBuilder.cs @@ -1,4 +1,5 @@ using IKVM.CoreLib.Symbols.Emit; +using IKVM.Reflection.Emit; namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit { diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionModuleSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionModuleSymbolBuilder.cs index fc5f3eb9d..a572d60bb 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionModuleSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionModuleSymbolBuilder.cs @@ -57,9 +57,10 @@ interface IIkvmReflectionModuleSymbolBuilder : IIkvmReflectionSymbolBuilder, IMo /// /// Gets or creates a for the specified . /// + /// /// /// - IIkvmReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter); + IIkvmReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(IIkvmReflectionMemberSymbolBuilder member, ParameterBuilder parameter); /// /// Gets or creates a for the specified . diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionPropertySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionPropertySymbolBuilder.cs index 723fc6ca0..a4fc28e00 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionPropertySymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionPropertySymbolBuilder.cs @@ -13,6 +13,13 @@ interface IIkvmReflectionPropertySymbolBuilder : IIkvmReflectionSymbolBuilder, I /// PropertyBuilder UnderlyingPropertyBuilder { get; } + /// + /// Gets or creates a for the given . + /// + /// + /// + public IIkvmReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter); + } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionSymbolBuilder.cs index c19769466..9d57604e4 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionSymbolBuilder.cs @@ -73,14 +73,6 @@ interface IIkvmReflectionSymbolBuilder : ISymbolBuilder [return: NotNullIfNotNull(nameof(@event))] IIkvmReflectionEventSymbolBuilder ResolveEventSymbol(EventBuilder @event); - /// - /// Resolves the symbol for the specified parameter. - /// - /// - /// - [return: NotNullIfNotNull(nameof(parameter))] - IIkvmReflectionParameterSymbolBuilder? ResolveParameterSymbol(ParameterBuilder parameter); - /// /// Resolves the symbol for the specified generic type parameter. /// diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionAssemblySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionAssemblySymbolBuilder.cs index bafa374cf..73594ea8c 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionAssemblySymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionAssemblySymbolBuilder.cs @@ -190,19 +190,13 @@ public IModuleSymbol[] GetModules(bool getResourceModules) } /// - public System.Reflection.AssemblyName GetName() + public AssemblyNameInfo GetName() { return UnderlyingAssembly.GetName().Pack(); } /// - public System.Reflection.AssemblyName GetName(bool copiedName) - { - return UnderlyingAssembly.GetName(copiedName).Pack(); - } - - /// - public System.Reflection.AssemblyName[] GetReferencedAssemblies() + public AssemblyNameInfo[] GetReferencedAssemblies() { return UnderlyingAssembly.GetReferencedAssemblies().Pack(); } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionConstructorSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionConstructorSymbolBuilder.cs index 66e1ef64d..8c776fbff 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionConstructorSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionConstructorSymbolBuilder.cs @@ -42,37 +42,40 @@ public IkvmReflectionConstructorSymbolBuilder(IkvmReflectionSymbolContext contex #region IConstructorSymbolBuilder /// - public void SetImplementationFlags(System.Reflection.MethodImplAttributes attributes) + public override void SetImplementationFlags(System.Reflection.MethodImplAttributes attributes) { UnderlyingConstructorBuilder.SetImplementationFlags((MethodImplAttributes)attributes); } /// - public IParameterSymbolBuilder DefineParameter(int iSequence, System.Reflection.ParameterAttributes attributes, string? strParamName) + public override IParameterSymbolBuilder DefineParameter(int iSequence, System.Reflection.ParameterAttributes attributes, string? strParamName) { - return ResolveParameterSymbol(UnderlyingConstructorBuilder.DefineParameter(iSequence, (ParameterAttributes)attributes, strParamName)); + if (iSequence <= 0) + throw new ArgumentOutOfRangeException(nameof(iSequence)); + + return ResolveParameterSymbol(this, UnderlyingConstructorBuilder.DefineParameter(iSequence, (ParameterAttributes)attributes, strParamName)); } /// - public IILGenerator GetILGenerator() + public override IILGenerator GetILGenerator() { return _il ??= new IkvmReflectionILGenerator(Context, UnderlyingConstructorBuilder.GetILGenerator()); } /// - public IILGenerator GetILGenerator(int streamSize) + public override IILGenerator GetILGenerator(int streamSize) { return _il ??= new IkvmReflectionILGenerator(Context, UnderlyingConstructorBuilder.GetILGenerator(streamSize)); } /// - public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) + public override void SetCustomAttribute(ICustomAttributeBuilder customBuilder) { UnderlyingConstructorBuilder.SetCustomAttribute(((IkvmReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); } /// - public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) + public override void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) { UnderlyingConstructorBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); } @@ -89,7 +92,6 @@ public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) /// public override void OnComplete() { - _ctor = (ConstructorInfo?)ResolvingModule.UnderlyingModule.ResolveMethod(MetadataToken) ?? throw new InvalidOperationException(); _builder = null; base.OnComplete(); } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionEventSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionEventSymbolBuilder.cs index b7c2ca9c3..4f388a3b2 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionEventSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionEventSymbolBuilder.cs @@ -153,7 +153,6 @@ public IMethodSymbol[] GetOtherMethods(bool nonPublic) /// public override void OnComplete() { - _event = (EventInfo?)ResolvingModule.UnderlyingModule.ResolveMember(MetadataToken) ?? throw new InvalidOperationException(); _builder = null; base.OnComplete(); } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionFieldSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionFieldSymbolBuilder.cs index 342d6bce4..847249780 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionFieldSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionFieldSymbolBuilder.cs @@ -135,7 +135,6 @@ public ITypeSymbol[] GetRequiredCustomModifiers() /// public override void OnComplete() { - _field = ResolvingModule.UnderlyingModule.ResolveField(MetadataToken) ?? throw new InvalidOperationException(); _builder = null; base.OnComplete(); } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionGenericTypeParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionGenericTypeParameterSymbolBuilder.cs index 12c2606df..5e318922e 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionGenericTypeParameterSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionGenericTypeParameterSymbolBuilder.cs @@ -699,7 +699,7 @@ public ITypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments) /// public override void OnComplete() { - throw new NotImplementedException(); + } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionILGenerator.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionILGenerator.cs index f83e7c390..dcfdb68ad 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionILGenerator.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionILGenerator.cs @@ -490,6 +490,7 @@ OpCode Convert(System.Reflection.Emit.OpCode opcode) 0xfe1a => OpCodes.Rethrow, 0xfe1c => OpCodes.Sizeof, 0xfe1d => OpCodes.Refanytype, + 0xfe13 => OpCodes.Volatile, _ => throw new NotImplementedException(), }; } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMemberSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMemberSymbolBuilder.cs index 58ac56a0f..456507620 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMemberSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMemberSymbolBuilder.cs @@ -145,15 +145,28 @@ public override IIkvmReflectionEventSymbolBuilder ResolveEventSymbol(EventBuilde /// [return: NotNullIfNotNull(nameof(parameter))] - public override IIkvmReflectionParameterSymbolBuilder ResolveParameterSymbol(ParameterBuilder parameter) + public override IIkvmReflectionParameterSymbolBuilder? ResolveParameterSymbol(IIkvmReflectionMethodBaseSymbolBuilder method, ParameterBuilder parameter) { if (parameter is null) - throw new ArgumentNullException(nameof(parameter)); + return null; if (parameter.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateParameterSymbol(parameter); + return _resolvingModule.GetOrCreateParameterSymbol(method, parameter); - return base.ResolveParameterSymbol(parameter); + return base.ResolveParameterSymbol(method, parameter); + } + + /// + [return: NotNullIfNotNull(nameof(parameter))] + public override IIkvmReflectionParameterSymbolBuilder? ResolveParameterSymbol(IIkvmReflectionPropertySymbolBuilder property, ParameterBuilder parameter) + { + if (parameter is null) + return null; + + if (parameter.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateParameterSymbol(property, parameter); + + return base.ResolveParameterSymbol(property, parameter); } #endregion diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodBaseSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodBaseSymbolBuilder.cs index 573c98183..60499625a 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodBaseSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodBaseSymbolBuilder.cs @@ -1,4 +1,5 @@ -using IKVM.Reflection; +using IKVM.CoreLib.Symbols.Emit; +using IKVM.Reflection; using IKVM.Reflection.Emit; namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit @@ -27,20 +28,38 @@ public IkvmReflectionMethodBaseSymbolBuilder(IkvmReflectionSymbolContext context /// public override MemberInfo UnderlyingMember => UnderlyingMethodBase; - #region IIkvmReflectionMethodBaseSymbolBuilder + #region IIkvmReflectionMethodBaseSymbol /// - public IIkvmReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter) + public IIkvmReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) { return _parameterTable.GetOrCreateParameterSymbol(parameter); } #endregion - #region IIkvmReflectionMethodBaseSymbol + #region IMethodBaseSymbolBuilder /// - public IIkvmReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) + public abstract void SetImplementationFlags(System.Reflection.MethodImplAttributes attributes); + + /// + public abstract IParameterSymbolBuilder DefineParameter(int position, System.Reflection.ParameterAttributes attributes, string? strParamName); + + /// + public abstract IILGenerator GetILGenerator(); + + /// + public abstract IILGenerator GetILGenerator(int streamSize); + + /// + public abstract void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute); + + /// + public abstract void SetCustomAttribute(ICustomAttributeBuilder customBuilder); + + /// + public IIkvmReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter) { return _parameterTable.GetOrCreateParameterSymbol(parameter); } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodSymbolBuilder.cs index 23b82a638..2b5270b6d 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodSymbolBuilder.cs @@ -16,6 +16,7 @@ class IkvmReflectionMethodSymbolBuilder : IkvmReflectionMethodBaseSymbolBuilder, MethodInfo _method; IkvmReflectionGenericTypeParameterTable _genericTypeParameterTable; + IkvmReflectionMethodSpecTable _specTable; IkvmReflectionILGenerator? _il; @@ -33,6 +34,7 @@ public IkvmReflectionMethodSymbolBuilder(IkvmReflectionSymbolContext context, II _builder = builder ?? throw new ArgumentNullException(nameof(builder)); _method = _builder; _genericTypeParameterTable = new IkvmReflectionGenericTypeParameterTable(context, resolvingModule, this); + _specTable = new IkvmReflectionMethodSpecTable(context, resolvingModule, resolvingType, this); } /// @@ -62,6 +64,12 @@ public IIkvmReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type gene return _genericTypeParameterTable.GetOrCreateGenericTypeParameterSymbol(genericTypeParameter); } + /// + public IIkvmReflectionMethodSymbol GetOrCreateGenericMethodSymbol(MethodInfo method) + { + return _specTable.GetOrCreateGenericMethodSymbol(method.GetGenericArguments()); + } + #endregion #region IIkvmReflectionMethodBaseSymbol @@ -72,70 +80,74 @@ public IIkvmReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type gene #endregion - #region IMethodSymbolBuilder + #region IMethodBaseSymbolBuilder /// - public void SetImplementationFlags(System.Reflection.MethodImplAttributes attributes) + public override void SetImplementationFlags(System.Reflection.MethodImplAttributes attributes) { UnderlyingMethodBuilder.SetImplementationFlags((MethodImplAttributes)attributes); } /// - public void SetParameters(params ITypeSymbol[] parameterTypes) + public override IParameterSymbolBuilder DefineParameter(int position, System.Reflection.ParameterAttributes attributes, string? strParamName) { - UnderlyingMethodBuilder.SetParameters(parameterTypes.Unpack()); + return ResolveParameterSymbol(this, UnderlyingMethodBuilder.DefineParameter(position, (ParameterAttributes)attributes, strParamName)); } /// - public void SetReturnType(ITypeSymbol? returnType) + public override IILGenerator GetILGenerator() { - UnderlyingMethodBuilder.SetReturnType(returnType?.Unpack()); + return _il ??= new IkvmReflectionILGenerator(Context, UnderlyingMethodBuilder.GetILGenerator()); } /// - public void SetSignature(ITypeSymbol? returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers) + public override IILGenerator GetILGenerator(int streamSize) { - UnderlyingMethodBuilder.SetSignature(returnType?.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack()); + return _il ??= new IkvmReflectionILGenerator(Context, UnderlyingMethodBuilder.GetILGenerator(streamSize)); } - public IGenericTypeParameterSymbolBuilder[] DefineGenericParameters(params string[] names) + /// + public override void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) { - var l = UnderlyingMethodBuilder.DefineGenericParameters(names); - var a = new IGenericTypeParameterSymbolBuilder[l.Length]; - for (int i = 0; i < l.Length; i++) - a[i] = ResolveGenericTypeParameterSymbol(l[i]); - - return a; + UnderlyingMethodBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); } /// - public IParameterSymbolBuilder DefineParameter(int position, System.Reflection.ParameterAttributes attributes, string? strParamName) + public override void SetCustomAttribute(ICustomAttributeBuilder customBuilder) { - return ResolveParameterSymbol(UnderlyingMethodBuilder.DefineParameter(position, (ParameterAttributes)attributes, strParamName)); + UnderlyingMethodBuilder.SetCustomAttribute(((IkvmReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); } + #endregion + + #region IMethodSymbolBuilder + /// - public IILGenerator GetILGenerator() + public void SetParameters(params ITypeSymbol[] parameterTypes) { - return _il ??= new IkvmReflectionILGenerator(Context, UnderlyingMethodBuilder.GetILGenerator()); + UnderlyingMethodBuilder.SetParameters(parameterTypes.Unpack()); } /// - public IILGenerator GetILGenerator(int streamSize) + public void SetReturnType(ITypeSymbol? returnType) { - return _il ??= new IkvmReflectionILGenerator(Context, UnderlyingMethodBuilder.GetILGenerator(streamSize)); + UnderlyingMethodBuilder.SetReturnType(returnType?.Unpack()); } /// - public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) + public void SetSignature(ITypeSymbol? returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers) { - UnderlyingMethodBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); + UnderlyingMethodBuilder.SetSignature(returnType?.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack()); } - /// - public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) + public IGenericTypeParameterSymbolBuilder[] DefineGenericParameters(params string[] names) { - UnderlyingMethodBuilder.SetCustomAttribute(((IkvmReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); + var l = UnderlyingMethodBuilder.DefineGenericParameters(names); + var a = new IGenericTypeParameterSymbolBuilder[l.Length]; + for (int i = 0; i < l.Length; i++) + a[i] = ResolveGenericTypeParameterSymbol(l[i]); + + return a; } #endregion @@ -177,7 +189,6 @@ public IMethodSymbol MakeGenericMethod(params ITypeSymbol[] typeArguments) /// public override void OnComplete() { - _method = (MethodInfo?)ResolvingModule.UnderlyingModule.ResolveMethod(MetadataToken) ?? throw new InvalidOperationException(); _builder = null; base.OnComplete(); } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionModuleSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionModuleSymbolBuilder.cs index 1ac802ff4..752ef4f3e 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionModuleSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionModuleSymbolBuilder.cs @@ -23,7 +23,6 @@ class IkvmReflectionModuleSymbolBuilder : IkvmReflectionSymbolBuilder, IIkvmRefl IkvmReflectionMethodTable _methodTable; IkvmReflectionFieldTable _fieldTable; - /// /// Initializes a new instance. /// @@ -68,6 +67,10 @@ public IIkvmReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) return ResolveTypeSymbol(type.GetElementType()).GetOrCreatePointerTypeSymbol(); else if (type.IsByRef) return ResolveTypeSymbol(type.GetElementType()).GetOrCreateByRefTypeSymbol(); + else if (type.IsGenericParameter && type.DeclaringMethod is MethodInfo dm) + return ResolveMethodSymbol(dm).GetOrCreateGenericTypeParameterSymbol(type); + else if (type.IsGenericParameter) + return ResolveTypeSymbol(type.DeclaringType).GetOrCreateGenericTypeParameterSymbol(type); else throw new InvalidOperationException(); } @@ -171,9 +174,14 @@ public IIkvmReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo p } /// - public IIkvmReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter) + public IIkvmReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(IIkvmReflectionMemberSymbolBuilder member, ParameterBuilder parameter) { - return ResolveMethodSymbol((MethodBuilder)parameter.Method).GetOrCreateParameterSymbol(parameter); + return member switch + { + IIkvmReflectionMethodBaseSymbolBuilder method => method.GetOrCreateParameterSymbol(parameter), + IIkvmReflectionPropertySymbolBuilder property => property.GetOrCreateParameterSymbol(parameter), + _ => throw new InvalidOperationException(), + }; } /// @@ -214,21 +222,21 @@ public IResourceWriter DefineResource(string name, string description, System.Re } /// - public IMethodSymbolBuilder DefineGlobalMethod(string name, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, ITypeSymbol returnType, ITypeSymbol[] parameterTypes) + public IMethodSymbolBuilder DefineGlobalMethod(string name, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes) { - return ResolveMethodSymbol(UnderlyingModuleBuilder.DefineGlobalMethod(name, (MethodAttributes)attributes, (CallingConventions)callingConvention, returnType.Unpack(), parameterTypes.Unpack())); + return ResolveMethodSymbol(UnderlyingModuleBuilder.DefineGlobalMethod(name, (MethodAttributes)attributes, (CallingConventions)callingConvention, returnType?.Unpack(), parameterTypes?.Unpack())); } /// - public IMethodSymbolBuilder DefineGlobalMethod(string name, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, ITypeSymbol returnType, ITypeSymbol[] requiredReturnTypeCustomModifiers, ITypeSymbol[] optionalReturnTypeCustomModifiers, ITypeSymbol[] parameterTypes, ITypeSymbol[][] requiredParameterTypeCustomModifiers, ITypeSymbol[][] optionalParameterTypeCustomModifiers) + public IMethodSymbolBuilder DefineGlobalMethod(string name, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? requiredReturnTypeCustomModifiers, ITypeSymbol[]? optionalReturnTypeCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? requiredParameterTypeCustomModifiers, ITypeSymbol[][]? optionalParameterTypeCustomModifiers) { - return ResolveMethodSymbol(UnderlyingModuleBuilder.DefineGlobalMethod(name, (MethodAttributes)attributes, (CallingConventions)callingConvention, returnType.Unpack(), requiredReturnTypeCustomModifiers.Unpack(), optionalReturnTypeCustomModifiers.Unpack(), parameterTypes.Unpack(), requiredParameterTypeCustomModifiers.Unpack(), optionalParameterTypeCustomModifiers.Unpack())); + return ResolveMethodSymbol(UnderlyingModuleBuilder.DefineGlobalMethod(name, (MethodAttributes)attributes, (CallingConventions)callingConvention, returnType?.Unpack(), requiredReturnTypeCustomModifiers?.Unpack(), optionalReturnTypeCustomModifiers?.Unpack(), parameterTypes?.Unpack(), requiredParameterTypeCustomModifiers?.Unpack(), optionalParameterTypeCustomModifiers?.Unpack())); } /// - public IMethodSymbolBuilder DefineGlobalMethod(string name, System.Reflection.MethodAttributes attributes, ITypeSymbol returnType, ITypeSymbol[] parameterTypes) + public IMethodSymbolBuilder DefineGlobalMethod(string name, System.Reflection.MethodAttributes attributes, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes) { - return ResolveMethodSymbol(UnderlyingModuleBuilder.DefineGlobalMethod(name, (MethodAttributes)attributes, returnType.Unpack(), parameterTypes.Unpack())); + return ResolveMethodSymbol(UnderlyingModuleBuilder.DefineGlobalMethod(name, (MethodAttributes)attributes, returnType?.Unpack(), parameterTypes?.Unpack())); } /// diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterBuilderInfo.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterBuilderInfo.cs index ea7a2a744..441b991f5 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterBuilderInfo.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterBuilderInfo.cs @@ -14,18 +14,20 @@ namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit class IkvmReflectionParameterBuilderInfo : ParameterInfo { + readonly IIkvmReflectionMemberSymbol _member; readonly ParameterBuilder _builder; readonly Func _getDefaultValue; /// /// Initialies a new instance. /// + /// /// - /// /// /// - public IkvmReflectionParameterBuilderInfo(ParameterBuilder builder, Func getDefaultValue) + public IkvmReflectionParameterBuilderInfo(IIkvmReflectionMemberSymbol member, ParameterBuilder builder, Func getDefaultValue) { + _member = member ?? throw new ArgumentNullException(nameof(member)); _builder = builder ?? throw new ArgumentNullException(nameof(builder)); _getDefaultValue = getDefaultValue ?? throw new ArgumentNullException(nameof(getDefaultValue)); } @@ -34,7 +36,7 @@ public IkvmReflectionParameterBuilderInfo(ParameterBuilder builder, Func (ParameterAttributes)_builder.Attributes; /// - public override MemberInfo Member => throw new NotImplementedException(); + public override MemberInfo Member => _member.UnderlyingMember; /// public override Type ParameterType => ((MethodBase)Member).GetParameters()[Position].ParameterType; @@ -46,7 +48,7 @@ public IkvmReflectionParameterBuilderInfo(ParameterBuilder builder, Func _builder.Name; /// - public override int Position => _builder.Position; + public override int Position => _builder.Position - 1; /// public override int MetadataToken => throw new NotImplementedException(); diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterSymbolBuilder.cs index e49827c7d..461d75db7 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterSymbolBuilder.cs @@ -11,8 +11,8 @@ namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit class IkvmReflectionParameterSymbolBuilder : IkvmReflectionSymbolBuilder, IIkvmReflectionParameterSymbolBuilder { - readonly IIkvmReflectionModuleSymbol _resolvingModule; - readonly IIkvmReflectionMemberSymbol _resolvingMethod; + readonly IIkvmReflectionModuleSymbol _module; + readonly IIkvmReflectionMemberSymbol _member; ParameterBuilder? _builder; ParameterInfo _parameter; @@ -23,23 +23,23 @@ class IkvmReflectionParameterSymbolBuilder : IkvmReflectionSymbolBuilder, IIkvmR /// Initializes a new instance. /// /// - /// - /// + /// + /// /// - public IkvmReflectionParameterSymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol resolvingModule, IIkvmReflectionMemberSymbol resolvingMethod, ParameterBuilder builder) : + public IkvmReflectionParameterSymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol module, IIkvmReflectionMemberSymbol member, ParameterBuilder builder) : base(context) { - _resolvingModule = resolvingModule ?? throw new ArgumentNullException(nameof(resolvingModule)); - _resolvingMethod = resolvingMethod ?? throw new ArgumentNullException(nameof(resolvingMethod)); + _module = module ?? throw new ArgumentNullException(nameof(module)); + _member = member ?? throw new ArgumentNullException(nameof(member)); _builder = builder ?? throw new ArgumentNullException(nameof(builder)); - _parameter = new IkvmReflectionParameterBuilderInfo(_builder, () => _constant); + _parameter = new IkvmReflectionParameterBuilderInfo(member, _builder, () => _constant); } /// - public IIkvmReflectionModuleSymbol ResolvingModule => _resolvingMethod.ResolvingModule; + public IIkvmReflectionModuleSymbol ResolvingModule => _module; /// - public IIkvmReflectionMemberSymbol ResolvingMember => _resolvingMethod; + public IIkvmReflectionMemberSymbol ResolvingMember => _member; /// public ParameterInfo UnderlyingParameter => _parameter; diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionPropertySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionPropertySymbolBuilder.cs index 731828bd7..f4416773b 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionPropertySymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionPropertySymbolBuilder.cs @@ -40,8 +40,19 @@ public IkvmReflectionPropertySymbolBuilder(IkvmReflectionSymbolContext context, /// public override MemberInfo UnderlyingMember => UnderlyingProperty; - #region IIkvmPropertySymbol + #region IIkvmReflectionPropertySymbolBuilder + /// + public IIkvmReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter) + { + return _parameterTable.GetOrCreateParameterSymbol(parameter); + } + + #endregion + + #region IIkvmReflectionPropertySymbol + + /// public IIkvmReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) { return _parameterTable.GetOrCreateParameterSymbol(parameter); @@ -49,7 +60,7 @@ public IIkvmReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo p #endregion - #region IPropertySymbol + #region IPropertySymbolBuilder /// public void SetConstant(object? defaultValue) @@ -186,7 +197,6 @@ public ITypeSymbol[] GetRequiredCustomModifiers() /// public override void OnComplete() { - _property = (PropertyInfo?)ResolvingModule.UnderlyingModule.ResolveMember(MetadataToken) ?? throw new InvalidOperationException(); _builder = null; base.OnComplete(); } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionTypeSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionTypeSymbolBuilder.cs index f392d4502..3ec41457e 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionTypeSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionTypeSymbolBuilder.cs @@ -27,18 +27,19 @@ class IkvmReflectionTypeSymbolBuilder : IkvmReflectionMemberSymbolBuilder, IIkvm /// Initializes a new instance. /// /// - /// + /// /// - public IkvmReflectionTypeSymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbolBuilder resolvingModule, TypeBuilder builder) : - base(context, resolvingModule, null) + public IkvmReflectionTypeSymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbolBuilder module, TypeBuilder builder) : + base(context, module, null) { _builder = builder ?? throw new ArgumentNullException(nameof(builder)); _type = _builder; - _methodTable = new IkvmReflectionMethodTable(context, resolvingModule, this); - _fieldTable = new IkvmReflectionFieldTable(context, resolvingModule, this); - _propertyTable = new IkvmReflectionPropertyTable(context, resolvingModule, this); - _eventTable = new IkvmReflectionEventTable(context, resolvingModule, this); - _genericTypeParameterTable = new IkvmReflectionGenericTypeParameterTable(context, resolvingModule, this); + _methodTable = new IkvmReflectionMethodTable(context, module, this); + _fieldTable = new IkvmReflectionFieldTable(context, module, this); + _propertyTable = new IkvmReflectionPropertyTable(context, module, this); + _eventTable = new IkvmReflectionEventTable(context, module, this); + _genericTypeParameterTable = new IkvmReflectionGenericTypeParameterTable(context, module, this); + _specTable = new IkvmReflectionTypeSpecTable(context, module, this); } /// @@ -164,12 +165,6 @@ public IIkvmReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @ev return _eventTable.GetOrCreateEventSymbol(@event); } - /// - public IIkvmReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter) - { - return ResolveMethodSymbol((MethodBuilder)parameter.Method).GetOrCreateParameterSymbol(parameter); - } - #endregion #region ITypeSymbolBuilder @@ -899,7 +894,10 @@ public void Complete() { // complete type if (_builder.IsCreated() == false) - _builder.CreateType(); + { + _type = _builder.CreateType(); + _builder = null; + } // force module to reresolve Context.GetOrCreateModuleSymbol(ResolvingModule.UnderlyingModule); @@ -912,9 +910,6 @@ public override void OnComplete() { const System.Reflection.BindingFlags DefaultBindingFlags = System.Reflection.BindingFlags.DeclaredOnly | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Static; - _type = ResolvingModule.UnderlyingModule.ResolveType(MetadataToken); - _builder = null; - foreach (var i in GetGenericArguments()) if (i is IIkvmReflectionGenericTypeParameterSymbolBuilder b) b.OnComplete(); diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionMethodSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionMethodSymbol.cs index 8e64ccaa4..5a0068973 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionMethodSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionMethodSymbol.cs @@ -18,6 +18,13 @@ interface IIkvmReflectionMethodSymbol : IIkvmReflectionMethodBaseSymbol, IMethod /// IIkvmReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type genericTypeParameter); + /// + /// Gets or creates a for the given generic version of this method definition. + /// + /// + /// + IIkvmReflectionMethodSymbol GetOrCreateGenericMethodSymbol(MethodInfo method); + } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs index 61b83f629..73163f1ba 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs @@ -93,19 +93,13 @@ public IModuleSymbol[] GetModules(bool getResourceModules) } /// - public System.Reflection.AssemblyName GetName() + public AssemblyNameInfo GetName() { return UnderlyingAssembly.GetName().Pack(); } /// - public System.Reflection.AssemblyName GetName(bool copiedName) - { - return UnderlyingAssembly.GetName().Pack(); - } - - /// - public System.Reflection.AssemblyName[] GetReferencedAssemblies() + public AssemblyNameInfo[] GetReferencedAssemblies() { return UnderlyingAssembly.GetReferencedAssemblies().Pack(); } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionGenericTypeParameterTable.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionGenericTypeParameterTable.cs index 7caf5453c..9bff410a3 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionGenericTypeParameterTable.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionGenericTypeParameterTable.cs @@ -60,10 +60,8 @@ public IIkvmReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type gene return _table[pos] ??= new IkvmReflectionGenericTypeParameterSymbolBuilder(_context, (IIkvmReflectionModuleSymbolBuilder)_module, (IIkvmReflectionMemberSymbolBuilder)_member, builder); else return _table[pos] ??= new IkvmReflectionGenericTypeParameterSymbol(_context, _module, _member, genericTypeParameter); - else - { - return _table[pos] ?? throw new InvalidOperationException(); - } + + return _table[pos] ?? throw new InvalidOperationException(); } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs index 69abb7189..c74eafbf3 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs @@ -2,9 +2,7 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; -using IKVM.CoreLib.Symbols.IkvmReflection.Emit; using IKVM.Reflection; -using IKVM.Reflection.Emit; using Type = IKVM.Reflection.Type; @@ -17,8 +15,8 @@ namespace IKVM.CoreLib.Symbols.IkvmReflection abstract class IkvmReflectionMemberSymbol : IkvmReflectionSymbol, IIkvmReflectionMemberSymbol { - readonly IIkvmReflectionModuleSymbol _resolvingModule; - readonly IIkvmReflectionTypeSymbol? _resolvingType; + readonly IIkvmReflectionModuleSymbol _module; + readonly IIkvmReflectionTypeSymbol? _type; /// /// Initializes a new instance. @@ -30,8 +28,8 @@ abstract class IkvmReflectionMemberSymbol : IkvmReflectionSymbol, IIkvmReflectio public IkvmReflectionMemberSymbol(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol resolvingModule, IIkvmReflectionTypeSymbol? resolvingType) : base(context) { - _resolvingModule = resolvingModule ?? throw new ArgumentNullException(nameof(resolvingModule)); - _resolvingType = resolvingType; + _module = resolvingModule ?? throw new ArgumentNullException(nameof(resolvingModule)); + _type = resolvingType; } /// @@ -40,12 +38,12 @@ public IkvmReflectionMemberSymbol(IkvmReflectionSymbolContext context, IIkvmRefl /// /// Gets the which contains the metadata of this member. /// - public IIkvmReflectionModuleSymbol ResolvingModule => _resolvingModule; + public IIkvmReflectionModuleSymbol ResolvingModule => _module; /// /// Gets the which contains the metadata of this member, or null if the member is not a member of a type. /// - public IIkvmReflectionTypeSymbol? ResolvingType => _resolvingType; + public IIkvmReflectionTypeSymbol? ResolvingType => _type; /// [return: NotNullIfNotNull(nameof(type))] @@ -57,11 +55,11 @@ public IkvmReflectionMemberSymbol(IkvmReflectionSymbolContext context, IIkvmRefl if (type == UnderlyingMember) return (IIkvmReflectionTypeSymbol)this; - if (_resolvingType != null && type == _resolvingType.UnderlyingType) - return _resolvingType; + if (_type != null && type == _type.UnderlyingType) + return _type; - if (type.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateTypeSymbol(type); + if (type.Module == _module.UnderlyingModule) + return _module.GetOrCreateTypeSymbol(type); return base.ResolveTypeSymbol(type); } @@ -76,8 +74,8 @@ public IkvmReflectionMemberSymbol(IkvmReflectionSymbolContext context, IIkvmRefl if (ctor == UnderlyingMember) return (IIkvmReflectionConstructorSymbol)this; - if (ctor.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateConstructorSymbol(ctor); + if (ctor.Module == _module.UnderlyingModule) + return _module.GetOrCreateConstructorSymbol(ctor); return base.ResolveConstructorSymbol(ctor); } @@ -92,8 +90,8 @@ public IkvmReflectionMemberSymbol(IkvmReflectionSymbolContext context, IIkvmRefl if (method == UnderlyingMember) return (IIkvmReflectionMethodSymbol)this; - if (method.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateMethodSymbol(method); + if (method.Module == _module.UnderlyingModule) + return _module.GetOrCreateMethodSymbol(method); return base.ResolveMethodSymbol(method); } @@ -108,8 +106,8 @@ public IkvmReflectionMemberSymbol(IkvmReflectionSymbolContext context, IIkvmRefl if (field == UnderlyingMember) return (IIkvmReflectionFieldSymbol)this; - if (field.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateFieldSymbol(field); + if (field.Module == _module.UnderlyingModule) + return _module.GetOrCreateFieldSymbol(field); return base.ResolveFieldSymbol(field); } @@ -124,8 +122,8 @@ public IkvmReflectionMemberSymbol(IkvmReflectionSymbolContext context, IIkvmRefl if (property == UnderlyingMember) return (IIkvmReflectionPropertySymbol)this; - if (property.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreatePropertySymbol(property); + if (property.Module == _module.UnderlyingModule) + return _module.GetOrCreatePropertySymbol(property); return base.ResolvePropertySymbol(property); } @@ -140,8 +138,8 @@ public IkvmReflectionMemberSymbol(IkvmReflectionSymbolContext context, IIkvmRefl if (@event == UnderlyingMember) return (IIkvmReflectionEventSymbol)this; - if (@event.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateEventSymbol(@event); + if (@event.Module == _module.UnderlyingModule) + return _module.GetOrCreateEventSymbol(@event); return base.ResolveEventSymbol(@event); } @@ -153,8 +151,8 @@ public IkvmReflectionMemberSymbol(IkvmReflectionSymbolContext context, IIkvmRefl if (parameter is null) throw new ArgumentNullException(nameof(parameter)); - if (parameter.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateParameterSymbol(parameter); + if (parameter.Module == _module.UnderlyingModule) + return _module.GetOrCreateParameterSymbol(parameter); return base.ResolveParameterSymbol(parameter); } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodSpecTable.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodSpecTable.cs index 1a94625e7..5c0c70607 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodSpecTable.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodSpecTable.cs @@ -12,7 +12,7 @@ struct IkvmReflectionMethodSpecTable readonly IkvmReflectionSymbolContext _context; readonly IIkvmReflectionModuleSymbol _module; - readonly IIkvmReflectionTypeSymbol _type; + readonly IIkvmReflectionTypeSymbol? _type; readonly IIkvmReflectionMethodSymbol _method; ConcurrentDictionary? _genericMethodSymbols; @@ -25,11 +25,11 @@ struct IkvmReflectionMethodSpecTable /// /// /// - public IkvmReflectionMethodSpecTable(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol module, IIkvmReflectionTypeSymbol type, IIkvmReflectionMethodSymbol method) + public IkvmReflectionMethodSpecTable(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol module, IIkvmReflectionTypeSymbol? type, IIkvmReflectionMethodSymbol method) { _context = context ?? throw new ArgumentNullException(nameof(context)); _module = module ?? throw new ArgumentNullException(nameof(module)); - _type = type ?? throw new ArgumentNullException(nameof(type)); + _type = type; _method = method ?? throw new ArgumentNullException(nameof(method)); } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodSymbol.cs index e0c8b8e3e..50efe60e8 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodSymbol.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using IKVM.Reflection; @@ -13,6 +14,7 @@ class IkvmReflectionMethodSymbol : IkvmReflectionMethodBaseSymbol, IIkvmReflecti readonly MethodInfo _method; IkvmReflectionGenericTypeParameterTable _genericTypeParameterTable; + IkvmReflectionMethodSpecTable _specTable; /// /// Initializes a new instance. @@ -26,6 +28,7 @@ public IkvmReflectionMethodSymbol(IkvmReflectionSymbolContext context, IIkvmRefl { _method = method ?? throw new ArgumentNullException(nameof(method)); _genericTypeParameterTable = new IkvmReflectionGenericTypeParameterTable(context, module, this); + _specTable = new IkvmReflectionMethodSpecTable(context, module, type, this); } /// @@ -42,6 +45,12 @@ public IIkvmReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type gene return _genericTypeParameterTable.GetOrCreateGenericTypeParameterSymbol(genericTypeParameter); } + /// + public IIkvmReflectionMethodSymbol GetOrCreateGenericMethodSymbol(MethodInfo method) + { + return _specTable.GetOrCreateGenericMethodSymbol(method.GetGenericArguments()); + } + #endregion #region IMethodSymbol diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodTable.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodTable.cs index cd1781c83..479dda6ac 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodTable.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodTable.cs @@ -53,8 +53,8 @@ public IIkvmReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase me if (method is MethodInfo m_ && m_.IsMethodDefinition() == false) throw new ArgumentException(nameof(method)); - var row = MetadataTokens.GetRowNumber(MetadataTokens.MethodDefinitionHandle(method.MetadataToken)); - if (row == 0) + var token = method.MetadataToken; + if (token <= 0) { // we fall back to lookup by name if there is no valid metadata token if (_byName == null) @@ -73,11 +73,11 @@ public IIkvmReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase me using (_lock.CreateUpgradeableReadLock()) { - if (_table[row] == null) + if (_table[token] == null) using (_lock.CreateWriteLock()) - return _table[row] ??= CreateMethodBaseSymbol(_context, _module, _type, method); + return _table[token] ??= CreateMethodBaseSymbol(_context, _module, _type, method); - return _table[row] ?? throw new InvalidOperationException(); + return _table[token] ?? throw new InvalidOperationException(); } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterTable.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterTable.cs index 452c861a4..9f4452ec4 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterTable.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterTable.cs @@ -19,6 +19,7 @@ struct IkvmReflectionParameterTable IndexRangeDictionary _table = new(); ReaderWriterLockSlim? _lock; + IIkvmReflectionParameterSymbol? _returnParameter; /// /// Initializes a new instance. @@ -54,6 +55,9 @@ public IIkvmReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo p using (_lock.CreateUpgradeableReadLock()) { var position = parameter.Position; + if (position == -1) + return _returnParameter ??= new IkvmReflectionParameterSymbol(_context, _module, _member, parameter); + if (_table[position] == null) using (_lock.CreateWriteLock()) return _table[position] ??= new IkvmReflectionParameterSymbol(_context, _module, _member, parameter); @@ -80,7 +84,10 @@ public IIkvmReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(Paramete using (_lock.CreateUpgradeableReadLock()) { - var position = parameter.Position; + var position = parameter.Position - 1; + if (position == -1) + return (IIkvmReflectionParameterSymbolBuilder)(_returnParameter ??= new IkvmReflectionParameterSymbolBuilder(_context, _module, (IIkvmReflectionMethodBaseSymbol)_member, parameter)); + if (_table[position] == null) using (_lock.CreateWriteLock()) return (IIkvmReflectionParameterSymbolBuilder)(_table[position] ??= new IkvmReflectionParameterSymbolBuilder(_context, _module, (IIkvmReflectionMethodBaseSymbol)_member, parameter)); diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs index 9780e7997..68f30b47d 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs @@ -349,12 +349,15 @@ public virtual IIkvmReflectionPropertySymbolBuilder ResolvePropertySymbol(Proper [return: NotNullIfNotNull(nameof(@event))] public virtual IIkvmReflectionEventSymbol? ResolveEventSymbol(EventInfo? @event) { - return @event == null ? null : _context.GetOrCreateEventSymbol(@event); + if (@event is null) + return null; + + return _context.GetOrCreateEventSymbol(@event); } /// [return: NotNullIfNotNull(nameof(@event))] - public virtual IIkvmReflectionEventSymbolBuilder ResolveEventSymbol(EventBuilder @event) + public virtual IIkvmReflectionEventSymbolBuilder? ResolveEventSymbol(EventBuilder @event) { if (@event is null) throw new ArgumentNullException(nameof(@event)); @@ -383,17 +386,36 @@ public virtual IIkvmReflectionEventSymbolBuilder ResolveEventSymbol(EventBuilder [return: NotNullIfNotNull(nameof(parameter))] public virtual IIkvmReflectionParameterSymbol? ResolveParameterSymbol(ParameterInfo? parameter) { - return parameter == null ? null : _context.GetOrCreateParameterSymbol(parameter); + if (parameter is null) + throw new ArgumentNullException(nameof(parameter)); + + return _context.GetOrCreateParameterSymbol(parameter); } /// [return: NotNullIfNotNull(nameof(parameter))] - public virtual IIkvmReflectionParameterSymbolBuilder ResolveParameterSymbol(ParameterBuilder parameter) + public virtual IIkvmReflectionParameterSymbolBuilder? ResolveParameterSymbol(IIkvmReflectionMethodBaseSymbolBuilder method, ParameterBuilder parameter) { + if (method is null) + throw new ArgumentNullException(nameof(method)); + if (parameter is null) - throw new ArgumentNullException(nameof(parameter)); + return null; - return _context.GetOrCreateParameterSymbol(parameter); + return method.GetOrCreateParameterSymbol(parameter); + } + + /// + [return: NotNullIfNotNull(nameof(parameter))] + public virtual IIkvmReflectionParameterSymbolBuilder? ResolveParameterSymbol(IIkvmReflectionPropertySymbolBuilder property, ParameterBuilder parameter) + { + if (property is null) + throw new ArgumentNullException(nameof(property)); + + if (parameter is null) + return null; + + return property.GetOrCreateParameterSymbol(parameter); } /// diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolContext.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolContext.cs index c7a1c06ee..4cc41b20b 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolContext.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolContext.cs @@ -32,7 +32,7 @@ public IkvmReflectionSymbolContext(Universe universe) } /// - public IAssemblySymbolBuilder DefineAssembly(System.Reflection.AssemblyName name) + public IAssemblySymbolBuilder DefineAssembly(AssemblyNameInfo name) { if (name is null) throw new ArgumentNullException(nameof(name)); @@ -41,7 +41,7 @@ public IAssemblySymbolBuilder DefineAssembly(System.Reflection.AssemblyName name } /// - public IAssemblySymbolBuilder DefineAssembly(System.Reflection.AssemblyName name, ICustomAttributeBuilder[]? assemblyAttributes) + public IAssemblySymbolBuilder DefineAssembly(AssemblyNameInfo name, ICustomAttributeBuilder[]? assemblyAttributes) { if (name is null) throw new ArgumentNullException(nameof(name)); @@ -245,16 +245,6 @@ public IIkvmReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo p return GetOrCreateModuleSymbol(parameter.Module).GetOrCreateParameterSymbol(parameter); } - /// - /// Gets or creates a for the specified . - /// - /// - /// - public IIkvmReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter) - { - return GetOrCreateModuleSymbol((ModuleBuilder)parameter.Module).GetOrCreateParameterSymbol(parameter); - } - /// /// Gets or creates a for the specified . /// @@ -262,11 +252,7 @@ public IIkvmReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(Paramete /// public IIkvmReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) { - return field switch - { - FieldBuilder builder => GetOrCreateFieldSymbol(builder), - _ => GetOrCreateModuleSymbol(field.Module).GetOrCreateFieldSymbol(field) - }; + return GetOrCreateModuleSymbol(field.Module).GetOrCreateFieldSymbol(field); } /// @@ -340,25 +326,52 @@ public IIkvmReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypePa /// public ICustomAttributeBuilder CreateCustomAttribute(IConstructorSymbol con, object?[] constructorArgs) { - return new IkvmReflectionCustomAttributeBuilder(new CustomAttributeBuilder(con.Unpack(), constructorArgs)); + return new IkvmReflectionCustomAttributeBuilder(new CustomAttributeBuilder(con.Unpack(), UnpackArguments(constructorArgs))); } /// public ICustomAttributeBuilder CreateCustomAttribute(IConstructorSymbol con, object?[] constructorArgs, IFieldSymbol[] namedFields, object?[] fieldValues) { - return new IkvmReflectionCustomAttributeBuilder(new CustomAttributeBuilder(con.Unpack(), constructorArgs, namedFields.Unpack(), fieldValues)); + return new IkvmReflectionCustomAttributeBuilder(new CustomAttributeBuilder(con.Unpack(), UnpackArguments(constructorArgs), namedFields.Unpack(), UnpackArguments(fieldValues))); } /// public ICustomAttributeBuilder CreateCustomAttribute(IConstructorSymbol con, object?[] constructorArgs, IPropertySymbol[] namedProperties, object?[] propertyValues) { - return new IkvmReflectionCustomAttributeBuilder(new CustomAttributeBuilder(con.Unpack(), constructorArgs, namedProperties.Unpack(), propertyValues)); + return new IkvmReflectionCustomAttributeBuilder(new CustomAttributeBuilder(con.Unpack(), UnpackArguments(constructorArgs), namedProperties.Unpack(), UnpackArguments(propertyValues))); } /// public ICustomAttributeBuilder CreateCustomAttribute(IConstructorSymbol con, object?[] constructorArgs, IPropertySymbol[] namedProperties, object?[] propertyValues, IFieldSymbol[] namedFields, object?[] fieldValues) { - return new IkvmReflectionCustomAttributeBuilder(new CustomAttributeBuilder(con.Unpack(), constructorArgs, namedProperties.Unpack(), propertyValues, namedFields.Unpack(), fieldValues)); + return new IkvmReflectionCustomAttributeBuilder(new CustomAttributeBuilder(con.Unpack(), UnpackArguments(constructorArgs), namedProperties.Unpack(), UnpackArguments(propertyValues), namedFields.Unpack(), UnpackArguments(fieldValues))); + } + + /// + /// Unpacks a single constructor argument. + /// + /// + /// + object? UnpackArgument(object? constructorArg) + { + if (constructorArg is ITypeSymbol type) + return type.Unpack(); + + return constructorArg; + } + + /// + /// Unpacks a set of constructor arguments. + /// + /// + /// + object?[] UnpackArguments(object?[] constructorArgs) + { + var l = new object?[constructorArgs.Length]; + for (int i = 0; i < constructorArgs.Length; i++) + l[i] = UnpackArgument(constructorArgs[i]); + + return l; } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs index cad0ca912..b99a9ef22 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs @@ -55,13 +55,19 @@ public IIkvmReflectionConstructorSymbol GetOrCreateConstructorSymbol(Constructor /// public IIkvmReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method) { - return _methodTable.GetOrCreateMethodBaseSymbol(method); + if (method is ConstructorInfo ctor) + return GetOrCreateConstructorSymbol(ctor); + else + return GetOrCreateMethodSymbol((MethodInfo)method); } /// public IIkvmReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) { - return _methodTable.GetOrCreateMethodSymbol(method); + if (method.IsMethodDefinition()) + return _methodTable.GetOrCreateMethodSymbol(method); + else + return ResolveMethodSymbol(method.GetGenericMethodDefinition()).GetOrCreateGenericMethodSymbol(method); } /// @@ -433,7 +439,7 @@ public ITypeSymbol[] GetInterfaces(bool inherit = true) if (inherit) return ResolveTypeSymbols(UnderlyingType.GetInterfaces()); else - throw new NotImplementedException(); + return ResolveTypeSymbols(UnderlyingType.__GetDeclaredInterfaces()); } /// diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionUtil.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionUtil.cs index 7a7d30082..7239bb3f3 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionUtil.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionUtil.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Immutable; using IKVM.CoreLib.Symbols.Emit; using IKVM.CoreLib.Symbols.IkvmReflection.Emit; @@ -13,83 +14,55 @@ namespace IKVM.CoreLib.Symbols.IkvmReflection static class IkvmReflectionUtil { -#pragma warning disable SYSLIB0017 // Type or member is obsolete -#pragma warning disable SYSLIB0037 // Type or member is obsolete - /// /// Converts a to a . /// /// /// - public static System.Reflection.AssemblyName Pack(this AssemblyName n) + public static AssemblyNameInfo Pack(this AssemblyName n) { - return new System.Reflection.AssemblyName() - { - Name = n.Name, - Version = n.Version, - CultureInfo = n.CultureInfo, - CultureName = n.CultureName, - ProcessorArchitecture = (System.Reflection.ProcessorArchitecture)n.ProcessorArchitecture, - Flags = (System.Reflection.AssemblyNameFlags)n.Flags, - HashAlgorithm = (System.Configuration.Assemblies.AssemblyHashAlgorithm)n.HashAlgorithm, - ContentType = (System.Reflection.AssemblyContentType)n.ContentType, - VersionCompatibility = (System.Configuration.Assemblies.AssemblyVersionCompatibility)n.VersionCompatibility, - }; + return new AssemblyNameInfo(n.Name, n.Version, n.CultureName, (System.Reflection.AssemblyNameFlags)n.Flags, n.GetPublicKeyToken()?.ToImmutableArray() ?? ImmutableArray.Empty); } -#pragma warning restore SYSLIB0037 // Type or member is obsolete -#pragma warning restore SYSLIB0017 // Type or member is obsolete - /// /// Converts a set of to a set of . /// /// /// - public static System.Reflection.AssemblyName[] Pack(this AssemblyName[] n) + public static AssemblyNameInfo[] Pack(this AssemblyName[] n) { if (n.Length == 0) return []; - var a = new System.Reflection.AssemblyName[n.Length]; + var a = new AssemblyNameInfo[n.Length]; for (int i = 0; i < n.Length; i++) a[i] = n[i].Pack(); return a; } -#pragma warning disable SYSLIB0017 // Type or member is obsolete -#pragma warning disable SYSLIB0037 // Type or member is obsolete - /// - /// Converts a to a . + /// Converts a to a . /// /// /// - public static AssemblyName Unpack(this System.Reflection.AssemblyName n) + public static AssemblyName Unpack(this AssemblyNameInfo n) { return new AssemblyName() { Name = n.Name, Version = n.Version, - CultureInfo = n.CultureInfo, CultureName = n.CultureName, - ProcessorArchitecture = (ProcessorArchitecture)n.ProcessorArchitecture, Flags = (AssemblyNameFlags)n.Flags, - HashAlgorithm = (AssemblyHashAlgorithm)n.HashAlgorithm, - ContentType = (AssemblyContentType)n.ContentType, - VersionCompatibility = (AssemblyVersionCompatibility)n.VersionCompatibility, }; } -#pragma warning restore SYSLIB0037 // Type or member is obsolete -#pragma warning restore SYSLIB0017 // Type or member is obsolete - /// /// Converts a set of to a set of . /// /// /// - public static AssemblyName[] Unpack(this System.Reflection.AssemblyName[] n) + public static AssemblyName[] Unpack(this AssemblyNameInfo[] n) { if (n.Length == 0) return []; @@ -454,7 +427,7 @@ public static bool IsMethodDefinition(this MethodBase method) if (method is null) throw new ArgumentNullException(nameof(method)); - return method.IsGenericMethod == false || (method.IsGenericMethod && method.IsGenericMethodDefinition == true); + return method.IsGenericMethod == false || method.IsGenericMethodDefinition; } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs index 941d04e53..b421a94c6 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.IO; using System.Linq; using System.Reflection; @@ -187,21 +188,26 @@ public IModuleSymbol[] GetModules(bool getResourceModules) } /// - public AssemblyName GetName() + public AssemblyNameInfo GetName() { - return UnderlyingAssembly.GetName(); + return ToAssemblyName(UnderlyingAssembly.GetName()); } /// - public AssemblyName GetName(bool copiedName) + public AssemblyNameInfo[] GetReferencedAssemblies() { - return UnderlyingAssembly.GetName(copiedName); + return UnderlyingAssembly.GetReferencedAssemblies().Select(i => ToAssemblyName(i)).ToArray(); } - /// - public AssemblyName[] GetReferencedAssemblies() + /// + /// Transforms the to a . + /// + /// + /// + /// + AssemblyNameInfo ToAssemblyName(AssemblyName n) { - return UnderlyingAssembly.GetReferencedAssemblies(); + return new AssemblyNameInfo(n.Name ?? throw new InvalidOperationException(), n.Version, n.CultureName, n.Flags, n.GetPublicKeyToken()?.ToImmutableArray() ?? []); } /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionConstructorSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionConstructorSymbolBuilder.cs index 1dcb3c58d..a80569f59 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionConstructorSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionConstructorSymbolBuilder.cs @@ -39,46 +39,50 @@ public ReflectionConstructorSymbolBuilder(ReflectionSymbolContext context, IRefl /// public ConstructorBuilder UnderlyingConstructorBuilder => _builder ?? throw new InvalidOperationException(); - #region IConstructorSymbolBuilder + #region IMethodBaseSymbolBuilder /// - public void SetImplementationFlags(MethodImplAttributes attributes) + public override void SetImplementationFlags(MethodImplAttributes attributes) { UnderlyingConstructorBuilder.SetImplementationFlags(attributes); } /// - public IParameterSymbolBuilder DefineParameter(int iSequence, ParameterAttributes attributes, string? strParamName) + public override IParameterSymbolBuilder DefineParameter(int iSequence, ParameterAttributes attributes, string? strParamName) { return ResolveParameterSymbol(UnderlyingConstructorBuilder.DefineParameter(iSequence, attributes, strParamName)); } /// - public IILGenerator GetILGenerator() + public override IILGenerator GetILGenerator() { return _il ??= new ReflectionILGenerator(Context, UnderlyingConstructorBuilder.GetILGenerator()); } /// - public IILGenerator GetILGenerator(int streamSize) + public override IILGenerator GetILGenerator(int streamSize) { return _il ??= new ReflectionILGenerator(Context, UnderlyingConstructorBuilder.GetILGenerator(streamSize)); } /// - public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) + public override void SetCustomAttribute(ICustomAttributeBuilder customBuilder) { UnderlyingConstructorBuilder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); } /// - public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) + public override void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) { UnderlyingConstructorBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); } #endregion + #region IConstructorSymbolBuilder + + #endregion + #region IConstructorSymbol /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodBaseSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodBaseSymbolBuilder.cs index b662e1a59..d9d283327 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodBaseSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodBaseSymbolBuilder.cs @@ -26,6 +26,28 @@ public ReflectionMethodBaseSymbolBuilder(ReflectionSymbolContext context, IRefle /// public override MemberInfo UnderlyingMember => UnderlyingMethodBase; + #region IMethodBaseSymbolBuilder + + /// + public abstract void SetImplementationFlags(System.Reflection.MethodImplAttributes attributes); + + /// + public abstract IParameterSymbolBuilder DefineParameter(int position, System.Reflection.ParameterAttributes attributes, string? strParamName); + + /// + public abstract IILGenerator GetILGenerator(); + + /// + public abstract IILGenerator GetILGenerator(int streamSize); + + /// + public abstract void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute); + + /// + public abstract void SetCustomAttribute(ICustomAttributeBuilder customBuilder); + + #endregion + #region IMethodBaseSymbol /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs index 7fba722c5..933623740 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs @@ -39,70 +39,74 @@ public ReflectionMethodSymbolBuilder(ReflectionSymbolContext context, IReflectio /// public MethodBuilder UnderlyingMethodBuilder => _builder ?? throw new InvalidOperationException(); - #region IMethodSymbolBuilder + #region IMethodBaseSymbolBuilder /// - public void SetImplementationFlags(MethodImplAttributes attributes) + public override void SetImplementationFlags(MethodImplAttributes attributes) { UnderlyingMethodBuilder.SetImplementationFlags(attributes); } /// - public void SetParameters(params ITypeSymbol[] parameterTypes) + public override IParameterSymbolBuilder DefineParameter(int position, ParameterAttributes attributes, string? strParamName) { - UnderlyingMethodBuilder.SetParameters(parameterTypes.Unpack()); + return ResolveParameterSymbol(UnderlyingMethodBuilder.DefineParameter(position, attributes, strParamName)); } /// - public void SetReturnType(ITypeSymbol? returnType) + public override IILGenerator GetILGenerator() { - UnderlyingMethodBuilder.SetReturnType(returnType?.Unpack()); + return _il ??= new ReflectionILGenerator(Context, UnderlyingMethodBuilder.GetILGenerator()); } /// - public void SetSignature(ITypeSymbol? returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers) + public override IILGenerator GetILGenerator(int streamSize) { - UnderlyingMethodBuilder.SetSignature(returnType?.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack()); + return _il ??= new ReflectionILGenerator(Context, UnderlyingMethodBuilder.GetILGenerator(streamSize)); } - public IGenericTypeParameterSymbolBuilder[] DefineGenericParameters(params string[] names) + /// + public override void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) { - var l = UnderlyingMethodBuilder.DefineGenericParameters(names); - var a = new IGenericTypeParameterSymbolBuilder[l.Length]; - for (int i = 0; i < l.Length; i++) - a[i] = (IGenericTypeParameterSymbolBuilder)ResolveTypeSymbol(l[i]); - - return a; + UnderlyingMethodBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); } /// - public IParameterSymbolBuilder DefineParameter(int position, ParameterAttributes attributes, string? strParamName) + public override void SetCustomAttribute(ICustomAttributeBuilder customBuilder) { - return ResolveParameterSymbol(UnderlyingMethodBuilder.DefineParameter(position, attributes, strParamName)); + UnderlyingMethodBuilder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); } + #endregion + + #region IMethodSymbolBuilder + /// - public IILGenerator GetILGenerator() + public void SetParameters(params ITypeSymbol[] parameterTypes) { - return _il ??= new ReflectionILGenerator(Context, UnderlyingMethodBuilder.GetILGenerator()); + UnderlyingMethodBuilder.SetParameters(parameterTypes.Unpack()); } /// - public IILGenerator GetILGenerator(int streamSize) + public void SetReturnType(ITypeSymbol? returnType) { - return _il ??= new ReflectionILGenerator(Context, UnderlyingMethodBuilder.GetILGenerator(streamSize)); + UnderlyingMethodBuilder.SetReturnType(returnType?.Unpack()); } /// - public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) + public void SetSignature(ITypeSymbol? returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers) { - UnderlyingMethodBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); + UnderlyingMethodBuilder.SetSignature(returnType?.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack()); } - /// - public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) + public IGenericTypeParameterSymbolBuilder[] DefineGenericParameters(params string[] names) { - UnderlyingMethodBuilder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); + var l = UnderlyingMethodBuilder.DefineGenericParameters(names); + var a = new IGenericTypeParameterSymbolBuilder[l.Length]; + for (int i = 0; i < l.Length; i++) + a[i] = (IGenericTypeParameterSymbolBuilder)ResolveTypeSymbol(l[i]); + + return a; } #endregion diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionModuleSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionModuleSymbolBuilder.cs index 0c6e91d2f..42fdb989d 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionModuleSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionModuleSymbolBuilder.cs @@ -87,21 +87,21 @@ public IResourceWriter DefineResource(string name, string description, ResourceA } /// - public IMethodSymbolBuilder DefineGlobalMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol returnType, ITypeSymbol[] parameterTypes) + public IMethodSymbolBuilder DefineGlobalMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes) { - return ResolveMethodSymbol(UnderlyingModuleBuilder.DefineGlobalMethod(name, attributes, callingConvention, returnType.Unpack(), parameterTypes.Unpack())); + return ResolveMethodSymbol(UnderlyingModuleBuilder.DefineGlobalMethod(name, attributes, callingConvention, returnType?.Unpack(), parameterTypes?.Unpack())); } /// - public IMethodSymbolBuilder DefineGlobalMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol returnType, ITypeSymbol[] requiredReturnTypeCustomModifiers, ITypeSymbol[] optionalReturnTypeCustomModifiers, ITypeSymbol[] parameterTypes, ITypeSymbol[][] requiredParameterTypeCustomModifiers, ITypeSymbol[][] optionalParameterTypeCustomModifiers) + public IMethodSymbolBuilder DefineGlobalMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? requiredReturnTypeCustomModifiers, ITypeSymbol[]? optionalReturnTypeCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? requiredParameterTypeCustomModifiers, ITypeSymbol[][]? optionalParameterTypeCustomModifiers) { - return ResolveMethodSymbol(UnderlyingModuleBuilder.DefineGlobalMethod(name, attributes, callingConvention, returnType.Unpack(), requiredReturnTypeCustomModifiers.Unpack(), optionalReturnTypeCustomModifiers.Unpack(), parameterTypes.Unpack(), requiredParameterTypeCustomModifiers.Unpack(), optionalParameterTypeCustomModifiers.Unpack())); + return ResolveMethodSymbol(UnderlyingModuleBuilder.DefineGlobalMethod(name, attributes, callingConvention, returnType?.Unpack(), requiredReturnTypeCustomModifiers?.Unpack(), optionalReturnTypeCustomModifiers?.Unpack(), parameterTypes?.Unpack(), requiredParameterTypeCustomModifiers?.Unpack(), optionalParameterTypeCustomModifiers?.Unpack())); } /// - public IMethodSymbolBuilder DefineGlobalMethod(string name, MethodAttributes attributes, ITypeSymbol returnType, ITypeSymbol[] parameterTypes) + public IMethodSymbolBuilder DefineGlobalMethod(string name, MethodAttributes attributes, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes) { - return ResolveMethodSymbol(UnderlyingModuleBuilder.DefineGlobalMethod(name, attributes, returnType.Unpack(), parameterTypes.Unpack())); + return ResolveMethodSymbol(UnderlyingModuleBuilder.DefineGlobalMethod(name, attributes, returnType?.Unpack(), parameterTypes?.Unpack())); } /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs index 951f0c243..df2d48527 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.IO; using System.Linq; using System.Reflection; @@ -84,21 +85,26 @@ public IModuleSymbol[] GetModules(bool getResourceModules) } /// - public AssemblyName GetName() + public AssemblyNameInfo GetName() { - return _assembly.GetName(); + return ToAssemblyNameInfo(_assembly.GetName()); } /// - public AssemblyName GetName(bool copiedName) + public AssemblyNameInfo[] GetReferencedAssemblies() { - return _assembly.GetName(copiedName); + return _assembly.GetReferencedAssemblies().Select(i => ToAssemblyNameInfo(i)).ToArray(); } - /// - public AssemblyName[] GetReferencedAssemblies() + /// + /// Transforms the to a . + /// + /// + /// + /// + AssemblyNameInfo ToAssemblyNameInfo(AssemblyName n) { - return _assembly.GetReferencedAssemblies(); + return new AssemblyNameInfo(n.Name ?? throw new InvalidOperationException(), n.Version, n.CultureName, n.Flags, n.GetPublicKeyToken()?.ToImmutableArray() ?? []); } /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs index 369833fb7..8b57fc2b6 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs @@ -34,12 +34,12 @@ public ReflectionSymbolContext() /// /// /// - public IAssemblySymbolBuilder DefineAssembly(AssemblyName name) + public IAssemblySymbolBuilder DefineAssembly(AssemblyNameInfo name) { if (name is null) throw new ArgumentNullException(nameof(name)); - return GetOrCreateAssemblySymbol(AssemblyBuilder.DefineDynamicAssembly(name, AssemblyBuilderAccess.RunAndCollect)); + return GetOrCreateAssemblySymbol(AssemblyBuilder.DefineDynamicAssembly(name.Unpack(), AssemblyBuilderAccess.RunAndCollect)); } /// @@ -48,12 +48,12 @@ public IAssemblySymbolBuilder DefineAssembly(AssemblyName name) /// /// /// - public IAssemblySymbolBuilder DefineAssembly(AssemblyName name, ICustomAttributeBuilder[]? assemblyAttributes) + public IAssemblySymbolBuilder DefineAssembly(AssemblyNameInfo name, ICustomAttributeBuilder[]? assemblyAttributes) { if (name is null) throw new ArgumentNullException(nameof(name)); - return GetOrCreateAssemblySymbol(AssemblyBuilder.DefineDynamicAssembly(name, AssemblyBuilderAccess.RunAndCollect, assemblyAttributes?.Unpack())); + return GetOrCreateAssemblySymbol(AssemblyBuilder.DefineDynamicAssembly(name.Unpack(), AssemblyBuilderAccess.RunAndCollect, assemblyAttributes?.Unpack())); } /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionUtil.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionUtil.cs index 10f77d184..26c53e898 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionUtil.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionUtil.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Immutable; using System.Reflection; using System.Reflection.Emit; @@ -11,6 +12,49 @@ namespace IKVM.CoreLib.Symbols.Reflection static class ReflectionUtil { + /// + /// Converts a to a . + /// + /// + /// + public static AssemblyNameInfo Pack(this AssemblyName n) + { + return new AssemblyNameInfo(n.Name ?? throw new InvalidOperationException(), n.Version, n.CultureName, n.Flags, n.GetPublicKeyToken()?.ToImmutableArray() ?? ImmutableArray.Empty); + } + + /// + /// Converts a set of to a set of . + /// + /// + /// + public static AssemblyNameInfo[] Pack(this AssemblyName[] n) + { + if (n.Length == 0) + return []; + + var a = new AssemblyNameInfo[n.Length]; + for (int i = 0; i < n.Length; i++) + a[i] = n[i].Pack(); + + return a; + } + + /// + /// Converts a to a . + /// + /// + /// + public static AssemblyName Unpack(this AssemblyNameInfo n) + { + return new AssemblyName() + { + Name = n.Name, + Version = n.Version, + CultureName = n.CultureName, + Flags = n.Flags, + }; + } + /// /// Unpacks the symbol into their original type. /// diff --git a/src/IKVM.CoreLib/Text/HexConverter.cs b/src/IKVM.CoreLib/Text/HexConverter.cs new file mode 100644 index 000000000..504f43238 --- /dev/null +++ b/src/IKVM.CoreLib/Text/HexConverter.cs @@ -0,0 +1,443 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Diagnostics; +using System.Runtime.CompilerServices; + +namespace IKVM.CoreLib.Text +{ + + internal static class HexConverter + { + + public enum Casing : uint + { + // Output [ '0' .. '9' ] and [ 'A' .. 'F' ]. + Upper = 0, + + // Output [ '0' .. '9' ] and [ 'a' .. 'f' ]. + // This works because values in the range [ 0x30 .. 0x39 ] ([ '0' .. '9' ]) + // already have the 0x20 bit set, so ORing them with 0x20 is a no-op, + // while outputs in the range [ 0x41 .. 0x46 ] ([ 'A' .. 'F' ]) + // don't have the 0x20 bit set, so ORing them maps to + // [ 0x61 .. 0x66 ] ([ 'a' .. 'f' ]), which is what we want. + Lower = 0x2020U, + } + + // We want to pack the incoming byte into a single integer [ 0000 HHHH 0000 LLLL ], + // where HHHH and LLLL are the high and low nibbles of the incoming byte. Then + // subtract this integer from a constant minuend as shown below. + // + // [ 1000 1001 1000 1001 ] + // - [ 0000 HHHH 0000 LLLL ] + // ========================= + // [ *YYY **** *ZZZ **** ] + // + // The end result of this is that YYY is 0b000 if HHHH <= 9, and YYY is 0b111 if HHHH >= 10. + // Similarly, ZZZ is 0b000 if LLLL <= 9, and ZZZ is 0b111 if LLLL >= 10. + // (We don't care about the value of asterisked bits.) + // + // To turn a nibble in the range [ 0 .. 9 ] into hex, we calculate hex := nibble + 48 (ascii '0'). + // To turn a nibble in the range [ 10 .. 15 ] into hex, we calculate hex := nibble - 10 + 65 (ascii 'A'). + // => hex := nibble + 55. + // The difference in the starting ASCII offset is (55 - 48) = 7, depending on whether the nibble is <= 9 or >= 10. + // Since 7 is 0b111, this conveniently matches the YYY or ZZZ value computed during the earlier subtraction. + + // The commented out code below is code that directly implements the logic described above. + + // uint packedOriginalValues = (((uint)value & 0xF0U) << 4) + ((uint)value & 0x0FU); + // uint difference = 0x8989U - packedOriginalValues; + // uint add7Mask = (difference & 0x7070U) >> 4; // line YYY and ZZZ back up with the packed values + // uint packedResult = packedOriginalValues + add7Mask + 0x3030U /* ascii '0' */; + + // The code below is equivalent to the commented out code above but has been tweaked + // to allow codegen to make some extra optimizations. + + // The low byte of the packed result contains the hex representation of the incoming byte's low nibble. + // The adjacent byte of the packed result contains the hex representation of the incoming byte's high nibble. + + // Finally, write to the output buffer starting with the *highest* index so that codegen can + // elide all but the first bounds check. (This only works if 'startingIndex' is a compile-time constant.) + + // The JIT can elide bounds checks if 'startingIndex' is constant and if the caller is + // writing to a span of known length (or the caller has already checked the bounds of the + // furthest access). + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ToBytesBuffer(byte value, Span buffer, int startingIndex = 0, Casing casing = Casing.Upper) + { + uint difference = (((uint)value & 0xF0U) << 4) + ((uint)value & 0x0FU) - 0x8989U; + uint packedResult = ((((uint)(-(int)difference) & 0x7070U) >> 4) + difference + 0xB9B9U) | (uint)casing; + + buffer[startingIndex + 1] = (byte)packedResult; + buffer[startingIndex] = (byte)(packedResult >> 8); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ToCharsBuffer(byte value, Span buffer, int startingIndex = 0, Casing casing = Casing.Upper) + { + uint difference = (((uint)value & 0xF0U) << 4) + ((uint)value & 0x0FU) - 0x8989U; + uint packedResult = ((((uint)(-(int)difference) & 0x7070U) >> 4) + difference + 0xB9B9U) | (uint)casing; + + buffer[startingIndex + 1] = (char)(packedResult & 0xFF); + buffer[startingIndex] = (char)(packedResult >> 8); + } + +#if SYSTEM_PRIVATE_CORELIB + // Converts Vector128 into 2xVector128 ASCII Hex representation + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [CompExactlyDependsOn(typeof(Ssse3))] + [CompExactlyDependsOn(typeof(AdvSimd.Arm64))] + internal static (Vector128, Vector128) AsciiToHexVector128(Vector128 src, Vector128 hexMap) + { + Debug.Assert(Ssse3.IsSupported || AdvSimd.Arm64.IsSupported); + // The algorithm is simple: a single srcVec (contains the whole 16b Guid) is converted + // into nibbles and then, via hexMap, converted into a HEX representation via + // Shuffle(nibbles, srcVec). ASCII is then expanded to UTF-16. + Vector128 shiftedSrc = Vector128.ShiftRightLogical(src.AsUInt64(), 4).AsByte(); + Vector128 lowNibbles = Vector128.UnpackLow(shiftedSrc, src); + Vector128 highNibbles = Vector128.UnpackHigh(shiftedSrc, src); + + return (Vector128.ShuffleUnsafe(hexMap, lowNibbles & Vector128.Create((byte)0xF)), + Vector128.ShuffleUnsafe(hexMap, highNibbles & Vector128.Create((byte)0xF))); + } + + [CompExactlyDependsOn(typeof(Ssse3))] + [CompExactlyDependsOn(typeof(AdvSimd.Arm64))] + private static void EncodeToUtf16_Vector128(ReadOnlySpan bytes, Span chars, Casing casing) + { + Debug.Assert(bytes.Length >= Vector128.Count); + + ref byte srcRef = ref MemoryMarshal.GetReference(bytes); + ref ushort destRef = ref Unsafe.As(ref MemoryMarshal.GetReference(chars)); + + Vector128 hexMap = casing == Casing.Upper ? + Vector128.Create((byte)'0', (byte)'1', (byte)'2', (byte)'3', + (byte)'4', (byte)'5', (byte)'6', (byte)'7', + (byte)'8', (byte)'9', (byte)'A', (byte)'B', + (byte)'C', (byte)'D', (byte)'E', (byte)'F') : + Vector128.Create((byte)'0', (byte)'1', (byte)'2', (byte)'3', + (byte)'4', (byte)'5', (byte)'6', (byte)'7', + (byte)'8', (byte)'9', (byte)'a', (byte)'b', + (byte)'c', (byte)'d', (byte)'e', (byte)'f'); + + nuint pos = 0; + nuint lengthSubVector128 = (nuint)bytes.Length - (nuint)Vector128.Count; + do + { + // This implementation processes 4 bytes of input at once, it can be easily modified + // to support 16 bytes at once, but that didn't demonstrate noticeable wins + // for Converter.ToHexString (around 8% faster for large inputs) so + // it focuses on small inputs instead. + + uint i32 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref srcRef, pos)); + Vector128 vec = Vector128.CreateScalar(i32).AsByte(); + + // JIT is expected to eliminate all unused calculations + (Vector128 hexLow, _) = AsciiToHexVector128(vec, hexMap); + (Vector128 v0, _) = Vector128.Widen(hexLow); + + v0.StoreUnsafe(ref destRef, pos * 2); + + pos += (nuint)Vector128.Count; + if (pos == (nuint)bytes.Length) + { + return; + } + + // Overlap with the current chunk for trailing elements + if (pos > lengthSubVector128) + { + pos = lengthSubVector128; + } + + } while (true); + } +#endif + + public static void EncodeToUtf16(ReadOnlySpan bytes, Span chars, Casing casing = Casing.Upper) + { + Debug.Assert(chars.Length >= bytes.Length * 2); + +#if SYSTEM_PRIVATE_CORELIB + if ((AdvSimd.Arm64.IsSupported || Ssse3.IsSupported) && bytes.Length >= 4) + { + EncodeToUtf16_Vector128(bytes, chars, casing); + return; + } +#endif + for (int pos = 0; pos < bytes.Length; pos++) + { + ToCharsBuffer(bytes[pos], chars, pos * 2, casing); + } + } + + public static unsafe string ToString(ReadOnlySpan bytes, Casing casing = Casing.Upper) + { +#if NETFRAMEWORK || NETSTANDARD2_0 + Span result = bytes.Length > 16 ? + new char[bytes.Length * 2].AsSpan() : + stackalloc char[bytes.Length * 2]; + + int pos = 0; + foreach (byte b in bytes) + { + ToCharsBuffer(b, result, pos, casing); + pos += 2; + } + return result.ToString(); +#else + return string.Create(bytes.Length * 2, (RosPtr: (IntPtr)(&bytes), casing), static (chars, args) => + EncodeToUtf16(*(ReadOnlySpan*)args.RosPtr, chars, args.casing)); +#endif + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static char ToCharUpper(int value) + { + value &= 0xF; + value += '0'; + + if (value > '9') + { + value += ('A' - ('9' + 1)); + } + + return (char)value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static char ToCharLower(int value) + { + value &= 0xF; + value += '0'; + + if (value > '9') + { + value += ('a' - ('9' + 1)); + } + + return (char)value; + } + + public static bool TryDecodeFromUtf16(ReadOnlySpan chars, Span bytes, out int charsProcessed) + { +#if SYSTEM_PRIVATE_CORELIB + if (BitConverter.IsLittleEndian && (Ssse3.IsSupported || AdvSimd.Arm64.IsSupported) && + chars.Length >= Vector128.Count * 2) + { + return TryDecodeFromUtf16_Vector128(chars, bytes, out charsProcessed); + } +#endif + return TryDecodeFromUtf16_Scalar(chars, bytes, out charsProcessed); + } + +#if SYSTEM_PRIVATE_CORELIB + [CompExactlyDependsOn(typeof(AdvSimd.Arm64))] + [CompExactlyDependsOn(typeof(Ssse3))] + public static bool TryDecodeFromUtf16_Vector128(ReadOnlySpan chars, Span bytes, out int charsProcessed) + { + Debug.Assert(Ssse3.IsSupported || AdvSimd.Arm64.IsSupported); + Debug.Assert(chars.Length <= bytes.Length * 2); + Debug.Assert(chars.Length % 2 == 0); + Debug.Assert(chars.Length >= Vector128.Count * 2); + + nuint offset = 0; + nuint lengthSubTwoVector128 = (nuint)chars.Length - ((nuint)Vector128.Count * 2); + + ref ushort srcRef = ref Unsafe.As(ref MemoryMarshal.GetReference(chars)); + ref byte destRef = ref MemoryMarshal.GetReference(bytes); + + do + { + // The algorithm is UTF8 so we'll be loading two UTF-16 vectors to narrow them into a + // single UTF8 ASCII vector - the implementation can be shared with UTF8 paths. + Vector128 vec1 = Vector128.LoadUnsafe(ref srcRef, offset); + Vector128 vec2 = Vector128.LoadUnsafe(ref srcRef, offset + (nuint)Vector128.Count); + Vector128 vec = Ascii.ExtractAsciiVector(vec1, vec2); + + // Based on "Algorithm #3" https://github.com/WojciechMula/toys/blob/master/simd-parse-hex/geoff_algorithm.cpp + // by Geoff Langdale and Wojciech Mula + // Move digits '0'..'9' into range 0xf6..0xff. + Vector128 t1 = vec + Vector128.Create((byte)(0xFF - '9')); + // And then correct the range to 0xf0..0xf9. + // All other bytes become less than 0xf0. + Vector128 t2 = Vector128.SubtractSaturate(t1, Vector128.Create((byte)6)); + // Convert into uppercase 'a'..'f' => 'A'..'F' and + // move hex letter 'A'..'F' into range 0..5. + Vector128 t3 = (vec & Vector128.Create((byte)0xDF)) - Vector128.Create((byte)'A'); + // And correct the range into 10..15. + // The non-hex letters bytes become greater than 0x0f. + Vector128 t4 = Vector128.AddSaturate(t3, Vector128.Create((byte)10)); + // Convert '0'..'9' into nibbles 0..9. Non-digit bytes become + // greater than 0x0f. Finally choose the result: either valid nibble (0..9/10..15) + // or some byte greater than 0x0f. + Vector128 nibbles = Vector128.Min(t2 - Vector128.Create((byte)0xF0), t4); + // Any high bit is a sign that input is not a valid hex data + if (!Utf16Utility.AllCharsInVectorAreAscii(vec1 | vec2) || + Vector128.AddSaturate(nibbles, Vector128.Create((byte)(127 - 15))).ExtractMostSignificantBits() != 0) + { + // Input is either non-ASCII or invalid hex data + break; + } + Vector128 output; + if (Ssse3.IsSupported) + { + output = Ssse3.MultiplyAddAdjacent(nibbles, + Vector128.Create((short)0x0110).AsSByte()).AsByte(); + } + else + { + // Workaround for missing MultiplyAddAdjacent on ARM + Vector128 even = AdvSimd.Arm64.TransposeEven(nibbles, Vector128.Zero).AsInt16(); + Vector128 odd = AdvSimd.Arm64.TransposeOdd(nibbles, Vector128.Zero).AsInt16(); + even = AdvSimd.ShiftLeftLogical(even, 4).AsInt16(); + output = AdvSimd.AddSaturate(even, odd).AsByte(); + } + // Accumulate output in lower INT64 half and take care about endianness + output = Vector128.Shuffle(output, Vector128.Create((byte)0, 2, 4, 6, 8, 10, 12, 14, 0, 0, 0, 0, 0, 0, 0, 0)); + // Store 8 bytes in dest by given offset + Unsafe.WriteUnaligned(ref Unsafe.Add(ref destRef, offset / 2), output.AsUInt64().ToScalar()); + + offset += (nuint)Vector128.Count * 2; + if (offset == (nuint)chars.Length) + { + charsProcessed = chars.Length; + return true; + } + // Overlap with the current chunk for trailing elements + if (offset > lengthSubTwoVector128) + { + offset = lengthSubTwoVector128; + } + } + while (true); + + // Fall back to the scalar routine in case of invalid input. + bool fallbackResult = TryDecodeFromUtf16_Scalar(chars.Slice((int)offset), bytes.Slice((int)(offset / 2)), out int fallbackProcessed); + charsProcessed = (int)offset + fallbackProcessed; + return fallbackResult; + } +#endif + + private static bool TryDecodeFromUtf16_Scalar(ReadOnlySpan chars, Span bytes, out int charsProcessed) + { + Debug.Assert(chars.Length % 2 == 0, "Un-even number of characters provided"); + Debug.Assert(chars.Length / 2 == bytes.Length, "Target buffer not right-sized for provided characters"); + + int i = 0; + int j = 0; + int byteLo = 0; + int byteHi = 0; + while (j < bytes.Length) + { + byteLo = FromChar(chars[i + 1]); + byteHi = FromChar(chars[i]); + + // byteHi hasn't been shifted to the high half yet, so the only way the bitwise or produces this pattern + // is if either byteHi or byteLo was not a hex character. + if ((byteLo | byteHi) == 0xFF) + break; + + bytes[j++] = (byte)((byteHi << 4) | byteLo); + i += 2; + } + + if (byteLo == 0xFF) + i++; + + charsProcessed = i; + return (byteLo | byteHi) != 0xFF; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int FromChar(int c) + { + return c >= CharToHexLookup.Length ? 0xFF : CharToHexLookup[c]; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int FromUpperChar(int c) + { + return c > 71 ? 0xFF : CharToHexLookup[c]; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int FromLowerChar(int c) + { + if ((uint)(c - '0') <= '9' - '0') + return c - '0'; + + if ((uint)(c - 'a') <= 'f' - 'a') + return c - 'a' + 10; + + return 0xFF; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsHexChar(int c) + { + if (IntPtr.Size == 8) + { + // This code path, when used, has no branches and doesn't depend on cache hits, + // so it's faster and does not vary in speed depending on input data distribution. + // We only use this logic on 64-bit systems, as using 64 bit values would otherwise + // be much slower than just using the lookup table anyway (no hardware support). + // The magic constant 18428868213665201664 is a 64 bit value containing 1s at the + // indices corresponding to all the valid hex characters (ie. "0123456789ABCDEFabcdef") + // minus 48 (ie. '0'), and backwards (so from the most significant bit and downwards). + // The offset of 48 for each bit is necessary so that the entire range fits in 64 bits. + // First, we subtract '0' to the input digit (after casting to uint to account for any + // negative inputs). Note that even if this subtraction underflows, this happens before + // the result is zero-extended to ulong, meaning that `i` will always have upper 32 bits + // equal to 0. We then left shift the constant with this offset, and apply a bitmask that + // has the highest bit set (the sign bit) if and only if `c` is in the ['0', '0' + 64) range. + // Then we only need to check whether this final result is less than 0: this will only be + // the case if both `i` was in fact the index of a set bit in the magic constant, and also + // `c` was in the allowed range (this ensures that false positive bit shifts are ignored). + ulong i = (uint)c - '0'; + ulong shift = 18428868213665201664UL << (int)i; + ulong mask = i - 64; + + return (long)(shift & mask) < 0 ? true : false; + } + + return FromChar(c) != 0xFF; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsHexUpperChar(int c) + { + return (uint)(c - '0') <= 9 || (uint)(c - 'A') <= ('F' - 'A'); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsHexLowerChar(int c) + { + return (uint)(c - '0') <= 9 || (uint)(c - 'a') <= ('f' - 'a'); + } + + /// Map from an ASCII char to its hex value, e.g. arr['b'] == 11. 0xFF means it's not a hex digit. + public static ReadOnlySpan CharToHexLookup => + [ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 15 + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 31 + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 47 + 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 63 + 0xFF, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 79 + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 95 + 0xFF, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 111 + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 127 + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 143 + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 159 + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 175 + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 191 + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 207 + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 223 + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 239 + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF // 255 + ]; + + } + +} \ No newline at end of file diff --git a/src/IKVM.CoreLib/Text/ValueStringBuilder.cs b/src/IKVM.CoreLib/Text/ValueStringBuilder.cs new file mode 100644 index 000000000..441893673 --- /dev/null +++ b/src/IKVM.CoreLib/Text/ValueStringBuilder.cs @@ -0,0 +1,339 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Buffers; +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace IKVM.CoreLib.Text +{ + + /// + /// Stolen from dotnet/runtime. + /// + internal ref partial struct ValueStringBuilder + { + + private char[]? _arrayToReturnToPool; + private Span _chars; + private int _pos; + + public ValueStringBuilder(Span initialBuffer) + { + _arrayToReturnToPool = null; + _chars = initialBuffer; + _pos = 0; + } + + public ValueStringBuilder(int initialCapacity) + { + _arrayToReturnToPool = ArrayPool.Shared.Rent(initialCapacity); + _chars = _arrayToReturnToPool; + _pos = 0; + } + + public int Length + { + get => _pos; + set + { + Debug.Assert(value >= 0); + Debug.Assert(value <= _chars.Length); + _pos = value; + } + } + + public int Capacity => _chars.Length; + + public void EnsureCapacity(int capacity) + { + // This is not expected to be called this with negative capacity + Debug.Assert(capacity >= 0); + + // If the caller has a bug and calls this with negative capacity, make sure to call Grow to throw an exception. + if ((uint)capacity > (uint)_chars.Length) + Grow(capacity - _pos); + } + + /// + /// Get a pinnable reference to the builder. + /// Does not ensure there is a null char after + /// This overload is pattern matched in the C# 7.3+ compiler so you can omit + /// the explicit method call, and write eg "fixed (char* c = builder)" + /// + public ref char GetPinnableReference() + { + return ref MemoryMarshal.GetReference(_chars); + } + + /// + /// Get a pinnable reference to the builder. + /// + /// Ensures that the builder has a null char after + public ref char GetPinnableReference(bool terminate) + { + if (terminate) + { + EnsureCapacity(Length + 1); + _chars[Length] = '\0'; + } + return ref MemoryMarshal.GetReference(_chars); + } + + public ref char this[int index] + { + get + { + Debug.Assert(index < _pos); + return ref _chars[index]; + } + } + + public override string ToString() + { + string s = _chars.Slice(0, _pos).ToString(); + Dispose(); + return s; + } + + /// Returns the underlying storage of the builder. + public Span RawChars => _chars; + + /// + /// Returns a span around the contents of the builder. + /// + /// Ensures that the builder has a null char after + public ReadOnlySpan AsSpan(bool terminate) + { + if (terminate) + { + EnsureCapacity(Length + 1); + _chars[Length] = '\0'; + } + return _chars.Slice(0, _pos); + } + + public ReadOnlySpan AsSpan() => _chars.Slice(0, _pos); + public ReadOnlySpan AsSpan(int start) => _chars.Slice(start, _pos - start); + public ReadOnlySpan AsSpan(int start, int length) => _chars.Slice(start, length); + + public bool TryCopyTo(Span destination, out int charsWritten) + { + if (_chars.Slice(0, _pos).TryCopyTo(destination)) + { + charsWritten = _pos; + Dispose(); + return true; + } + else + { + charsWritten = 0; + Dispose(); + return false; + } + } + + public void Insert(int index, char value, int count) + { + if (_pos > _chars.Length - count) + { + Grow(count); + } + + int remaining = _pos - index; + _chars.Slice(index, remaining).CopyTo(_chars.Slice(index + count)); + _chars.Slice(index, count).Fill(value); + _pos += count; + } + + public void Insert(int index, string? s) + { + if (s == null) + { + return; + } + + int count = s.Length; + + if (_pos > (_chars.Length - count)) + { + Grow(count); + } + + int remaining = _pos - index; + _chars.Slice(index, remaining).CopyTo(_chars.Slice(index + count)); + s +#if !NET + .AsSpan() +#endif + .CopyTo(_chars.Slice(index)); + _pos += count; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(char c) + { + int pos = _pos; + Span chars = _chars; + if ((uint)pos < (uint)chars.Length) + { + chars[pos] = c; + _pos = pos + 1; + } + else + { + GrowAndAppend(c); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(string? s) + { + if (s == null) + { + return; + } + + int pos = _pos; + if (s.Length == 1 && (uint)pos < (uint)_chars.Length) // very common case, e.g. appending strings from NumberFormatInfo like separators, percent symbols, etc. + { + _chars[pos] = s[0]; + _pos = pos + 1; + } + else + { + AppendSlow(s); + } + } + + private void AppendSlow(string s) + { + int pos = _pos; + if (pos > _chars.Length - s.Length) + { + Grow(s.Length); + } + + s +#if !NET + .AsSpan() +#endif + .CopyTo(_chars.Slice(pos)); + _pos += s.Length; + } + + public void Append(char c, int count) + { + if (_pos > _chars.Length - count) + { + Grow(count); + } + + Span dst = _chars.Slice(_pos, count); + for (int i = 0; i < dst.Length; i++) + { + dst[i] = c; + } + _pos += count; + } + + public unsafe void Append(char* value, int length) + { + int pos = _pos; + if (pos > _chars.Length - length) + { + Grow(length); + } + + Span dst = _chars.Slice(_pos, length); + for (int i = 0; i < dst.Length; i++) + { + dst[i] = *value++; + } + _pos += length; + } + + public void Append(scoped ReadOnlySpan value) + { + int pos = _pos; + if (pos > _chars.Length - value.Length) + { + Grow(value.Length); + } + + value.CopyTo(_chars.Slice(_pos)); + _pos += value.Length; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Span AppendSpan(int length) + { + int origPos = _pos; + if (origPos > _chars.Length - length) + { + Grow(length); + } + + _pos = origPos + length; + return _chars.Slice(origPos, length); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void GrowAndAppend(char c) + { + Grow(1); + Append(c); + } + + /// + /// Resize the internal buffer either by doubling current buffer size or + /// by adding to + /// whichever is greater. + /// + /// + /// Number of chars requested beyond current position. + /// + [MethodImpl(MethodImplOptions.NoInlining)] + private void Grow(int additionalCapacityBeyondPos) + { + Debug.Assert(additionalCapacityBeyondPos > 0); + Debug.Assert(_pos > _chars.Length - additionalCapacityBeyondPos, "Grow called incorrectly, no resize is needed."); + + const uint ArrayMaxLength = 0x7FFFFFC7; // same as Array.MaxLength + + // Increase to at least the required size (_pos + additionalCapacityBeyondPos), but try + // to double the size if possible, bounding the doubling to not go beyond the max array length. + int newCapacity = (int)Math.Max( + (uint)(_pos + additionalCapacityBeyondPos), + Math.Min((uint)_chars.Length * 2, ArrayMaxLength)); + + // Make sure to let Rent throw an exception if the caller has a bug and the desired capacity is negative. + // This could also go negative if the actual required length wraps around. + char[] poolArray = ArrayPool.Shared.Rent(newCapacity); + + _chars.Slice(0, _pos).CopyTo(poolArray); + + char[]? toReturn = _arrayToReturnToPool; + _chars = _arrayToReturnToPool = poolArray; + if (toReturn != null) + { + ArrayPool.Shared.Return(toReturn); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Dispose() + { + char[]? toReturn = _arrayToReturnToPool; + this = default; // for safety, to avoid using pooled array if this instance is erroneously appended to again + if (toReturn != null) + { + ArrayPool.Shared.Return(toReturn); + } + } + + } + +} diff --git a/src/IKVM.Reflection/Universe.cs b/src/IKVM.Reflection/Universe.cs index e933bc87a..2c71d0993 100644 --- a/src/IKVM.Reflection/Universe.cs +++ b/src/IKVM.Reflection/Universe.cs @@ -204,7 +204,7 @@ static bool GetUseNativeFusion() /// /// Gets the core library. /// - internal Assembly CoreLib => Load(coreLibName); + public Assembly CoreLib => Load(coreLibName); /// /// Attempts to import the type from the core library. diff --git a/src/IKVM.Runtime/Annotation.cs b/src/IKVM.Runtime/Annotation.cs index 69d77735f..932b6e7e8 100644 --- a/src/IKVM.Runtime/Annotation.cs +++ b/src/IKVM.Runtime/Annotation.cs @@ -34,7 +34,7 @@ namespace IKVM.Runtime abstract class Annotation { -#if IMPORTER +#if !EXPORTER internal static Annotation LoadAssemblyCustomAttribute(RuntimeClassLoader loader, object[] def) { @@ -60,10 +60,6 @@ internal static Annotation LoadAssemblyCustomAttribute(RuntimeClassLoader loader return null; } -#endif - -#if !EXPORTER - // NOTE this method returns null if the type could not be found // or if the type is not a Custom Attribute and we're not in the static compiler internal static Annotation Load(RuntimeJavaType owner, object[] def) @@ -303,7 +299,7 @@ private static object[] ValueQualifyClassNames(RuntimeClassLoader loader, object } internal abstract void Apply(RuntimeClassLoader loader, ITypeSymbolBuilder tb, object annotation); - internal abstract void Apply(RuntimeClassLoader loader, IMethodSymbolBuilder mb, object annotation); + internal abstract void Apply(RuntimeClassLoader loader, IMethodBaseSymbolBuilder mb, object annotation); internal abstract void Apply(RuntimeClassLoader loader, IFieldSymbolBuilder fb, object annotation); internal abstract void Apply(RuntimeClassLoader loader, IParameterSymbolBuilder pb, object annotation); internal abstract void Apply(RuntimeClassLoader loader, IAssemblySymbolBuilder ab, object annotation); diff --git a/src/IKVM.Runtime/AttributeHelper.cs b/src/IKVM.Runtime/AttributeHelper.cs index fd2195cb4..f51065581 100644 --- a/src/IKVM.Runtime/AttributeHelper.cs +++ b/src/IKVM.Runtime/AttributeHelper.cs @@ -25,21 +25,17 @@ Jeroen Frijters using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; +using System.Reflection; using System.Runtime.CompilerServices; using IKVM.Attributes; -using IKVM.CoreLib.Diagnostics; using IKVM.ByteCode.Buffers; using IKVM.ByteCode.Decoding; using IKVM.ByteCode.Encoding; +using IKVM.CoreLib.Diagnostics; using IKVM.CoreLib.Symbols; using IKVM.CoreLib.Symbols.Emit; - -#if IMPORTER || EXPORTER -using IKVM.Reflection; -#else -using System.Reflection; -#endif +using IKVM.CoreLib.Symbols.Reflection; #if IMPORTER using IKVM.Tools.Importer; @@ -56,8 +52,6 @@ class AttributeHelper readonly RuntimeContext context; -#if IMPORTER - ICustomAttributeBuilder compilerGeneratedAttribute; ICustomAttributeBuilder ghostInterfaceAttribute; ICustomAttributeBuilder deprecatedAttribute; @@ -80,8 +74,6 @@ class AttributeHelper ITypeSymbol typeofSourceFileAttribute; ITypeSymbol typeofLineNumberTableAttribute; -#endif - ITypeSymbol typeofRemappedClassAttribute; ITypeSymbol typeofRemappedTypeAttribute; ITypeSymbol typeofModifiersAttribute; @@ -105,80 +97,69 @@ class AttributeHelper ITypeSymbol typeofRuntimeVisibleTypeAnnotationsAttribute; ITypeSymbol typeofConstantPoolAttribute; ITypeSymbol typeofDebuggableAttribute; + ITypeSymbol typeofCustomAssemblyClassLoaderAttribute; ICustomAttributeBuilder hideFromJavaAttribute; ICustomAttributeBuilder hideFromReflection; IConstructorSymbol debuggableAttribute; -#if IMPORTER - - ITypeSymbol TypeOfModifiers => typeofModifiers ??= LoadType(typeof(Modifiers)); + ITypeSymbol TypeOfModifiers => typeofModifiers ??= context.Resolver.ResolveRuntimeType(typeof(Modifiers).FullName); - ITypeSymbol TypeOfSourceFileAttribute => typeofSourceFileAttribute ??= LoadType(typeof(IKVM.Attributes.SourceFileAttribute)); + ITypeSymbol TypeOfSourceFileAttribute => typeofSourceFileAttribute ??= context.Resolver.ResolveRuntimeType(typeof(IKVM.Attributes.SourceFileAttribute).FullName); - ITypeSymbol TypeOfLineNumberTableAttribute => typeofLineNumberTableAttribute ??= LoadType(typeof(IKVM.Attributes.LineNumberTableAttribute)); + ITypeSymbol TypeOfLineNumberTableAttribute => typeofLineNumberTableAttribute ??= context.Resolver.ResolveRuntimeType(typeof(IKVM.Attributes.LineNumberTableAttribute).FullName); -#endif - - ITypeSymbol TypeOfRemappedClassAttribute => typeofRemappedClassAttribute ??= LoadType(typeof(RemappedClassAttribute)); + ITypeSymbol TypeOfRemappedClassAttribute => typeofRemappedClassAttribute ??= context.Resolver.ResolveRuntimeType(typeof(RemappedClassAttribute).FullName); - ITypeSymbol TypeOfRemappedTypeAttribute => typeofRemappedTypeAttribute ??= LoadType(typeof(RemappedTypeAttribute)); + ITypeSymbol TypeOfRemappedTypeAttribute => typeofRemappedTypeAttribute ??= context.Resolver.ResolveRuntimeType(typeof(RemappedTypeAttribute).FullName); - ITypeSymbol TypeOfModifiersAttribute => typeofModifiersAttribute ??= LoadType(typeof(ModifiersAttribute)); + ITypeSymbol TypeOfModifiersAttribute => typeofModifiersAttribute ??= context.Resolver.ResolveRuntimeType(typeof(ModifiersAttribute).FullName); - ITypeSymbol TypeOfRemappedInterfaceMethodAttribute => typeofRemappedInterfaceMethodAttribute ??= LoadType(typeof(RemappedInterfaceMethodAttribute)); + ITypeSymbol TypeOfRemappedInterfaceMethodAttribute => typeofRemappedInterfaceMethodAttribute ??= context.Resolver.ResolveRuntimeType(typeof(RemappedInterfaceMethodAttribute).FullName); - ITypeSymbol TypeOfNameSigAttribute => typeofNameSigAttribute ??= LoadType(typeof(NameSigAttribute)); + ITypeSymbol TypeOfNameSigAttribute => typeofNameSigAttribute ??= context.Resolver.ResolveRuntimeType(typeof(NameSigAttribute).FullName); - ITypeSymbol TypeOfJavaModuleAttribute => typeofJavaModuleAttribute ??= LoadType(typeof(JavaModuleAttribute)); + ITypeSymbol TypeOfJavaModuleAttribute => typeofJavaModuleAttribute ??= context.Resolver.ResolveRuntimeType(typeof(JavaModuleAttribute).FullName); - ITypeSymbol TypeOfSignatureAttribute => typeofSignatureAttribute ??= LoadType(typeof(IKVM.Attributes.SignatureAttribute)); + ITypeSymbol TypeOfSignatureAttribute => typeofSignatureAttribute ??= context.Resolver.ResolveRuntimeType(typeof(IKVM.Attributes.SignatureAttribute).FullName); - ITypeSymbol TypeOfInnerClassAttribute => typeofInnerClassAttribute ??= LoadType(typeof(InnerClassAttribute)); + ITypeSymbol TypeOfInnerClassAttribute => typeofInnerClassAttribute ??= context.Resolver.ResolveRuntimeType(typeof(InnerClassAttribute).FullName); - ITypeSymbol TypeOfImplementsAttribute => typeofImplementsAttribute ??= LoadType(typeof(ImplementsAttribute)); + ITypeSymbol TypeOfImplementsAttribute => typeofImplementsAttribute ??= context.Resolver.ResolveRuntimeType(typeof(ImplementsAttribute).FullName); - ITypeSymbol TypeOfGhostInterfaceAttribute => typeofGhostInterfaceAttribute ??= LoadType(typeof(GhostInterfaceAttribute)); + ITypeSymbol TypeOfGhostInterfaceAttribute => typeofGhostInterfaceAttribute ??= context.Resolver.ResolveRuntimeType(typeof(GhostInterfaceAttribute).FullName); - ITypeSymbol TypeOfExceptionIsUnsafeForMappingAttribute => typeofExceptionIsUnsafeForMappingAttribute ??= LoadType(typeof(ExceptionIsUnsafeForMappingAttribute)); + ITypeSymbol TypeOfExceptionIsUnsafeForMappingAttribute => typeofExceptionIsUnsafeForMappingAttribute ??= context.Resolver.ResolveRuntimeType(typeof(ExceptionIsUnsafeForMappingAttribute).FullName); - ITypeSymbol TypeOfThrowsAttribute => typeofThrowsAttribute ??= LoadType(typeof(ThrowsAttribute)); + ITypeSymbol TypeOfThrowsAttribute => typeofThrowsAttribute ??= context.Resolver.ResolveRuntimeType(typeof(ThrowsAttribute).FullName); - ITypeSymbol TypeOfHideFromJavaAttribute => typeofHideFromJavaAttribute ??= LoadType(typeof(HideFromJavaAttribute)); + ITypeSymbol TypeOfHideFromJavaAttribute => typeofHideFromJavaAttribute ??= context.Resolver.ResolveRuntimeType(typeof(HideFromJavaAttribute).FullName); - ITypeSymbol TypeOfHideFromJavaFlags => typeofHideFromJavaFlags ??= LoadType(typeof(HideFromJavaFlags)); + ITypeSymbol TypeOfHideFromJavaFlags => typeofHideFromJavaFlags ??= context.Resolver.ResolveRuntimeType(typeof(HideFromJavaFlags).FullName); - ITypeSymbol TypeOfNoPackagePrefixAttribute => typeofNoPackagePrefixAttribute ??= LoadType(typeof(NoPackagePrefixAttribute)); + ITypeSymbol TypeOfNoPackagePrefixAttribute => typeofNoPackagePrefixAttribute ??= context.Resolver.ResolveRuntimeType(typeof(NoPackagePrefixAttribute).FullName); - ITypeSymbol TypeOfAnnotationAttributeAttribute => typeofAnnotationAttributeAttribute ??= LoadType(typeof(AnnotationAttributeAttribute)); + ITypeSymbol TypeOfAnnotationAttributeAttribute => typeofAnnotationAttributeAttribute ??= context.Resolver.ResolveRuntimeType(typeof(AnnotationAttributeAttribute).FullName); - ITypeSymbol TypeOfNonNestedInnerClassAttribute => typeofNonNestedInnerClassAttribute ??= LoadType(typeof(NonNestedInnerClassAttribute)); + ITypeSymbol TypeOfNonNestedInnerClassAttribute => typeofNonNestedInnerClassAttribute ??= context.Resolver.ResolveRuntimeType(typeof(NonNestedInnerClassAttribute).FullName); - ITypeSymbol TypeOfNonNestedOuterClassAttribute => typeofNonNestedOuterClassAttribute ??= LoadType(typeof(NonNestedOuterClassAttribute)); + ITypeSymbol TypeOfNonNestedOuterClassAttribute => typeofNonNestedOuterClassAttribute ??= context.Resolver.ResolveRuntimeType(typeof(NonNestedOuterClassAttribute).FullName); - ITypeSymbol TypeOfEnclosingMethodAttribute => typeofEnclosingMethodAttribute ??= LoadType(typeof(IKVM.Attributes.EnclosingMethodAttribute)); + ITypeSymbol TypeOfEnclosingMethodAttribute => typeofEnclosingMethodAttribute ??= context.Resolver.ResolveRuntimeType(typeof(IKVM.Attributes.EnclosingMethodAttribute).FullName); - ITypeSymbol TypeOfMethodParametersAttribute => typeofMethodParametersAttribute ??= LoadType(typeof(IKVM.Attributes.MethodParametersAttribute)); + ITypeSymbol TypeOfMethodParametersAttribute => typeofMethodParametersAttribute ??= context.Resolver.ResolveRuntimeType(typeof(IKVM.Attributes.MethodParametersAttribute).FullName); - ITypeSymbol TypeOfRuntimeVisibleTypeAnnotationsAttribute => typeofRuntimeVisibleTypeAnnotationsAttribute ??= LoadType(typeof(IKVM.Attributes.RuntimeVisibleTypeAnnotationsAttribute)); + ITypeSymbol TypeOfRuntimeVisibleTypeAnnotationsAttribute => typeofRuntimeVisibleTypeAnnotationsAttribute ??= context.Resolver.ResolveRuntimeType(typeof(IKVM.Attributes.RuntimeVisibleTypeAnnotationsAttribute).FullName); - ITypeSymbol TypeOfConstantPoolAttribute => typeofConstantPoolAttribute ??= LoadType(typeof(ConstantPoolAttribute)); + ITypeSymbol TypeOfConstantPoolAttribute => typeofConstantPoolAttribute ??= context.Resolver.ResolveRuntimeType(typeof(ConstantPoolAttribute).FullName); ITypeSymbol TypeOfDebuggableAttribute => typeofDebuggableAttribute ??= context.Resolver.ResolveCoreType(typeof(DebuggableAttribute).FullName); + ITypeSymbol TypeOfCustomAssemblyClassLoaderAttribute => typeofCustomAssemblyClassLoaderAttribute ??= context.Resolver.ResolveRuntimeType(typeof(IKVM.Attributes.CustomAssemblyClassLoaderAttribute).FullName); + ICustomAttributeBuilder HideFromJavaAttributeBuilder => hideFromJavaAttribute ??= context.Resolver.Symbols.CreateCustomAttribute(TypeOfHideFromJavaAttribute.GetConstructor([]), []); ICustomAttributeBuilder HideFromReflectionBuilder => hideFromReflection ??= context.Resolver.Symbols.CreateCustomAttribute(TypeOfHideFromJavaAttribute.GetConstructor([TypeOfHideFromJavaFlags]), [HideFromJavaFlags.Reflection | HideFromJavaFlags.StackTrace | HideFromJavaFlags.StackWalk]); - /// - /// Loads the given managed type from the runtime assembly. - /// - /// - /// - ITypeSymbol LoadType(System.Type t) - { - return context.Resolver.ResolveRuntimeType(t.FullName); - } - /// /// Initializes a new instance. /// @@ -320,7 +301,7 @@ ICustomAttributeBuilder CreateCustomAttribute(RuntimeClassLoader loader, IKVM.To GetAttributeArgsAndTypes(loader, attr, out var argTypes, out var args); if (attr.Type != null) { - var t = context.Resolver.ResolveCoreType(attr.Type); + var t = context.Resolver.ResolveType(attr.Type); var ci = t.GetConstructor(argTypes); if (ci == null) throw new InvalidOperationException($"Constructor missing: {attr.Type}::{attr.Sig}"); @@ -404,13 +385,13 @@ ICustomAttributeBuilder GetEditorBrowsableNever() internal void SetCompilerGenerated(ITypeSymbolBuilder tb) { - compilerGeneratedAttribute ??= context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveCoreType(typeof(CompilerGeneratedAttribute).FullName).GetConstructor([]), []); + compilerGeneratedAttribute ??= context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveType(typeof(CompilerGeneratedAttribute).FullName).GetConstructor([]), []); tb.SetCustomAttribute(compilerGeneratedAttribute); } - internal void SetCompilerGenerated(IMethodSymbolBuilder mb) + internal void SetCompilerGenerated(IMethodBaseSymbolBuilder mb) { - compilerGeneratedAttribute ??= context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveCoreType(typeof(CompilerGeneratedAttribute).FullName).GetConstructor([]), []); + compilerGeneratedAttribute ??= context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveType(typeof(CompilerGeneratedAttribute).FullName).GetConstructor([]), []); mb.SetCustomAttribute(compilerGeneratedAttribute); } @@ -419,12 +400,7 @@ internal void SetEditorBrowsableNever(ITypeSymbolBuilder tb) tb.SetCustomAttribute(GetEditorBrowsableNever()); } - internal void SetEditorBrowsableNever(IConstructorSymbolBuilder mb) - { - mb.SetCustomAttribute(GetEditorBrowsableNever()); - } - - internal void SetEditorBrowsableNever(IMethodSymbolBuilder mb) + internal void SetEditorBrowsableNever(IMethodBaseSymbolBuilder mb) { mb.SetCustomAttribute(GetEditorBrowsableNever()); } @@ -434,7 +410,7 @@ internal void SetEditorBrowsableNever(IPropertySymbolBuilder pb) pb.SetCustomAttribute(GetEditorBrowsableNever()); } - internal void SetDeprecatedAttribute(IMethodSymbolBuilder mb) + internal void SetDeprecatedAttribute(IMethodBaseSymbolBuilder mb) { deprecatedAttribute ??= context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveCoreType(typeof(ObsoleteAttribute).FullName).GetConstructor([]), []); mb.SetCustomAttribute(deprecatedAttribute); @@ -458,17 +434,7 @@ internal void SetDeprecatedAttribute(IPropertySymbolBuilder pb) pb.SetCustomAttribute(deprecatedAttribute); } - internal void SetThrowsAttribute(IConstructorSymbolBuilder mb, string[] exceptions) - { - if (exceptions != null && exceptions.Length != 0) - { - throwsAttribute ??= TypeOfThrowsAttribute.GetConstructor([context.Resolver.ResolveCoreType(typeof(string).FullName).MakeArrayType()]); - exceptions = UnicodeUtil.EscapeInvalidSurrogates(exceptions); - mb.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(throwsAttribute, [exceptions])); - } - } - - internal void SetThrowsAttribute(IMethodSymbolBuilder mb, string[] exceptions) + internal void SetThrowsAttribute(IMethodBaseSymbolBuilder mb, string[] exceptions) { if (exceptions != null && exceptions.Length != 0) { @@ -498,7 +464,7 @@ internal void SetNonNestedOuterClass(ITypeSymbolBuilder typeBuilder, string clas #endif // IMPORTER - internal void HideFromReflection(IMethodSymbolBuilder mb) + internal void HideFromReflection(IMethodBaseSymbolBuilder mb) { mb.SetCustomAttribute(HideFromReflectionBuilder); } @@ -518,17 +484,12 @@ internal void HideFromJava(ITypeSymbolBuilder typeBuilder) typeBuilder.SetCustomAttribute(HideFromJavaAttributeBuilder); } - internal void HideFromJava(IConstructorSymbolBuilder ctor) + internal void HideFromJava(IMethodBaseSymbolBuilder ctor) { ctor.SetCustomAttribute(HideFromJavaAttributeBuilder); } - internal void HideFromJava(IMethodSymbolBuilder mb) - { - mb.SetCustomAttribute(HideFromJavaAttributeBuilder); - } - - internal void HideFromJava(IMethodSymbolBuilder mb, HideFromJavaFlags flags) + internal void HideFromJava(IMethodBaseSymbolBuilder mb, HideFromJavaFlags flags) { mb.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(TypeOfHideFromJavaAttribute.GetConstructor([TypeOfHideFromJavaFlags]), [flags])); } @@ -538,15 +499,11 @@ internal void HideFromJava(IFieldSymbolBuilder fb) fb.SetCustomAttribute(HideFromJavaAttributeBuilder); } -#if IMPORTER - internal void HideFromJava(IPropertySymbolBuilder pb) { pb.SetCustomAttribute(HideFromJavaAttributeBuilder); } -#endif - internal bool IsHideFromJava(ITypeSymbol type) { return type.IsDefined(TypeOfHideFromJavaAttribute, false) || (type.IsNested && (type.DeclaringType.IsDefined(TypeOfHideFromJavaAttribute, false) || type.Name.StartsWith("__<", StringComparison.Ordinal))); @@ -584,8 +541,6 @@ internal HideFromJavaFlags GetHideFromJavaFlags(IMemberSymbol mi) return HideFromJavaFlags.None; } -#if IMPORTER - internal void SetImplementsAttribute(ITypeSymbolBuilder typeBuilder, RuntimeJavaType[] ifaceWrappers) { var interfaces = new string[ifaceWrappers.Length]; @@ -598,8 +553,6 @@ internal void SetImplementsAttribute(ITypeSymbolBuilder typeBuilder, RuntimeJava typeBuilder.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(implementsAttribute, [interfaces])); } -#endif - internal bool IsGhostInterface(ITypeSymbol type) { return type.IsDefined(TypeOfGhostInterfaceAttribute, false); @@ -749,18 +702,7 @@ internal void SetDebuggingModes(IAssemblySymbolBuilder assemblyBuilder, Debuggab #if IMPORTER - internal void SetModifiers(IConstructorSymbolBuilder cb, Modifiers modifiers, bool isInternal) - { - ICustomAttributeBuilder customAttributeBuilder; - if (isInternal) - customAttributeBuilder = context.Resolver.Symbols.CreateCustomAttribute(TypeOfModifiersAttribute.GetConstructor([TypeOfModifiers, context.Types.Boolean]), [modifiers, isInternal]); - else - customAttributeBuilder = context.Resolver.Symbols.CreateCustomAttribute(TypeOfModifiersAttribute.GetConstructor([TypeOfModifiers]), [modifiers]); - - cb.SetCustomAttribute(customAttributeBuilder); - } - - internal void SetModifiers(IMethodSymbolBuilder mb, Modifiers modifiers, bool isInternal) + internal void SetModifiers(IMethodBaseSymbolBuilder mb, Modifiers modifiers, bool isInternal) { ICustomAttributeBuilder customAttributeBuilder; if (isInternal) @@ -804,7 +746,7 @@ internal void SetModifiers(ITypeSymbolBuilder tb, Modifiers modifiers, bool isIn tb.SetCustomAttribute(customAttributeBuilder); } - internal void SetNameSig(IMethodSymbolBuilder mb, string name, string sig) + internal void SetNameSig(IMethodBaseSymbolBuilder mb, string name, string sig) { var customAttributeBuilder = context.Resolver.Symbols.CreateCustomAttribute(TypeOfNameSigAttribute.GetConstructor([context.Types.String, context.Types.String]), [UnicodeUtil.EscapeInvalidSurrogates(name), UnicodeUtil.EscapeInvalidSurrogates(sig)]); mb.SetCustomAttribute(customAttributeBuilder); @@ -831,7 +773,7 @@ internal void SetSourceFile(IModuleSymbolBuilder moduleBuilder, string filename) moduleBuilder.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(sourceFileAttribute, [filename])); } - internal void SetLineNumberTable(IMethodSymbolBuilder mb, IKVM.Attributes.LineNumberTableAttribute.LineNumberWriter writer) + internal void SetLineNumberTable(IMethodBaseSymbolBuilder mb, IKVM.Attributes.LineNumberTableAttribute.LineNumberWriter writer) { object arg; IConstructorSymbol con; @@ -869,13 +811,13 @@ internal void SetSignatureAttribute(IFieldSymbolBuilder fb, string signature) fb.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(signatureAttribute, [UnicodeUtil.EscapeInvalidSurrogates(signature)])); } - internal void SetSignatureAttribute(IMethodSymbolBuilder mb, string signature) + internal void SetSignatureAttribute(IMethodBaseSymbolBuilder mb, string signature) { signatureAttribute ??= TypeOfSignatureAttribute.GetConstructor([context.Types.String]); mb.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(signatureAttribute, [UnicodeUtil.EscapeInvalidSurrogates(signature)])); } - internal void SetMethodParametersAttribute(IMethodSymbolBuilder mb, Modifiers[] modifiers) + internal void SetMethodParametersAttribute(IMethodBaseSymbolBuilder mb, Modifiers[] modifiers) { methodParametersAttribute ??= TypeOfMethodParametersAttribute.GetConstructor([TypeOfModifiers.MakeArrayType()]); mb.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(methodParametersAttribute, [modifiers])); @@ -901,7 +843,7 @@ internal void SetRuntimeVisibleTypeAnnotationsAttribute(IFieldSymbolBuilder fb, fb.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(runtimeVisibleTypeAnnotationsAttribute, [builder.ToArray()])); } - internal void SetRuntimeVisibleTypeAnnotationsAttribute(IMethodSymbolBuilder mb, ref readonly TypeAnnotationTable table) + internal void SetRuntimeVisibleTypeAnnotationsAttribute(IMethodBaseSymbolBuilder mb, ref readonly TypeAnnotationTable table) { var builder = new BlobBuilder(); var encoder = new TypeAnnotationTableEncoder(builder); @@ -1080,9 +1022,9 @@ internal string GetAnnotationAttributeType(ITypeSymbol type) return null; } - internal System.Reflection.AssemblyName[] GetInternalsVisibleToAttributes(IAssemblySymbol assembly) + internal AssemblyNameInfo[] GetInternalsVisibleToAttributes(IAssemblySymbol assembly) { - var list = new List(); + var list = new List(); foreach (var cad in assembly.GetCustomAttributes()) { @@ -1090,7 +1032,7 @@ internal System.Reflection.AssemblyName[] GetInternalsVisibleToAttributes(IAssem { try { - list.Add(new System.Reflection.AssemblyName((string)cad.ConstructorArguments[0].Value)); + list.Add(new AssemblyName((string)cad.ConstructorArguments[0].Value).Pack()); } catch { @@ -1141,8 +1083,6 @@ internal IKVM.Attributes.EnclosingMethodAttribute GetEnclosingMethodAttribute(IT return null; } -#if IMPORTER - internal void SetRemappedClass(IAssemblySymbolBuilder assemblyBuilder, string name, ITypeSymbol shadowType) { var remappedClassAttribute = TypeOfRemappedClassAttribute.GetConstructor([context.Types.String, context.Types.Type]); @@ -1167,8 +1107,6 @@ internal void SetExceptionIsUnsafeForMapping(ITypeSymbolBuilder typeBuilder) typeBuilder.SetCustomAttribute(cab); } -#endif - internal void SetRuntimeCompatibilityAttribute(IAssemblySymbolBuilder assemblyBuilder) { var runtimeCompatibilityAttribute = context.Resolver.ResolveCoreType(typeof(RuntimeCompatibilityAttribute).FullName); @@ -1182,6 +1120,12 @@ internal void SetInternalsVisibleToAttribute(IAssemblySymbolBuilder assemblyBuil assemblyBuilder.SetCustomAttribute(cab); } + internal void SetCustomAssemblyClassLoaderAttribute(IAssemblySymbolBuilder assemblyBuilder, ITypeSymbol classLoaderType) + { + var cab = context.Resolver.Symbols.CreateCustomAttribute(TypeOfCustomAssemblyClassLoaderAttribute.GetConstructor([context.Types.Type]), [classLoaderType]); + assemblyBuilder.SetCustomAttribute(cab); + } + } } diff --git a/src/IKVM.Runtime/Attributes/CustomAssemblyClassLoaderAttribute.cs b/src/IKVM.Runtime/Attributes/CustomAssemblyClassLoaderAttribute.cs index 3ae59ca9b..9cd806a03 100644 --- a/src/IKVM.Runtime/Attributes/CustomAssemblyClassLoaderAttribute.cs +++ b/src/IKVM.Runtime/Attributes/CustomAssemblyClassLoaderAttribute.cs @@ -23,10 +23,6 @@ Jeroen Frijters */ using System; -#if IMPORTER || EXPORTER -using Type = IKVM.Reflection.Type; -#endif - namespace IKVM.Attributes { diff --git a/src/IKVM.Runtime/ByteCodeHelper.cs b/src/IKVM.Runtime/ByteCodeHelper.cs index 43f3be833..337d16c35 100644 --- a/src/IKVM.Runtime/ByteCodeHelper.cs +++ b/src/IKVM.Runtime/ByteCodeHelper.cs @@ -27,13 +27,13 @@ Jeroen Frijters using System.Threading; using System.Runtime.CompilerServices; +using IKVM.CoreLib.Symbols; using IKVM.Attributes; using IKVM.ByteCode; #if IMPORTER || EXPORTER using IKVM.Reflection; using IKVM.Reflection.Emit; -using IKVM.Tools.Importer; using Type = IKVM.Reflection.Type; #else @@ -44,6 +44,7 @@ Jeroen Frijters using IKVM.Java.Externs.java.lang.invoke; using IKVM.Runtime.Accessors.Java.Lang; +using IKVM.CoreLib.Reflection; #endif @@ -99,7 +100,7 @@ public static object multianewarray_ghost(RuntimeTypeHandle typeHandle, int[] le { var type = Type.GetTypeFromHandle(typeHandle); int rank = 0; - while (ReflectUtil.IsVector(type)) + while (type.IsSZArray()) { rank++; type = type.GetElementType(); @@ -127,7 +128,7 @@ public static object DynamicMultianewarray(int[] lengths, global::java.lang.Clas Profiler.Count("DynamicMultianewarray"); var wrapper = RuntimeJavaType.FromClass(clazz); - var obj = multianewarray(wrapper.TypeAsArrayType.TypeHandle, lengths); + var obj = multianewarray(wrapper.TypeAsArrayType.AsReflection().TypeHandle, lengths); if (wrapper.IsGhostArray) GhostTag.SetTag(obj, wrapper); @@ -146,7 +147,7 @@ public static object DynamicNewarray(int length, global::java.lang.Class clazz) throw new global::java.lang.NegativeArraySizeException(); var wrapper = RuntimeJavaType.FromClass(clazz); - var obj = Array.CreateInstance(wrapper.TypeAsArrayType, length); + var obj = Array.CreateInstance(wrapper.TypeAsArrayType.AsReflection(), length); if (wrapper.IsGhost || wrapper.IsGhostArray) GhostTag.SetTag(obj, wrapper.MakeArrayType(1)); @@ -573,8 +574,8 @@ public static void arraycopy(object src, int srcStart, object dest, int destStar } else { - object[] src1 = src as object[]; - object[] dst1 = dest as object[]; + var src1 = src as object[]; + var dst1 = dest as object[]; if (src1 != null && dst1 != null) { // for small copies, don't bother comparing the types as this is relatively expensive @@ -594,8 +595,7 @@ public static void arraycopy(object src, int srcStart, object dest, int destStar return; } } - else if (src.GetType() != dest.GetType() && - (IsPrimitiveArrayType(src.GetType()) || IsPrimitiveArrayType(dest.GetType()))) + else if (src.GetType() != dest.GetType() && (IsPrimitiveArrayType(src.GetType()) || IsPrimitiveArrayType(dest.GetType()))) { // we don't want to allow copying a primitive into an object array! throw new global::java.lang.ArrayStoreException(); @@ -616,7 +616,7 @@ public static void arraycopy(object src, int srcStart, object dest, int destStar #endif // !FIRST_PASS } - private static bool IsPrimitiveArrayType(Type type) + private static bool IsPrimitiveArrayType(ITypeSymbol type) { #if FIRST_PASS throw new NotImplementedException(); @@ -625,6 +625,15 @@ private static bool IsPrimitiveArrayType(Type type) #endif } + private static bool IsPrimitiveArrayType(Type type) + { +#if FIRST_PASS + throw new NotImplementedException(); +#else + return type.IsArray && IsPrimitiveArrayType(JVM.Context.Resolver.ImportType(type.GetElementType())); +#endif + } + [DebuggerStepThroughAttribute] public static void arraycopy_fast(Array src, int srcStart, Array dest, int destStart, int len) { @@ -1040,7 +1049,7 @@ public static void InitializeModule(Module module) throw new ArgumentOutOfRangeException(); // check for InitializeModule method present on classloader - var classLoader = JVM.Context.AssemblyClassLoaderFactory.FromAssembly(asm).GetJavaClassLoader(); + var classLoader = JVM.Context.AssemblyClassLoaderFactory.FromAssembly(JVM.Context.Resolver.ImportAssembly(asm)).GetJavaClassLoader(); if (classLoader != null) { var init = (Action)Delegate.CreateDelegate(typeof(Action), classLoader, "InitializeModule", false, false); @@ -1098,8 +1107,8 @@ public static Exception DynamicMapException(Exception x, MapFlags mode, global:: if (exceptionTypeWrapper.IsSubTypeOf(JVM.Context.JavaBase.TypeOfCliSystemException)) mode |= MapFlags.NoRemapping; - var exceptionType = exceptionTypeWrapper == JVM.Context.JavaBase.TypeOfjavaLangThrowable ? typeof(System.Exception) : exceptionTypeWrapper.TypeAsBaseType; - return (Exception)JVM.Context.ByteCodeHelperMethods.MapException.MakeGenericMethod(exceptionType).Invoke(null, new object[] { x, mode }); + var exceptionType = exceptionTypeWrapper == JVM.Context.JavaBase.TypeOfjavaLangThrowable ? JVM.Context.Resolver.ResolveCoreType(typeof(System.Exception).FullName) : exceptionTypeWrapper.TypeAsBaseType; + return (Exception)JVM.Context.ByteCodeHelperMethods.MapException.MakeGenericMethod(exceptionType).AsReflection().Invoke(null, [x, mode]); #endif } diff --git a/src/IKVM.Runtime/CodeEmitter.cs b/src/IKVM.Runtime/CodeEmitter.cs index 59f1fde78..1df5466c4 100644 --- a/src/IKVM.Runtime/CodeEmitter.cs +++ b/src/IKVM.Runtime/CodeEmitter.cs @@ -61,11 +61,11 @@ public CodeEmitterFactory(RuntimeContext context) public IMethodSymbol VerboseCastFailureMethod => verboseCastFailure ??= JVM.SafeGetEnvironmentVariable("IKVM_VERBOSE_CAST") == null ? null : context.ByteCodeHelperMethods.VerboseCastFailure; - public IMethodSymbol MonitorEnterMethod => monitorEnter ??= context.Resolver.ResolveCoreType(typeof(System.Threading.Monitor).FullName).GetMethod("Enter", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static, [context.Types.Object]); + public IMethodSymbol MonitorEnterMethod => monitorEnter ??= context.Resolver.ResolveType(typeof(System.Threading.Monitor).FullName).GetMethod("Enter", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static, [context.Types.Object]); - public IMethodSymbol MonitorExitMethod => monitorExit ??= context.Resolver.ResolveCoreType(typeof(System.Threading.Monitor).FullName).GetMethod("Exit", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static, [context.Types.Object]); + public IMethodSymbol MonitorExitMethod => monitorExit ??= context.Resolver.ResolveType(typeof(System.Threading.Monitor).FullName).GetMethod("Exit", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static, [context.Types.Object]); - public IMethodSymbol MemoryBarrierMethod => memoryBarrier ??= context.Resolver.ResolveCoreType(typeof(System.Threading.Thread).FullName).GetMethod("MemoryBarrier", []); + public IMethodSymbol MemoryBarrierMethod => memoryBarrier ??= context.Resolver.ResolveType(typeof(System.Threading.Thread).FullName).GetMethod("MemoryBarrier", []); public bool ExperimentalOptimizations = JVM.SafeGetEnvironmentVariable("IKVM_EXPERIMENTAL_OPTIMIZATIONS") != null; @@ -74,21 +74,11 @@ public CodeEmitterFactory(RuntimeContext context) /// /// /// - public CodeEmitter Create(IMethodSymbolBuilder method) + public CodeEmitter Create(IMethodBaseSymbolBuilder method) { return new CodeEmitter(context, method.GetILGenerator(), method.DeclaringType); } - /// - /// Creates a new instance. - /// - /// - /// - public CodeEmitter Create(IConstructorSymbolBuilder ctor) - { - return new CodeEmitter(context, ctor.GetILGenerator(), ctor.DeclaringType); - } - #if IMPORTER == false /// @@ -338,10 +328,9 @@ private void RealEmitPseudoOpCode(int ilOffset, CodeType type, object data) break; case CodeType.SequencePoint: // MarkSequencePoint does not exist in Core, but does exist in Framework and IKVM.Reflection -#if NETFRAMEWORK || IMPORTER if (symbols != null) ilgen_real.MarkSequencePoint(symbols, (int)data, 0, (int)data + 1, 0); -#endif + // we emit a nop to make sure we always have an instruction associated with the sequence point ilgen_real.Emit(System.Reflection.Emit.OpCodes.Nop); break; @@ -2431,7 +2420,7 @@ internal byte[] GetLineNumberTable() #if IMPORTER - internal void EmitLineNumberTable(IMethodSymbolBuilder mb) + internal void EmitLineNumberTable(IMethodBaseSymbolBuilder mb) { if (linenums != null) context.AttributeHelper.SetLineNumberTable(mb, linenums); diff --git a/src/IKVM.Runtime/DefineMethodHelper.cs b/src/IKVM.Runtime/DefineMethodHelper.cs index d6e041c68..78a473144 100644 --- a/src/IKVM.Runtime/DefineMethodHelper.cs +++ b/src/IKVM.Runtime/DefineMethodHelper.cs @@ -72,21 +72,23 @@ internal IMethodSymbolBuilder DefineMethod(RuntimeJavaTypeFactory context, IType var parameters = mw.GetParameters(); var parameterTypes = new ITypeSymbol[parameters.Length + (mw.HasCallerID ? 1 : 0) + firstParam]; var modopt = new ITypeSymbol[parameterTypes.Length][]; + if (firstParameter != null) { parameterTypes[0] = firstParameter; modopt[0] = []; } + for (int i = 0; i < parameters.Length; i++) { - parameterTypes[i + firstParam] = mustBePublic - ? parameters[i].TypeAsPublicSignatureType - : parameters[i].TypeAsSignatureType; + parameterTypes[i + firstParam] = mustBePublic ? parameters[i].TypeAsPublicSignatureType : parameters[i].TypeAsSignatureType; modopt[i + firstParam] = RuntimeByteCodeJavaType.GetModOpt(context, parameters[i], mustBePublic); } + if (mw.HasCallerID) { parameterTypes[parameterTypes.Length - 1] = mw.DeclaringType.Context.JavaBase.TypeOfIkvmInternalCallerID.TypeAsSignatureType; + modopt[parameterTypes.Length - 1] = []; } var returnType = mustBePublic ? mw.ReturnType.TypeAsPublicSignatureType : mw.ReturnType.TypeAsSignatureType; @@ -94,14 +96,35 @@ internal IMethodSymbolBuilder DefineMethod(RuntimeJavaTypeFactory context, IType return tb.DefineMethod(name, attribs, System.Reflection.CallingConventions.Standard, returnType, null, modoptReturnType, parameterTypes, null, modopt); } - internal IMethodSymbolBuilder DefineConstructor(RuntimeByteCodeJavaType context, ITypeSymbolBuilder tb, System.Reflection.MethodAttributes attribs) + internal IConstructorSymbolBuilder DefineConstructor(RuntimeByteCodeJavaType context, ITypeSymbolBuilder tb, System.Reflection.MethodAttributes attribs) { - return DefineConstructor(context.ClassLoader.GetTypeWrapperFactory(), tb, attribs); + return DefineConstructor(context.ClassLoader.GetTypeWrapperFactory(), tb, attribs, false); } - internal IMethodSymbolBuilder DefineConstructor(RuntimeJavaTypeFactory context, ITypeSymbolBuilder tb, System.Reflection.MethodAttributes attribs) + internal IConstructorSymbolBuilder DefineConstructor(RuntimeJavaTypeFactory context, ITypeSymbolBuilder tb, System.Reflection.MethodAttributes attribs) { - return DefineMethod(context, tb, ConstructorInfo.ConstructorName, attribs | System.Reflection.MethodAttributes.SpecialName | System.Reflection.MethodAttributes.RTSpecialName); + return DefineConstructor(context, tb, attribs, false); + } + + internal IConstructorSymbolBuilder DefineConstructor(RuntimeJavaTypeFactory context, ITypeSymbolBuilder tb, System.Reflection.MethodAttributes attribs, bool mustBePublic) + { + // we add optional modifiers to make the signature unique + var parameters = mw.GetParameters(); + var parameterTypes = new ITypeSymbol[parameters.Length + (mw.HasCallerID ? 1 : 0)]; + var modopt = new ITypeSymbol[parameterTypes.Length][]; + for (int i = 0; i < parameters.Length; i++) + { + parameterTypes[i] = mustBePublic ? parameters[i].TypeAsPublicSignatureType : parameters[i].TypeAsSignatureType; + modopt[i] = RuntimeByteCodeJavaType.GetModOpt(context, parameters[i], mustBePublic); + } + + if (mw.HasCallerID) + { + parameterTypes[parameterTypes.Length - 1] = mw.DeclaringType.Context.JavaBase.TypeOfIkvmInternalCallerID.TypeAsSignatureType; + modopt[parameterTypes.Length - 1] = []; + } + + return tb.DefineConstructor(attribs, System.Reflection.CallingConventions.Standard, parameterTypes, null, modopt); } } diff --git a/src/IKVM.Runtime/DynamicClassLoader.cs b/src/IKVM.Runtime/DynamicClassLoader.cs index 8a82599a4..dff4b4656 100644 --- a/src/IKVM.Runtime/DynamicClassLoader.cs +++ b/src/IKVM.Runtime/DynamicClassLoader.cs @@ -32,6 +32,8 @@ Jeroen Frijters using IKVM.CoreLib.Symbols; using static System.Diagnostics.DebuggableAttribute; +using System.Collections.Immutable; + #if IMPORTER using IKVM.Reflection; @@ -137,10 +139,12 @@ public DynamicClassLoader GetOrCreate(RuntimeClassLoader loader) { if (attr.AssemblyName == name) { - var n = new AssemblyName(name); + byte[] kp = []; #if NETFRAMEWORK - n.KeyPair = DynamicClassLoader.ForgedKeyPair.Instance; + kp = DynamicClassLoader.ForgedKeyPair.Instance.PublicKey; #endif + + var n = new AssemblyNameInfo(name, publicKeyOrToken: kp.ToImmutableArray()); return new DynamicClassLoader(context, loader.Diagnostics, DynamicClassLoader.CreateModuleBuilder(context, n), true); } } @@ -442,8 +446,7 @@ internal void FinishAll() internal static IModuleSymbolBuilder CreateJniProxyModuleBuilder(RuntimeContext context) { - var name = new AssemblyName("jniproxy"); - jniProxyAssemblyBuilder = DefineDynamicAssembly(context, name, AssemblyBuilderAccess.Run, null); + jniProxyAssemblyBuilder = DefineDynamicAssembly(context, new AssemblyNameInfo("jniproxy"), null); return jniProxyAssemblyBuilder.DefineModule("jniproxy.dll"); } @@ -515,24 +518,21 @@ private static SerializationInfo ToInfo(byte[] publicKey) public static IModuleSymbolBuilder CreateModuleBuilder(RuntimeContext context) { - AssemblyName name = new AssemblyName(); - name.Name = "ikvm_dynamic_assembly__" + (uint)Environment.TickCount; - return CreateModuleBuilder(context, name); + return CreateModuleBuilder(context, new AssemblyNameInfo("ikvm_dynamic_assembly__" + (uint)Environment.TickCount)); } - public static IModuleSymbolBuilder CreateModuleBuilder(RuntimeContext context, AssemblyName name) + public static IModuleSymbolBuilder CreateModuleBuilder(RuntimeContext context, AssemblyNameInfo name) { var now = DateTime.Now; - name.Version = new Version(now.Year, (now.Month * 100) + now.Day, (now.Hour * 100) + now.Minute, (now.Second * 1000) + now.Millisecond); + name = new AssemblyNameInfo(name.Name, new Version(now.Year, (now.Month * 100) + now.Day, (now.Hour * 100) + now.Minute, (now.Second * 1000) + now.Millisecond)); var attribs = new List(); - var access = AssemblyBuilderAccess.Run; #if NETFRAMEWORK if (!AppDomain.CurrentDomain.IsFullyTrusted) attribs.Add(context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveCoreType(typeof(System.Security.SecurityTransparentAttribute).FullName).GetConstructor([]), [])); #endif - var assemblyBuilder = DefineDynamicAssembly(context, name, access, attribs.ToArray()); + var assemblyBuilder = DefineDynamicAssembly(context, name, attribs.ToArray()); context.AttributeHelper.SetRuntimeCompatibilityAttribute(assemblyBuilder); // determine debugging mode @@ -548,9 +548,9 @@ public static IModuleSymbolBuilder CreateModuleBuilder(RuntimeContext context, A return moduleBuilder; } - static IAssemblySymbolBuilder DefineDynamicAssembly(RuntimeContext context, AssemblyName name, AssemblyBuilderAccess access, ICustomAttributeBuilder[] assemblyAttributes) + static IAssemblySymbolBuilder DefineDynamicAssembly(RuntimeContext context, AssemblyNameInfo name, ICustomAttributeBuilder[] assemblyAttributes) { - return context.Resolver.Symbols.DefineAssembly(name, access, assemblyAttributes); + return context.Resolver.Symbols.DefineAssembly(name, assemblyAttributes); } #endif diff --git a/src/IKVM.Runtime/DynamicMethodUtil.cs b/src/IKVM.Runtime/DynamicMethodUtil.cs index 81cde41b1..aa1972117 100644 --- a/src/IKVM.Runtime/DynamicMethodUtil.cs +++ b/src/IKVM.Runtime/DynamicMethodUtil.cs @@ -87,7 +87,7 @@ static DynamicMethod CreateFramework(string name, Type owner, bool nonPublic, Ty /// static DynamicMethod CreateCore(string name, Type owner, bool nonPublic, Type returnType, Type[] paramTypes) { - if (ReflectUtil.CanOwnDynamicMethod(owner)) + if (ReflectUtil.CanOwnDynamicMethod(owner)) return new DynamicMethod(name, returnType, paramTypes, owner); else return new DynamicMethod(name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, paramTypes, owner.Module, true); diff --git a/src/IKVM.Runtime/ExceptionHelper.cs b/src/IKVM.Runtime/ExceptionHelper.cs index d9151e11a..20ab5b79a 100644 --- a/src/IKVM.Runtime/ExceptionHelper.cs +++ b/src/IKVM.Runtime/ExceptionHelper.cs @@ -381,7 +381,7 @@ int GetLineNumber(StackFrame frame) var mb = frame.GetMethod(); if (mb != null && mb.DeclaringType != null) { - var mbs = context.Resolver.ResolveMethodBase(mb); + var mbs = context.Resolver.ImportMethodBase(mb); if (context.ClassLoaderFactory.IsRemappedType(mbs.DeclaringType)) return -1; @@ -399,7 +399,7 @@ string GetFileName(StackFrame frame) var mb = frame.GetMethod(); if (mb != null && mb.DeclaringType != null) { - var mbs = context.Resolver.ResolveMethodBase(mb); + var mbs = context.Resolver.ImportMethodBase(mb); if (context.ClassLoaderFactory.IsRemappedType(mbs.DeclaringType)) return null; diff --git a/src/IKVM.Runtime/IRuntimeSymbolResolver.cs b/src/IKVM.Runtime/IRuntimeSymbolResolver.cs index 6c48e74ad..c3ae1c176 100644 --- a/src/IKVM.Runtime/IRuntimeSymbolResolver.cs +++ b/src/IKVM.Runtime/IRuntimeSymbolResolver.cs @@ -29,68 +29,94 @@ interface IRuntimeSymbolResolver : ISymbolResolver /// ISymbolContext Symbols { get; } + /// + /// Gets the known runtime assembly. + /// + /// + IAssemblySymbol ResolveRuntimeAssembly(); + + /// + /// Resolves the named type from the IKVM runtime assembly. + /// + /// + /// + ITypeSymbol ResolveRuntimeType(string typeName); + + /// + /// Resolves the known Java base assembly. + /// + /// + IAssemblySymbol ResolveBaseAssembly(); + + /// + /// Resolves the named type from the IKVM Java assembly. + /// + /// + /// + ITypeSymbol ResolveBaseType(string typeName); + /// /// Gets the associated with the specified assembly. /// /// /// - IAssemblySymbol? ResolveAssembly(Assembly? assembly); + IAssemblySymbol ImportAssembly(Assembly assembly); /// /// Gets the associated with the specified assembly. /// /// /// - IAssemblySymbolBuilder? ResolveAssembly(AssemblyBuilder? assembly); + IAssemblySymbolBuilder?ImportAssembly(AssemblyBuilder assembly); /// /// Gets the associated with the specified module. /// /// /// - IModuleSymbol? ResolveModule(Module? module); + IModuleSymbol ImportModule(Module module); /// /// Gets the associated with the specified module. /// /// /// - IModuleSymbolBuilder? ResolveModule(ModuleBuilder? module); + IModuleSymbolBuilder ImportModule(ModuleBuilder module); /// /// Gets the associated with the specified type. /// /// /// - ITypeSymbol? ResolveType(Type? type); + ITypeSymbol ImportType(Type type); /// /// Gets the associated with the specified member. /// /// /// - IMemberSymbol? ResolveMember(MemberInfo? memberInfo); + IMemberSymbol ImportMember(MemberInfo memberInfo); /// /// Gets the associated with the specified method. /// /// /// - IMethodBaseSymbol? ResolveMethodBase(MethodBase? type); + IMethodBaseSymbol ImportMethodBase(MethodBase type); /// /// Gets the associated with the specified method. /// /// /// - IConstructorSymbol? ResolveConstructor(ConstructorInfo? ctor); + IConstructorSymbol ImportConstructor(ConstructorInfo ctor); /// /// Gets the associated with the specified method. /// /// /// - IMethodSymbol? ResolveMethod(MethodInfo? method); + IMethodSymbol ImportMethod(MethodInfo method); } diff --git a/src/IKVM.Runtime/JVM.Resolver.cs b/src/IKVM.Runtime/JVM.Resolver.cs index 18fc01b75..6174d0a9c 100644 --- a/src/IKVM.Runtime/JVM.Resolver.cs +++ b/src/IKVM.Runtime/JVM.Resolver.cs @@ -92,7 +92,7 @@ public ITypeSymbol ResolveRuntimeType(string typeName) } /// - public ITypeSymbol ResolveType(Type type) + public ITypeSymbol ImportType(Type type) { return type is { } t ? _context.GetOrCreateTypeSymbol(t) : null; } diff --git a/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Util.cs b/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Util.cs index 98f7c118a..b8735c4d1 100644 --- a/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Util.cs +++ b/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Util.cs @@ -50,7 +50,7 @@ internal static RuntimeJavaType GetTypeWrapperFromObject(RuntimeContext context, return ghostType; var t = o.GetType(); - var ts = context.Resolver.ResolveType(t); + var ts = context.Resolver.ImportType(t); if (t.IsPrimitive || context.ClassLoaderFactory.IsRemappedType(ts) && !ts.IsSealed) return context.ManagedJavaTypeFactory.GetJavaTypeFromManagedType(ts); @@ -73,7 +73,7 @@ internal static RuntimeJavaType GetTypeWrapperFromObject(RuntimeContext context, throw new NotImplementedException(); #else var t = Type.GetTypeFromHandle(handle); - var ts = JVM.Context.Resolver.ResolveType(t); + var ts = JVM.Context.Resolver.ImportType(t); if (t.IsPrimitive || JVM.Context.ClassLoaderFactory.IsRemappedType(ts) || t == typeof(void)) return JVM.Context.ManagedJavaTypeFactory.GetJavaTypeFromManagedType(ts).ClassObject; @@ -94,7 +94,7 @@ internal static RuntimeJavaType GetTypeWrapperFromObject(RuntimeContext context, throw new NotImplementedException(); #else var t = Type.GetTypeFromHandle(handle); - var ts = JVM.Context.Resolver.ResolveType(t); + var ts = JVM.Context.Resolver.ImportType(t); if (ts.IsPrimitive || JVM.Context.ClassLoaderFactory.IsRemappedType(ts) || ts == typeof(void)) return JVM.Context.ManagedJavaTypeFactory.GetJavaTypeFromManagedType(ts).MakeArrayType(rank).ClassObject; @@ -114,7 +114,7 @@ internal static RuntimeJavaType GetTypeWrapperFromObject(RuntimeContext context, #if FIRST_PASS throw new NotImplementedException(); #else - var ts = JVM.Context.Resolver.ResolveType(type); + var ts = JVM.Context.Resolver.ImportType(type); int rank = 0; while (ReflectUtil.IsVector(ts)) diff --git a/src/IKVM.Runtime/Java/Externs/java/lang/Class.cs b/src/IKVM.Runtime/Java/Externs/java/lang/Class.cs index ea4d8fa57..cab514262 100644 --- a/src/IKVM.Runtime/Java/Externs/java/lang/Class.cs +++ b/src/IKVM.Runtime/Java/Externs/java/lang/Class.cs @@ -72,7 +72,7 @@ static class Class var type = Type.GetType(name); if (type != null) - tw = JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(JVM.Context.Resolver.ResolveType(type)); + tw = JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(JVM.Context.Resolver.ImportType(type)); if (tw == null) { diff --git a/src/IKVM.Runtime/ReflectUtil.cs b/src/IKVM.Runtime/ReflectUtil.cs index 86868c4bb..96cce87e5 100644 --- a/src/IKVM.Runtime/ReflectUtil.cs +++ b/src/IKVM.Runtime/ReflectUtil.cs @@ -26,6 +26,9 @@ Jeroen Frijters using IKVM.CoreLib.Symbols; using IKVM.CoreLib.Symbols.Emit; +using System.Collections.Immutable; + + #if IMPORTER || EXPORTER using IKVM.Reflection; using IKVM.Reflection.Emit; @@ -116,29 +119,19 @@ internal static bool IsDynamicMethod(IMethodSymbol method) } } - internal static IMethodSymbolBuilder DefineTypeInitializer(ITypeSymbolBuilder typeBuilder, RuntimeClassLoader loader) + internal static IConstructorSymbolBuilder DefineTypeInitializer(ITypeSymbolBuilder typeBuilder, RuntimeClassLoader loader) { - var attr = System.Reflection.MethodAttributes.Static | System.Reflection.MethodAttributes.RTSpecialName | System.Reflection.MethodAttributes.SpecialName | System.Reflection.MethodAttributes.Private; - return typeBuilder.DefineMethod(ConstructorInfo.TypeConstructorName, attr, null, []); + return typeBuilder.DefineTypeInitializer(); } - internal static bool MatchNameAndPublicKeyToken(System.Reflection.AssemblyName name1, System.Reflection.AssemblyName name2) + internal static bool MatchNameAndPublicKeyToken(AssemblyNameInfo name1, AssemblyNameInfo name2) { - return name1.Name.Equals(name2.Name, StringComparison.OrdinalIgnoreCase) && CompareKeys(name1.GetPublicKeyToken(), name2.GetPublicKeyToken()); + return name1.Name.Equals(name2.Name, StringComparison.OrdinalIgnoreCase) && CompareKeys(name1.PublicKeyOrToken, name2.PublicKeyOrToken); } - static bool CompareKeys(byte[] b1, byte[] b2) + static bool CompareKeys(ImmutableArray b1, ImmutableArray b2) { - int len1 = b1 == null ? 0 : b1.Length; - int len2 = b2 == null ? 0 : b2.Length; - if (len1 != len2) - return false; - - for (int i = 0; i < len1; i++) - if (b1[i] != b2[i]) - return false; - - return true; + return b1.AsSpan().SequenceEqual(b2.AsSpan()); } internal static bool IsConstructor(IMethodBaseSymbol method) @@ -156,7 +149,7 @@ internal static IConstructorSymbolBuilder DefineConstructor(ITypeSymbolBuilder t /// /// /// - internal static bool CanOwnDynamicMethod(ITypeSymbol type) + internal static bool CanOwnDynamicMethod(Type type) { return type != null && !type.IsInterface && !type.HasElementType && !type.IsGenericTypeDefinition && !type.IsGenericParameter; } diff --git a/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs b/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs index e44241a4a..9869a856e 100644 --- a/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs +++ b/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs @@ -75,7 +75,7 @@ sealed class AssemblyLoader IModuleSymbol[] modules; Dictionary nameMap; bool hasDotNetModule; - System.Reflection.AssemblyName[] internalsVisibleTo; + AssemblyNameInfo[] internalsVisibleTo; string[] jarList; #if !IMPORTER && !EXPORTER && !FIRST_PASS sun.misc.URLClassPath urlClassPath; @@ -384,7 +384,7 @@ internal RuntimeJavaType CreateJavaTypeForAssemblyType(ITypeSymbol type) } } - internal bool InternalsVisibleTo(System.Reflection.AssemblyName otherName) + internal bool InternalsVisibleTo(AssemblyNameInfo otherName) { if (internalsVisibleTo == null) Interlocked.CompareExchange(ref internalsVisibleTo, loader.Context.AttributeHelper.GetInternalsVisibleToAttributes(assembly), null); @@ -394,9 +394,7 @@ internal bool InternalsVisibleTo(System.Reflection.AssemblyName otherName) // we match the simple name and PublicKeyToken (because the AssemblyName constructor used // by GetInternalsVisibleToAttributes() only sets the PublicKeyToken, even if a PublicKey is specified) if (ReflectUtil.MatchNameAndPublicKeyToken(name, otherName)) - { return true; - } } return false; @@ -1176,7 +1174,7 @@ Type GetCustomClassLoaderType() var attribs = assembly.GetCustomAttribute(Context.Resolver.ResolveRuntimeType(typeof(CustomAssemblyClassLoaderAttribute).FullName), false); if (attribs is not null) - return new CustomAssemblyClassLoaderAttribute((System.Type)attribs.Value.ConstructorArguments[0].Value); + return ((ITypeSymbol)attribs.Value.ConstructorArguments[0].Value).AsReflection(); return null; } @@ -1286,7 +1284,7 @@ sealed class CustomClassLoaderCtorCaller : java.security.PrivilegedAction readonly ConstructorInfo ctor; readonly object classLoader; - readonly Assembly assembly; + readonly IAssemblySymbol assembly; /// /// Initializes a new instance. @@ -1294,7 +1292,7 @@ sealed class CustomClassLoaderCtorCaller : java.security.PrivilegedAction /// /// /// - internal CustomClassLoaderCtorCaller(ConstructorInfo ctor, object classLoader, Assembly assembly) + internal CustomClassLoaderCtorCaller(ConstructorInfo ctor, object classLoader, IAssemblySymbol assembly) { this.ctor = ctor ?? throw new ArgumentNullException(nameof(ctor)); this.classLoader = classLoader ?? throw new ArgumentNullException(nameof(classLoader)); @@ -1303,7 +1301,7 @@ internal CustomClassLoaderCtorCaller(ConstructorInfo ctor, object classLoader, A public object run() { - ctor.Invoke(classLoader, new object[] { assembly }); + ctor.Invoke(classLoader, [assembly.AsReflection()]); return null; } } diff --git a/src/IKVM.Runtime/RuntimeAssemblyClassLoaderFactory.cs b/src/IKVM.Runtime/RuntimeAssemblyClassLoaderFactory.cs index 5b50ef661..c0b9bf728 100644 --- a/src/IKVM.Runtime/RuntimeAssemblyClassLoaderFactory.cs +++ b/src/IKVM.Runtime/RuntimeAssemblyClassLoaderFactory.cs @@ -107,13 +107,12 @@ RuntimeAssemblyClassLoader Create(IAssemblySymbol assembly) return FromAssembly(mainAssembly); } - var baseAssembly = context.Resolver.ResolveBaseAssembly(); #if IMPORTER - if (baseAssembly != null && assembly.IsDefined(context.Resolver.ResolveRuntimeType("IKVM.Attributes.RemappedClassAttribute"), false)) + if (context.Options.Bootstrap == false && assembly.IsDefined(context.Resolver.ResolveRuntimeType("IKVM.Attributes.RemappedClassAttribute"), false)) context.ClassLoaderFactory.LoadRemappedTypes(); #endif - if (baseAssembly == assembly) + if (assembly.IsDefined(context.Resolver.ResolveRuntimeType("IKVM.Attributes.RemappedClassAttribute"), false)) { // This cast is necessary for ikvmc and a no-op for the runtime. // Note that the cast cannot fail, because ikvmc will only return a non AssemblyClassLoader diff --git a/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishContext.cs b/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishContext.cs index c884f801a..6c26b41fc 100644 --- a/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishContext.cs +++ b/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishContext.cs @@ -291,20 +291,19 @@ internal ITypeSymbol FinishImpl() #if IMPORTER ITypeSymbolBuilder tbDefaultMethods = null; #endif - bool basehasclinit = wrapper.BaseTypeWrapper != null && wrapper.BaseTypeWrapper.HasStaticInitializer; + var basehasclinit = wrapper.BaseTypeWrapper != null && wrapper.BaseTypeWrapper.HasStaticInitializer; int clinitIndex = -1; - bool hasConstructor = false; + var hasConstructor = false; for (int i = 0; i < classFile.Methods.Length; i++) { var m = classFile.Methods[i]; - var mb = (IMethodSymbolBuilder)methods[i].GetMethod(); + var mb = (IMethodBaseSymbolBuilder)methods[i].GetMethod(); if (mb == null) { // method doesn't really exist (e.g. delegate constructor or that is optimized away) if (m.IsConstructor) - { hasConstructor = true; - } + } else if (m.IsClassInitializer) { @@ -435,32 +434,27 @@ internal ITypeSymbol FinishImpl() if (field == null) { wrapper.Context.Diagnostics.GenericCompilerError($"Error: Native method field binding not found: {classFile.Name}.{param[j].Name}{fieldTypeWrapper.SigName}"); - wrapper.Context.StaticCompiler.errorCount++; continue; } if (m.IsStatic && !field.IsStatic) { wrapper.Context.Diagnostics.GenericCompilerError($"Error: Native method field binding cannot access instance field from static method: {classFile.Name}.{param[j].Name}{fieldTypeWrapper.SigName}"); - wrapper.Context.StaticCompiler.errorCount++; continue; } if (!field.IsAccessibleFrom(wrapper, wrapper, wrapper)) { wrapper.Context.Diagnostics.GenericCompilerError($"Error: Native method field binding not accessible: {classFile.Name}.{param[j].Name}{fieldTypeWrapper.SigName}"); - wrapper.Context.StaticCompiler.errorCount++; continue; } if (paramType.IsByRef && field.IsFinal) { wrapper.Context.Diagnostics.GenericCompilerError($"Error: Native method field binding cannot use ByRef for final field: {classFile.Name}.{param[j].Name}{fieldTypeWrapper.SigName}"); - wrapper.Context.StaticCompiler.errorCount++; continue; } field.Link(); if (paramType.IsByRef && field.GetField() == null) { wrapper.Context.Diagnostics.GenericCompilerError($"Error: Native method field binding cannot use ByRef on field without backing field: {classFile.Name}.{param[j].Name}{fieldTypeWrapper.SigName}"); - wrapper.Context.StaticCompiler.errorCount++; continue; } if (!field.IsStatic) @@ -509,9 +503,9 @@ internal ITypeSymbol FinishImpl() { if (m.IsVirtual && classFile.IsInterface) { - mb = (IMethodSymbolBuilder)RuntimeDefaultInterfaceJavaMethod.GetImpl(methods[i]); + mb = (IMethodBaseSymbolBuilder)RuntimeDefaultInterfaceJavaMethod.GetImpl(methods[i]); #if IMPORTER - CreateDefaultMethodInterop(ref tbDefaultMethods, mb, methods[i]); + CreateDefaultMethodInterop(ref tbDefaultMethods, (IMethodSymbolBuilder)mb, methods[i]); #endif } @@ -558,10 +552,10 @@ internal ITypeSymbol FinishImpl() if (clinitIndex != -1 || (basehasclinit && !classFile.IsInterface) || classFile.HasInitializedFields) { - IMethodSymbolBuilder cb; + IConstructorSymbolBuilder cb; if (clinitIndex != -1) { - cb = (IMethodSymbolBuilder)methods[clinitIndex].GetMethod(); + cb = (IConstructorSymbolBuilder)methods[clinitIndex].GetMethod(); } else { @@ -659,7 +653,7 @@ internal ITypeSymbol FinishImpl() for (int i = 0; i < classFile.Methods.Length; i++) { var m = classFile.Methods[i]; - var mb = (IMethodSymbolBuilder)methods[i].GetMethod(); + var mb = (IMethodBaseSymbolBuilder)methods[i].GetMethod(); if (mb == null) continue; @@ -672,7 +666,10 @@ internal ITypeSymbol FinishImpl() if (annotation != null) { annotation.Apply(wrapper.ClassLoader, mb, def); - annotation.ApplyReturnValue(wrapper.ClassLoader, mb, ref returnParameter, def); + + // constructors have no return value + if (mb is IMethodSymbolBuilder ms) + annotation.ApplyReturnValue(wrapper.ClassLoader, ms, ref returnParameter, def); } } } @@ -1001,7 +998,7 @@ private bool EmitInterlockedCompareAndSet(RuntimeJavaMethod method, string field } #endif - private void AddMethodParameterInfo(ClassFile.Method m, RuntimeJavaMethod mw, IMethodSymbolBuilder mb, out string[] parameterNames) + private void AddMethodParameterInfo(ClassFile.Method m, RuntimeJavaMethod mw, IMethodBaseSymbolBuilder mb, out string[] parameterNames) { parameterNames = null; IParameterSymbolBuilder[] parameterBuilders = null; @@ -1396,18 +1393,18 @@ void GenerateAccessStub(int id, RuntimeJavaMethod mw, bool virt, bool type1) var returnType = mw.ReturnType.TypeAsPublicSignatureType; var modoptReturnType = ArrayUtil.Concat(wrapper.GetModOpt(mw.ReturnType, true), context.Resolver.ResolveRuntimeType(typeof(IKVM.Attributes.AccessStub).FullName)); - string name; + IMethodBaseSymbolBuilder mb; if (mw.Name == StringConstants.INIT) { - name = ConstructorInfo.ConstructorName; stubattribs |= MethodAttributes.SpecialName | MethodAttributes.RTSpecialName; + mb = typeBuilder.DefineConstructor(stubattribs, CallingConventions.Standard, parameterTypes, null, modopt); } else { - name = virt ? (mw.Modifiers & Modifiers.Bridge) == 0 ? mw.Name : NamePrefix.Bridge + mw.Name : NamePrefix.NonVirtual + id; + var name = virt ? (mw.Modifiers & Modifiers.Bridge) == 0 ? mw.Name : NamePrefix.Bridge + mw.Name : NamePrefix.NonVirtual + id; + mb = typeBuilder.DefineMethod(name, stubattribs, CallingConventions.Standard, returnType, null, modoptReturnType, parameterTypes, null, modopt); } - var mb = typeBuilder.DefineMethod(name, stubattribs, CallingConventions.Standard, returnType, null, modoptReturnType, parameterTypes, null, modopt); if (virt && type1) { context.AttributeHelper.HideFromReflection(mb); @@ -1664,11 +1661,11 @@ public JniBuilder(RuntimeContext context) IMethodSymbol UnwrapLocalRefMethod => LocalRefStructType.GetMethod("UnwrapLocalRef"); - IMethodSymbol WriteLineMethod => context.Resolver.ResolveCoreType(typeof(Console).FullName).GetMethod("WriteLine", [context.Types.Object]); + IMethodSymbol WriteLineMethod => context.Resolver.ResolveType(typeof(Console).FullName).GetMethod("WriteLine", [context.Types.Object]); - IMethodSymbol MonitorEnterMethod => context.Resolver.ResolveCoreType(typeof(System.Threading.Monitor).FullName).GetMethod("Enter", [context.Types.Object]); + IMethodSymbol MonitorEnterMethod => context.Resolver.ResolveType(typeof(System.Threading.Monitor).FullName).GetMethod("Enter", [context.Types.Object]); - IMethodSymbol MonitorExitMethod => context.Resolver.ResolveCoreType(typeof(System.Threading.Monitor).FullName).GetMethod("Exit", [context.Types.Object]); + IMethodSymbol MonitorExitMethod => context.Resolver.ResolveType(typeof(System.Threading.Monitor).FullName).GetMethod("Exit", [context.Types.Object]); internal void Generate(RuntimeByteCodeJavaType.FinishContext context, CodeEmitter ilGenerator, RuntimeByteCodeJavaType wrapper, RuntimeJavaMethod mw, ITypeSymbolBuilder typeBuilder, ClassFile classFile, ClassFile.Method m, RuntimeJavaType[] args, bool thruProxy) { @@ -1899,7 +1896,7 @@ void EmitCallerIDStub(RuntimeJavaMethod mw, string[] parameterNames) } ilgen.Emit(OpCodes.Ldc_I4_1); ilgen.Emit(OpCodes.Ldc_I4_0); - ilgen.Emit(OpCodes.Newobj, context.Resolver.ResolveCoreType(typeof(StackFrame).FullName).GetConstructor(new ITypeSymbol[] { context.Types.Int32, context.Types.Boolean })); + ilgen.Emit(OpCodes.Newobj, context.Resolver.ResolveType(typeof(StackFrame).FullName).GetConstructor([context.Types.Int32, context.Types.Boolean])); var callerID = context.JavaBase.TypeOfIkvmInternalCallerID.GetMethodWrapper("create", "(Lcli.System.Diagnostics.StackFrame;)Likvm.internal.CallerID;", false); callerID.Link(); callerID.EmitCall(ilgen); @@ -2057,7 +2054,7 @@ void CompileConstructorBody(FinishContext context, CodeEmitter ilGenerator, int Compiler.Compile(context, host, wrapper, methods[methodIndex], classFile, m, ilGenerator, ref nonLeaf); ilGenerator.DoEmit(); #if IMPORTER - ilGenerator.EmitLineNumberTable((IMethodSymbolBuilder)methods[methodIndex].GetMethod()); + ilGenerator.EmitLineNumberTable((IMethodBaseSymbolBuilder)methods[methodIndex].GetMethod()); #else // IMPORTER var linenumbers = ilGenerator.GetLineNumberTable(); if (linenumbers != null) diff --git a/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.cs b/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.cs index 0f287ff2c..ed378f2a1 100644 --- a/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.cs +++ b/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.cs @@ -1853,7 +1853,7 @@ internal override void Apply(RuntimeClassLoader loader, ITypeSymbolBuilder tb, o tb.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); } - internal override void Apply(RuntimeClassLoader loader, IMethodSymbolBuilder mb, object annotation) + internal override void Apply(RuntimeClassLoader loader, IMethodBaseSymbolBuilder mb, object annotation) { mb.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); } @@ -2461,7 +2461,7 @@ internal override IMethodBaseSymbol LinkMethod(RuntimeJavaMethod mw) } var m = classFile.Methods[index]; - IMethodSymbolBuilder method; + IMethodBaseSymbolBuilder method; bool setModifiers = false; if (methods[index].HasCallerID && (m.Modifiers & Modifiers.VarArgs) != 0) @@ -2567,7 +2567,7 @@ private bool HasSerialVersionUID } } - IMethodSymbolBuilder GenerateConstructor(RuntimeJavaMethod mw) + IConstructorSymbolBuilder GenerateConstructor(RuntimeJavaMethod mw) { return mw.GetDefineMethodHelper().DefineConstructor(wrapper, typeBuilder, GetMethodAccess(mw) | MethodAttributes.HideBySig); } diff --git a/src/IKVM.Runtime/RuntimeByteCodeJavaType.cs b/src/IKVM.Runtime/RuntimeByteCodeJavaType.cs index 0375c0dfe..ea1dadac6 100644 --- a/src/IKVM.Runtime/RuntimeByteCodeJavaType.cs +++ b/src/IKVM.Runtime/RuntimeByteCodeJavaType.cs @@ -575,7 +575,7 @@ protected static void GetParameterNamesFromSig(string sig, string[] parameterNam parameterNames[i] = names[i]; } - protected static IParameterSymbolBuilder[] GetParameterBuilders(IMethodSymbolBuilder mb, int parameterCount, string[] parameterNames) + protected static IParameterSymbolBuilder[] GetParameterBuilders(IMethodBaseSymbolBuilder mb, int parameterCount, string[] parameterNames) { var parameterBuilders = new IParameterSymbolBuilder[parameterCount]; Dictionary clashes = null; @@ -909,7 +909,7 @@ internal static ITypeSymbol[] GetModOpt(RuntimeJavaTypeFactory context, RuntimeJ if (tw.IsUnloadable) { if (((RuntimeUnloadableJavaType)tw).MissingType == null) - modopt = new ITypeSymbol[] { ((RuntimeUnloadableJavaType)tw).GetCustomModifier(context) }; + modopt = [((RuntimeUnloadableJavaType)tw).GetCustomModifier(context)]; } else { @@ -920,11 +920,10 @@ internal static ITypeSymbol[] GetModOpt(RuntimeJavaTypeFactory context, RuntimeJ modopt = new ITypeSymbol[tw.ArrayRank + 1]; modopt[0] = GetModOptHelper(tw1); for (int i = 1; i < modopt.Length; i++) - { modopt[i] = tw.Context.Types.Array; - } } } + return modopt; } diff --git a/src/IKVM.Runtime/RuntimeClassLoaderFactory.cs b/src/IKVM.Runtime/RuntimeClassLoaderFactory.cs index f47f336ec..1625345a5 100644 --- a/src/IKVM.Runtime/RuntimeClassLoaderFactory.cs +++ b/src/IKVM.Runtime/RuntimeClassLoaderFactory.cs @@ -100,14 +100,14 @@ internal void SetBootstrapClassLoader(RuntimeClassLoader bootstrapClassLoader) internal void LoadRemappedTypes() { // if we're compiling the base assembly, we won't be able to resolve one - var baseAssembly = context.Resolver.ResolveBaseAssembly(); - if (baseAssembly != null && remappedTypes.Count == 0) + if (context.Options.Bootstrap == false && remappedTypes.Count == 0) { + var baseAssembly = context.Resolver.ResolveBaseAssembly(); var remapped = context.AttributeHelper.GetRemappedClasses(baseAssembly); if (remapped.Length > 0) { foreach (var r in remapped) - remappedTypes.Add(context.Resolver.ResolveType(r.RemappedType), r.Name); + remappedTypes.Add(context.Resolver.ImportType(r.RemappedType), r.Name); } else { @@ -390,9 +390,9 @@ internal RuntimeClassLoader GetAssemblyClassLoaderByName(string name) return GetGenericClassLoaderByName(name); #if NETFRAMEWORK - return context.AssemblyClassLoaderFactory.FromAssembly(context.Resolver.ResolveAssembly( Assembly.Load(name))); + return context.AssemblyClassLoaderFactory.FromAssembly(context.Resolver.ImportAssembly( Assembly.Load(name))); #else - return context.AssemblyClassLoaderFactory.FromAssembly(context.Resolver.ResolveAssembly(AssemblyLoadContext.GetLoadContext(typeof(RuntimeClassLoader).Assembly).LoadFromAssemblyName(new AssemblyName(name)))); + return context.AssemblyClassLoaderFactory.FromAssembly(context.Resolver.ImportAssembly(AssemblyLoadContext.GetLoadContext(typeof(RuntimeClassLoader).Assembly).LoadFromAssemblyName(new AssemblyName(name)))); #endif } diff --git a/src/IKVM.Runtime/RuntimeContext.cs b/src/IKVM.Runtime/RuntimeContext.cs index ef2ec783b..3568a8648 100644 --- a/src/IKVM.Runtime/RuntimeContext.cs +++ b/src/IKVM.Runtime/RuntimeContext.cs @@ -30,7 +30,6 @@ class RuntimeContext readonly RuntimeContextOptions options; readonly IDiagnosticHandler diagnostics; readonly IRuntimeSymbolResolver resolver; - readonly bool bootstrap; readonly ConcurrentDictionary singletons = new(); Types types; @@ -79,14 +78,12 @@ class RuntimeContext /// /// /// - /// /// - public RuntimeContext(RuntimeContextOptions options, IDiagnosticHandler diagnostics, IRuntimeSymbolResolver resolver, bool bootstrap, StaticCompiler staticCompiler) + public RuntimeContext(RuntimeContextOptions options, IDiagnosticHandler diagnostics, IRuntimeSymbolResolver resolver, StaticCompiler staticCompiler) { this.options = options ?? throw new ArgumentNullException(nameof(options)); this.diagnostics = diagnostics ?? throw new ArgumentNullException(nameof(diagnostics)); this.resolver = resolver ?? throw new ArgumentNullException(nameof(resolver)); - this.bootstrap = bootstrap; this.staticCompiler = staticCompiler; } @@ -98,13 +95,11 @@ public RuntimeContext(RuntimeContextOptions options, IDiagnosticHandler diagnost /// /// /// - /// - public RuntimeContext(RuntimeContextOptions options, IDiagnosticHandler diagnostics, IRuntimeSymbolResolver resolver, bool bootstrap) + public RuntimeContext(RuntimeContextOptions options, IDiagnosticHandler diagnostics, IRuntimeSymbolResolver resolver) { this.options = options ?? throw new ArgumentNullException(nameof(options)); this.diagnostics = diagnostics ?? throw new ArgumentNullException(nameof(diagnostics)); this.resolver = resolver ?? throw new ArgumentNullException(nameof(resolver)); - this.bootstrap = bootstrap; } #endif @@ -147,12 +142,6 @@ T GetOrCreateSingleton(ref T value, Func create) /// Gets the associated with this instance of the runtime. /// public IRuntimeSymbolResolver Resolver => resolver; - - /// - /// Gets whether or not the runtime is running in bootstrap mode; that is, we are compiling the Java base assembly itself. - /// - public bool Bootstrap => bootstrap; - /// /// Gets the associated with this instance of the runtime. /// @@ -213,7 +202,7 @@ T GetOrCreateSingleton(ref T value, Func create) /// Gets the associated with this instance of the runtime. /// /// - public CompilerFactory CompilerFactory => GetOrCreateSingleton(ref compilerFactory, () => new CompilerFactory(this, bootstrap)); + public CompilerFactory CompilerFactory => GetOrCreateSingleton(ref compilerFactory, () => new CompilerFactory(this, options.Bootstrap)); /// /// Gets the associated with this instance of the runtime. diff --git a/src/IKVM.Runtime/RuntimeContextOptions.cs b/src/IKVM.Runtime/RuntimeContextOptions.cs index c89914b55..159bef830 100644 --- a/src/IKVM.Runtime/RuntimeContextOptions.cs +++ b/src/IKVM.Runtime/RuntimeContextOptions.cs @@ -10,17 +10,25 @@ internal class RuntimeContextOptions internal const string DefaultDynamicAssemblySuffixAndPublicKey = "-ikvm-runtime-injected"; #endif + readonly bool bootstrap; readonly string dynamicAssemblySuffixAndPublicKey; /// /// Initializes a new instance. /// + /// /// - public RuntimeContextOptions(string dynamicAssemblySuffixAndPublicKey = null) + public RuntimeContextOptions(bool bootstrap = false, string dynamicAssemblySuffixAndPublicKey = null) { + this.bootstrap = bootstrap; this.dynamicAssemblySuffixAndPublicKey = dynamicAssemblySuffixAndPublicKey ?? DefaultDynamicAssemblySuffixAndPublicKey; } + /// + /// Gets whether or not bootstrap mode is enabled. + /// + public bool Bootstrap => bootstrap; + /// /// Gets the suffix and public key to add to dynamically generated assemblies. /// diff --git a/src/IKVM.Runtime/RuntimeJavaType.cs b/src/IKVM.Runtime/RuntimeJavaType.cs index 4908a8d3e..6fb940ce1 100644 --- a/src/IKVM.Runtime/RuntimeJavaType.cs +++ b/src/IKVM.Runtime/RuntimeJavaType.cs @@ -302,7 +302,7 @@ internal static RuntimeJavaType FromClass(java.lang.Class clazz) return FromClass(clazz); } - var symbol = JVM.Context.Resolver.ResolveType(type); + var symbol = JVM.Context.Resolver.ImportType(type); if (type == typeof(void) || type.IsPrimitive || JVM.Context.ClassLoaderFactory.IsRemappedType(symbol)) tw = JVM.Context.ManagedJavaTypeFactory.GetJavaTypeFromManagedType(symbol); else diff --git a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.RemappedJavaType.cs b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.RemappedJavaType.cs index ed369d2fe..ca2fb0d06 100644 --- a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.RemappedJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.RemappedJavaType.cs @@ -58,7 +58,7 @@ internal RemappedJavaType(RuntimeContext context, string name, ITypeSymbol type) base(context, name, type) { var attr = Context.AttributeHelper.GetRemappedType(type) ?? throw new InvalidOperationException(); - remappedType = Context.Resolver.ResolveType(attr.Type); + remappedType = Context.Resolver.ImportType(attr.Type); } internal override ITypeSymbol TypeAsTBD => remappedType; diff --git a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs index c0cda2478..cce286431 100644 --- a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs @@ -137,7 +137,7 @@ static RuntimeJavaType GetBaseTypeWrapper(RuntimeContext context, ITypeSymbol ty var attr = context.AttributeHelper.GetRemappedType(type); if (attr != null) { - if (context.Resolver.ResolveType(attr.Type) == context.Types.Object) + if (context.Resolver.ImportType(attr.Type) == context.Types.Object) return null; else return context.JavaBase.TypeOfJavaLangObject; @@ -1196,7 +1196,7 @@ internal override void Apply(RuntimeClassLoader loader, ITypeSymbolBuilder tb, o tb.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); } - internal override void Apply(RuntimeClassLoader loader, IMethodSymbolBuilder mb, object annotation) + internal override void Apply(RuntimeClassLoader loader, IMethodBaseSymbolBuilder mb, object annotation) { mb.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); } @@ -1254,7 +1254,7 @@ internal override ITypeSymbol EnumType internal override string GetSourceFileName() { - var attr = type.GetCustomAttribute(Context.Resolver.ResolveType(typeof(SourceFileAttribute))); + var attr = type.GetCustomAttribute(Context.Resolver.ImportType(typeof(SourceFileAttribute))); if (attr != null && attr.Value.ConstructorArguments.Length > 0) return (string)attr.Value.ConstructorArguments[0].Value; @@ -1264,7 +1264,7 @@ internal override string GetSourceFileName() if (IsNestedTypeAnonymousOrLocalClass(type)) return Context.ClassLoaderFactory.GetJavaTypeFromType(type.DeclaringType).GetSourceFileName(); - if (type.Module.IsDefined(Context.Resolver.ResolveType(typeof(SourceFileAttribute)), false)) + if (type.Module.IsDefined(Context.Resolver.ImportType(typeof(SourceFileAttribute)), false)) return type.Name + ".java"; return null; @@ -1272,7 +1272,7 @@ internal override string GetSourceFileName() internal override int GetSourceLineNumber(IMethodBaseSymbol mb, int ilOffset) { - var attr = type.GetCustomAttribute(Context.Resolver.ResolveType(typeof(LineNumberTableAttribute))); + var attr = type.GetCustomAttribute(Context.Resolver.ImportType(typeof(LineNumberTableAttribute))); if (attr != null && attr.Value.Constructor != null) return ((LineNumberTableAttribute)attr.Value.Constructor.AsReflection().Invoke(attr.Value.ConstructorArguments.Cast().ToArray())).GetLineNumber(ilOffset); diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.MultipleAnnotationJavaType.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.MultipleAnnotationJavaType.cs index d5b164b58..c288ba1d3 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.MultipleAnnotationJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.MultipleAnnotationJavaType.cs @@ -112,7 +112,7 @@ static object[] UnwrapArray(object annotation) return []; } - internal override void Apply(RuntimeClassLoader loader, IMethodSymbolBuilder mb, object annotation) + internal override void Apply(RuntimeClassLoader loader, IMethodBaseSymbolBuilder mb, object annotation) { Annotation annot = type.Annotation; foreach (object ann in UnwrapArray(annotation)) diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.ReturnValueAnnotationJavaType.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.ReturnValueAnnotationJavaType.cs index 81e268fd7..304a0bb33 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.ReturnValueAnnotationJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.ReturnValueAnnotationJavaType.cs @@ -66,7 +66,7 @@ internal ReturnValueAnnotationJavaType(RuntimeContext context, AttributeAnnotati #if IMPORTER || EXPORTER this.fakeType = context.FakeTypes.GetAttributeReturnValueType(declaringType.attributeType); #elif !FIRST_PASS - this.fakeType = typeof(ikvm.@internal.AttributeAnnotationReturnValue<>).MakeGenericType(declaringType.attributeType); + this.fakeType = context.Resolver.ResolveBaseType(typeof(ikvm.@internal.AttributeAnnotationReturnValue<>).FullName).MakeGenericType(declaringType.attributeType); #endif this.declaringType = declaringType; } @@ -138,7 +138,7 @@ internal override void ApplyReturnValue(RuntimeClassLoader loader, IMethodSymbol } } - internal override void Apply(RuntimeClassLoader loader, IMethodSymbolBuilder mb, object annotation) + internal override void Apply(RuntimeClassLoader loader, IMethodBaseSymbolBuilder mb, object annotation) { } diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.cs index 51ee91f3b..ae41f128c 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.cs @@ -71,7 +71,7 @@ internal AttributeAnnotationJavaType(RuntimeContext context, string name, ITypeS #if IMPORTER || EXPORTER this.fakeType = context.FakeTypes.GetAttributeType(attributeType); #elif !FIRST_PASS - this.fakeType = context.Resolver.ResolveType(typeof(ikvm.@internal.AttributeAnnotation<>)).MakeGenericType(attributeType); + this.fakeType = context.Resolver.ImportType(typeof(ikvm.@internal.AttributeAnnotation<>)).MakeGenericType(attributeType); #endif this.attributeType = attributeType; } @@ -560,7 +560,7 @@ internal override void Apply(RuntimeClassLoader loader, ITypeSymbolBuilder tb, o tb.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); } - internal override void Apply(RuntimeClassLoader loader, IMethodSymbolBuilder mb, object annotation) + internal override void Apply(RuntimeClassLoader loader, IMethodBaseSymbolBuilder mb, object annotation) { mb.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); } @@ -593,7 +593,7 @@ internal override void Apply(RuntimeClassLoader loader, IAssemblySymbolBuilder a { string str = (string)ConvertValue(loader, loader.Context.Types.String, ((object[])annotation)[3]); Version version; - if (ImportContext.TryParseVersion(str, out version)) + if (ImportContextFactory.TryParseVersion(str, out version)) { ab.__SetAssemblyVersion(version); } diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.DelegateInnerClassJavaType.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.DelegateInnerClassJavaType.cs index 7d47c9090..f3703bba6 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.DelegateInnerClassJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.DelegateInnerClassJavaType.cs @@ -53,7 +53,7 @@ internal DelegateInnerClassJavaType(RuntimeContext context, string name, ITypeSy #if IMPORTER || EXPORTER this.fakeType = context.FakeTypes.GetDelegateType(delegateType); #elif !FIRST_PASS - this.fakeType = context.Resolver.ResolveType(typeof(ikvm.@internal.DelegateInterface<>)).MakeGenericType(delegateType); + this.fakeType = context.Resolver.ImportType(typeof(ikvm.@internal.DelegateInterface<>)).MakeGenericType(delegateType); #endif var invoke = delegateType.GetMethod("Invoke"); var parameters = invoke.GetParameters(); diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.EnumEnumJavaType.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.EnumEnumJavaType.cs index a3412f98c..b9765c952 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.EnumEnumJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.EnumEnumJavaType.cs @@ -56,7 +56,7 @@ internal EnumEnumJavaType(RuntimeContext context, string name, ITypeSymbol enumT #if IMPORTER || EXPORTER this.fakeType = context.FakeTypes.GetEnumType(enumType); #elif !FIRST_PASS - this.fakeType = context.Resolver.ResolveType(typeof(ikvm.@internal.EnumEnum<>)).MakeGenericType(enumType); + this.fakeType = context.Resolver.ImportType(typeof(ikvm.@internal.EnumEnum<>)).MakeGenericType(enumType); #endif } diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.cs index a4df662c1..758e61747 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.cs @@ -541,7 +541,7 @@ protected override void LazyPublishMembers() #if !IMPORTER && !EXPORTER && !FIRST_PASS // support serializing .NET exceptions (by replacing them with a placeholder exception) - if (Context.Types.Exception.IsAssignableFrom(type) && Context.Resolver.ResolveType(typeof(java.io.Serializable.__Interface)).IsAssignableFrom(type) == false && methodsList.ContainsKey("writeReplace()Ljava.lang.Object;") == false) + if (Context.Types.Exception.IsAssignableFrom(type) && Context.Resolver.ImportType(typeof(java.io.Serializable.__Interface)).IsAssignableFrom(type) == false && methodsList.ContainsKey("writeReplace()Ljava.lang.Object;") == false) methodsList.Add("writeReplace()Ljava.lang.Object;", new ExceptionWriteReplaceJavaMethod(this)); #endif diff --git a/src/IKVM.Runtime/StubGen/StubGenerator.cs b/src/IKVM.Runtime/StubGen/StubGenerator.cs index f5a6b5fa8..51d7f4833 100644 --- a/src/IKVM.Runtime/StubGen/StubGenerator.cs +++ b/src/IKVM.Runtime/StubGen/StubGenerator.cs @@ -329,7 +329,7 @@ void AddExceptionsAttribute(ClassFileBuilder builder, RuntimeJavaType type, Runt if (throws.types != null) foreach (var ex in throws.types) - e.Class(builder.Constants.GetOrAddClass(context.ClassLoaderFactory.GetJavaTypeFromType(context.Resolver.ResolveType(ex)).Name.Replace('.', '/'))); + e.Class(builder.Constants.GetOrAddClass(context.ClassLoaderFactory.GetJavaTypeFromType(context.Resolver.ImportType(ex)).Name.Replace('.', '/'))); }); } } diff --git a/src/IKVM.Runtime/atomic.cs b/src/IKVM.Runtime/atomic.cs index 3467e3992..42f2af31c 100644 --- a/src/IKVM.Runtime/atomic.cs +++ b/src/IKVM.Runtime/atomic.cs @@ -143,7 +143,7 @@ public InterlockedMethods(RuntimeContext context) { this.context = context; - var type = context.Resolver.ResolveCoreType(typeof(System.Threading.Interlocked).FullName); + var type = context.Resolver.ResolveType(typeof(System.Threading.Interlocked).FullName); AddInt32 = type.GetMethod("Add", [context.Types.Int32.MakeByRefType(), context.Types.Int32]); CompareExchangeInt32 = type.GetMethod("CompareExchange", [context.Types.Int32.MakeByRefType(), context.Types.Int32, context.Types.Int32]); CompareExchangeInt64 = type.GetMethod("CompareExchange", [context.Types.Int64.MakeByRefType(), context.Types.Int64, context.Types.Int64]); diff --git a/src/IKVM.Tools.Importer/AssemblyResolver.cs b/src/IKVM.Tools.Exporter/AssemblyResolver.cs similarity index 98% rename from src/IKVM.Tools.Importer/AssemblyResolver.cs rename to src/IKVM.Tools.Exporter/AssemblyResolver.cs index 2608e2c37..5c5f58234 100644 --- a/src/IKVM.Tools.Importer/AssemblyResolver.cs +++ b/src/IKVM.Tools.Exporter/AssemblyResolver.cs @@ -28,15 +28,15 @@ Jeroen Frijters using IKVM.Reflection; using IKVM.Runtime; -namespace IKVM.Tools.Importer +namespace IKVM.Tools.Exporter { sealed class AssemblyResolver { - readonly List libpath = new List(); - Universe universe; - Version coreLibVersion; + private readonly List libpath = new List(); + private Universe universe; + private Version coreLibVersion; internal enum WarningId { diff --git a/src/IKVM.Tools.Exporter/ExportImpl.cs b/src/IKVM.Tools.Exporter/ExportImpl.cs index 149aaf055..b7e4b327b 100644 --- a/src/IKVM.Tools.Exporter/ExportImpl.cs +++ b/src/IKVM.Tools.Exporter/ExportImpl.cs @@ -11,7 +11,6 @@ using IKVM.CoreLib.Symbols.IkvmReflection; using IKVM.Reflection; using IKVM.Runtime; -using IKVM.Tools.Importer; using Type = IKVM.Reflection.Type; @@ -147,7 +146,7 @@ public int Execute() } compiler = new StaticCompiler(universe, assemblyResolver, runtimeAssembly); - context = new RuntimeContext(new RuntimeContextOptions(), diagnostics, new ManagedTypeResolver(symbols, compiler, null), true, compiler); + context = new RuntimeContext(new RuntimeContextOptions(true), diagnostics, new ManagedTypeResolver(symbols, universe, runtimeAssembly, null), compiler); context.ClassLoaderFactory.SetBootstrapClassLoader(new RuntimeBootstrapClassLoader(context)); } else @@ -174,10 +173,10 @@ public int Execute() } compiler = new StaticCompiler(universe, assemblyResolver, runtimeAssembly); - context = new RuntimeContext(new RuntimeContextOptions(), diagnostics, new ManagedTypeResolver(symbols, compiler, baseAssembly), false, compiler); + context = new RuntimeContext(new RuntimeContextOptions(), diagnostics, new ManagedTypeResolver(symbols, universe, runtimeAssembly, baseAssembly), compiler); } - if (context.AttributeHelper.IsJavaModule(context.Resolver.ResolveModule(assembly.ManifestModule))) + if (context.AttributeHelper.IsJavaModule(context.Resolver.ImportModule(assembly.ManifestModule))) { diagnostics.ExportingImportsNotSupported(); return 1; @@ -369,7 +368,7 @@ bool ExportNamespace(IList namespaces, ITypeSymbol type) int ProcessTypes(RuntimeContext context, Type[] types) { int rc = 0; - foreach (var t in types.Select(context.Resolver.ResolveType)) + foreach (var t in types.Select(context.Resolver.ImportType)) { if ((t.IsPublic || options.IncludeNonPublicTypes) && ExportNamespace(options.Namespaces, t) && !t.IsGenericTypeDefinition && !context.AttributeHelper.IsHideFromJava(t) && (!t.IsGenericType || !context.AttributeHelper.IsJavaModule(t.Module))) { diff --git a/src/IKVM.Tools.Exporter/IKVM.Tools.Exporter.csproj b/src/IKVM.Tools.Exporter/IKVM.Tools.Exporter.csproj index d3db518a9..af1d639c7 100644 --- a/src/IKVM.Tools.Exporter/IKVM.Tools.Exporter.csproj +++ b/src/IKVM.Tools.Exporter/IKVM.Tools.Exporter.csproj @@ -97,9 +97,5 @@ - - - - diff --git a/src/IKVM.Tools.Exporter/ManagedTypeResolver.cs b/src/IKVM.Tools.Exporter/ManagedTypeResolver.cs index 35d106fc8..55d36ccea 100644 --- a/src/IKVM.Tools.Exporter/ManagedTypeResolver.cs +++ b/src/IKVM.Tools.Exporter/ManagedTypeResolver.cs @@ -17,7 +17,8 @@ namespace IKVM.Tools.Exporter class ManagedTypeResolver : IRuntimeSymbolResolver { - readonly StaticCompiler compiler; + readonly Universe universe; + readonly Assembly runtimeAssembly; readonly Assembly baseAssembly; readonly IkvmReflectionSymbolContext symbols; @@ -26,10 +27,11 @@ class ManagedTypeResolver : IRuntimeSymbolResolver /// /// /// - public ManagedTypeResolver(IkvmReflectionSymbolContext symbols, StaticCompiler compiler, Assembly baseAssembly) + public ManagedTypeResolver(IkvmReflectionSymbolContext symbols, Universe universe, Assembly runtimeAssembly, Assembly baseAssembly) { this.symbols = symbols ?? throw new ArgumentNullException(nameof(symbols)); - this.compiler = compiler ?? throw new ArgumentNullException(nameof(compiler)); + this.universe = universe ?? throw new ArgumentNullException(nameof(universe)); + this.runtimeAssembly = runtimeAssembly ?? throw new ArgumentNullException(nameof(runtimeAssembly)); this.baseAssembly = baseAssembly; } @@ -37,103 +39,123 @@ public ManagedTypeResolver(IkvmReflectionSymbolContext symbols, StaticCompiler c public ISymbolContext Symbols => symbols; /// - public IAssemblySymbol? ResolveBaseAssembly() + public IAssemblySymbol ResolveCoreAssembly() { - return ResolveAssembly(baseAssembly); + return ImportAssembly(universe.CoreLib); } /// - public IAssemblySymbol? ResolveAssembly(string assemblyName) + public ITypeSymbol ResolveCoreType(string typeName) { - return ResolveAssembly(compiler.Load(assemblyName)); + return ResolveCoreAssembly().GetType(typeName) ?? throw new InvalidOperationException(); } /// - public ITypeSymbol? ResolveCoreType(string typeName) + public IAssemblySymbol ResolveRuntimeAssembly() { - foreach (var assembly in compiler.Universe.GetAssemblies()) - if (assembly.GetType(typeName) is Type t) - return ResolveType(t); + return ImportAssembly(runtimeAssembly); + } + + /// + public ITypeSymbol ResolveRuntimeType(string typeName) + { + return ResolveRuntimeAssembly().GetType(typeName) ?? throw new InvalidOperationException(); + } - return null; + /// + public IAssemblySymbol ResolveBaseAssembly() + { + return ImportAssembly(baseAssembly); + } + + /// + public ITypeSymbol ResolveBaseType(string typeName) + { + throw new NotImplementedException(); + } + + /// + public ITypeSymbol? ResolveType(string typeName) + { + throw new NotImplementedException(); } /// - public ITypeSymbol? ResolveRuntimeType(string typeName) + public IAssemblySymbol ResolveAssembly(string assemblyName) { - return ResolveType(compiler.GetRuntimeType(typeName)); + return ImportAssembly(universe.Load(assemblyName)); } /// - public IAssemblySymbol? ResolveAssembly(Assembly? assembly) + public IAssemblySymbol ImportAssembly(Assembly assembly) { - return assembly != null ? symbols.GetOrCreateAssemblySymbol(assembly) : null; + return symbols.GetOrCreateAssemblySymbol(assembly); } /// - public IAssemblySymbolBuilder? ResolveAssembly(AssemblyBuilder? assembly) + public IAssemblySymbolBuilder ImportAssembly(AssemblyBuilder assembly) { - return assembly != null ? symbols.GetOrCreateAssemblySymbol(assembly) : null; + return symbols.GetOrCreateAssemblySymbol(assembly); } /// - public IModuleSymbol? ResolveModule(Module? module) + public IModuleSymbol ImportModule(Module module) { - return module != null ? symbols.GetOrCreateModuleSymbol(module) : null; + return symbols.GetOrCreateModuleSymbol(module); } /// - public IModuleSymbolBuilder? ResolveModule(ModuleBuilder? module) + public IModuleSymbolBuilder ImportModule(ModuleBuilder module) { - return module != null ? symbols.GetOrCreateModuleSymbol(module) : null; + return symbols.GetOrCreateModuleSymbol(module); } /// - public ITypeSymbol? ResolveType(Type? type) + public ITypeSymbol ImportType(Type type) { - return type != null ? symbols.GetOrCreateTypeSymbol(type) : null; + return symbols.GetOrCreateTypeSymbol(type) ; } /// - public ITypeSymbolBuilder? ResolveType(TypeBuilder? type) + public ITypeSymbolBuilder ResolveType(TypeBuilder type) { - return type != null ? symbols.GetOrCreateTypeSymbol(type) : null; + return symbols.GetOrCreateTypeSymbol(type); } /// - public IMemberSymbol? ResolveMember(MemberInfo? module) + public IMemberSymbol ImportMember(MemberInfo module) { - return module != null ? symbols.GetOrCreateMemberSymbol(module) : null; + return symbols.GetOrCreateMemberSymbol(module); } /// - public IMethodBaseSymbol? ResolveMethodBase(MethodBase? method) + public IMethodBaseSymbol ImportMethodBase(MethodBase method) { - return method != null ? symbols.GetOrCreateMethodBaseSymbol(method) : null; + return symbols.GetOrCreateMethodBaseSymbol(method); } /// - public IConstructorSymbol? ResolveConstructor(ConstructorInfo? ctor) + public IConstructorSymbol ImportConstructor(ConstructorInfo ctor) { - return ctor != null ? symbols.GetOrCreateConstructorSymbol(ctor) : null; + return symbols.GetOrCreateConstructorSymbol(ctor); } /// - public IConstructorSymbolBuilder? ResolveConstructor(ConstructorBuilder? ctor) + public IConstructorSymbolBuilder ResolveConstructor(ConstructorBuilder ctor) { - return ctor != null ? symbols.GetOrCreateConstructorSymbol(ctor) : null; + return symbols.GetOrCreateConstructorSymbol(ctor); } /// - public IMethodSymbol? ResolveMethod(MethodInfo? method) + public IMethodSymbol ImportMethod(MethodInfo method) { - return method != null ? symbols.GetOrCreateMethodSymbol(method) : null; + return symbols.GetOrCreateMethodSymbol(method); } /// - public IMethodSymbolBuilder? ResolveMethod(MethodBuilder? method) + public IMethodSymbolBuilder ResolveMethod(MethodBuilder method) { - return method != null ? symbols.GetOrCreateMethodSymbol(method) : null; + return symbols.GetOrCreateMethodSymbol(method); } } diff --git a/src/IKVM.Tools.Exporter/StaticCompiler.cs b/src/IKVM.Tools.Exporter/StaticCompiler.cs index 57f27fbfd..59c8c0605 100644 --- a/src/IKVM.Tools.Exporter/StaticCompiler.cs +++ b/src/IKVM.Tools.Exporter/StaticCompiler.cs @@ -24,7 +24,6 @@ Jeroen Frijters using System; using IKVM.Reflection; -using IKVM.Tools.Importer; using Type = IKVM.Reflection.Type; diff --git a/src/IKVM.Tools.Importer/ExecutionContext.NetFramework.cs b/src/IKVM.Tools.Importer/ExecutionContext.NetFramework.cs index 74d2cb56f..72496b06f 100644 --- a/src/IKVM.Tools.Importer/ExecutionContext.NetFramework.cs +++ b/src/IKVM.Tools.Importer/ExecutionContext.NetFramework.cs @@ -11,7 +11,7 @@ partial class ExecutionContext { /// - /// Encapsulates a in a remote . + /// Encapsulates a in a remote . /// class ExecutionContextDispatcher : MarshalByRefObject { diff --git a/src/IKVM.Tools.Importer/FakeTypes.cs b/src/IKVM.Tools.Importer/FakeTypes.cs index 677d65f0a..6ae6aa638 100644 --- a/src/IKVM.Tools.Importer/FakeTypes.cs +++ b/src/IKVM.Tools.Importer/FakeTypes.cs @@ -103,7 +103,6 @@ internal void Finish(RuntimeClassLoader loader) ilgen.Emit(System.Reflection.Emit.OpCodes.Ret); ilgen.DoEmit(); tb.Complete(); - genericEnumEnumType = tb; } @@ -112,8 +111,6 @@ void CreateEnumEnum(IModuleSymbolBuilder modb, RuntimeClassLoader loader) var tb = modb.DefineType(RuntimeManagedJavaType.GenericEnumEnumTypeName, TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.Public); var gtpb = tb.DefineGenericParameters("T")[0]; gtpb.SetBaseTypeConstraint(context.Types.Enum); - tb.Complete(); - genericEnumEnumType = tb; } @@ -122,7 +119,6 @@ ITypeSymbol CreateAnnotationType(IModuleSymbolBuilder modb, string name) var tb = modb.DefineType(name, TypeAttributes.Interface | TypeAttributes.Abstract | TypeAttributes.Public); tb.DefineGenericParameters("T")[0].SetBaseTypeConstraint(context.Types.Attribute); tb.Complete(); - return tb; } diff --git a/src/IKVM.Tools.Importer/ImportAssemblyResolver.cs b/src/IKVM.Tools.Importer/ImportAssemblyResolver.cs new file mode 100644 index 000000000..4814a786d --- /dev/null +++ b/src/IKVM.Tools.Importer/ImportAssemblyResolver.cs @@ -0,0 +1,359 @@ +/* + Copyright (C) 2010-2013 Jeroen Frijters + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jeroen Frijters + jeroen@frijters.net + +*/ +using System; +using System.Collections.Generic; +using System.IO; + +using IKVM.CoreLib.Diagnostics; +using IKVM.Reflection; + +namespace IKVM.Tools.Importer +{ + + /// + /// Resolves assemblies from the universe of types. + /// + class ImportAssemblyResolver + { + + readonly Universe universe; + readonly ImportOptions options; + readonly IDiagnosticHandler diagnostics; + readonly List libpaths = new List(); + readonly Version coreLibVersion; + + /// + /// Initializes a new instance. + /// + /// + /// + public ImportAssemblyResolver(Universe universe, ImportOptions options, IDiagnosticHandler diagnostics) + { + this.universe = universe ?? throw new ArgumentNullException(nameof(universe)); + this.options = options ?? throw new ArgumentNullException(nameof(options)); + this.diagnostics = diagnostics ?? throw new ArgumentNullException(nameof(diagnostics)); + + // like the C# compiler, the references are loaded from: + // current directory, CLR directory, -lib: option, %LIB% environment + // (note that, unlike the C# compiler, we don't add the CLR directory if -nostdlib has been specified) + libpaths.Add(Environment.CurrentDirectory); + + // add the runtime directory + if (options.NoStdLib == false) + libpaths.Add(System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory()); + + // add user libraries + foreach (var directory in options.Libraries) + AddLibraryPaths(directory.FullName, true); + + // add LIB environmental variable + AddLibraryPaths(Environment.GetEnvironmentVariable("LIB") ?? "", false); + + // either load the corelib from the references, or from what already exists + if (options.NoStdLib) + coreLibVersion = LoadCoreLib(options.References).GetName().Version; + else + coreLibVersion = universe.Load(universe.CoreLibName).GetName().Version; + } + + /// + /// Gets the universe of types. + /// + public Universe Universe => universe; + + /// + /// Loads the assembly at the specified path. + /// + /// + /// + /// + internal Assembly LoadFile(string path) + { + string ex = null; + + try + { + using (var module = universe.OpenRawModule(path)) + { + if (coreLibVersion != null) + { + // to avoid problems (i.e. weird exceptions), we don't allow assemblies to load that reference a newer version of the corelib + foreach (var asmref in module.GetReferencedAssemblies()) + if (asmref.Name == universe.CoreLibName && asmref.Version > coreLibVersion) + throw new FatalCompilerErrorException(DiagnosticEvent.CoreAssemblyVersionMismatch(asmref.Name, universe.CoreLibName)); + } + + var asm = universe.LoadAssembly(module); + if (asm.Location != module.Location && CanonicalizePath(asm.Location) != CanonicalizePath(module.Location)) + diagnostics.AssemblyLocationIgnored(path, asm.Location, asm.FullName); + + return asm; + } + } + catch (IOException x) + { + ex = x.Message; + } + catch (UnauthorizedAccessException x) + { + ex = x.Message; + } + catch (IKVM.Reflection.BadImageFormatException x) + { + ex = x.Message; + } + + // TODO + Console.Error.WriteLine("Error: unable to load assembly '{0}'" + Environment.NewLine + " ({1})", path, ex); + Environment.Exit(1); + return null; + } + + static string CanonicalizePath(string path) + { + try + { + var fi = new System.IO.FileInfo(path); + if (fi.DirectoryName == null) + return path.Length > 1 && path[1] == ':' ? path.ToUpper() : path; + + var dir = CanonicalizePath(fi.DirectoryName); + var name = fi.Name; + try + { + var arr = System.IO.Directory.GetFileSystemEntries(dir, name); + if (arr.Length == 1) + name = arr[0]; + } + catch (System.UnauthorizedAccessException) + { + + } + catch (System.IO.IOException) + { + + } + + return System.IO.Path.Combine(dir, name); + } + catch (System.UnauthorizedAccessException) + { + + } + catch (System.IO.IOException) + { + + } + catch (System.Security.SecurityException) + { + + } + catch (System.NotSupportedException) + { + + } + + return path; + } + + internal Assembly LoadWithPartialName(string name) + { + foreach (string path in FindAssemblyPath(name + ".dll")) + return LoadFile(path); + + return null; + } + + internal bool ResolveReference(Dictionary cache, List references, string reference) + { + var files = Array.Empty(); + + try + { + var path = Path.GetDirectoryName(reference); + files = Directory.GetFiles(path == "" ? "." : path, Path.GetFileName(reference)); + } + catch (ArgumentException) + { + + } + catch (IOException) + { + + } + + if (files.Length == 0) + { + cache.TryGetValue(reference, out var asm); + + if (asm == null) + { + foreach (var found in FindAssemblyPath(reference)) + { + asm = LoadFile(found); + cache.Add(reference, asm); + break; + } + } + + if (asm == null) + return false; + + references.Add(asm); + } + else + { + foreach (string file in files) + { + if (!cache.TryGetValue(file, out var asm)) + asm = LoadFile(file); + + references.Add(asm); + } + } + + return true; + } + + /// + /// Handles the event. + /// + /// + /// + /// + public Assembly AssemblyResolve(object sender, IKVM.Reflection.ResolveEventArgs args) + { + var name = new AssemblyName(args.Name); + + foreach (var asm in universe.GetAssemblies()) + if (Match(asm.GetName(), name)) + return asm; + + if (args.RequestingAssembly != null) + return universe.CreateMissingAssembly(args.Name); + + return null; + } + + /// + /// Returs true if the two assembly names match. + /// + /// + /// + /// + bool Match(AssemblyName assemblyDef, AssemblyName assemblyRef) + { + return assemblyRef.Name == assemblyDef.Name; + } + + /// + /// Adds the library paths from the path separated string formatted string. + /// + /// + /// + void AddLibraryPaths(string env, bool option) + { + foreach (var directory in env.Split(Path.PathSeparator)) + { + if (Directory.Exists(directory)) + { + libpaths.Add(directory); + } + else if (directory != "") + { + if (option) + diagnostics.InvalidDirectoryInLibOptionPath(directory); + else + diagnostics.InvalidDirectoryInLibEnvironmentPath(directory); + } + } + } + + /// + /// Search for the CoreLib from the reference assembly set. + /// + /// + /// + Assembly LoadCoreLib(IList references) + { + // try to locate core lib from direct references + if (references != null) + { + foreach (var reference in references) + { + try + { + if (AssemblyName.GetAssemblyName(reference).Name == universe.CoreLibName) + return LoadFile(reference); + } + catch + { + + } + } + } + + // try to locate corelib from library paths + foreach (var coreLib in FindAssemblyPath(universe.CoreLibName + ".dll")) + return LoadFile(coreLib); + + Console.Error.WriteLine($"Error: unable to find '{universe.CoreLibName}.dll'."); + Environment.Exit(1); + return null; + } + + /// + /// Returns the assembly at the path, or the assemblies within the path. + /// + /// + /// + IEnumerable FindAssemblyPath(string path) + { + if (Path.IsPathRooted(path)) + { + if (File.Exists(path)) + yield return path; + } + else + { + foreach (var libpath in libpaths) + { + var p = Path.Combine(libpath, path); + if (File.Exists(p)) + yield return p; + + // for legacy compat, we try again after appending .dll + p = Path.Combine(libpath, p + ".dll"); + if (File.Exists(p)) + { + diagnostics.LegacySearchRule(p); + yield return p; + } + } + } + } + + } + +} diff --git a/src/IKVM.Tools.Importer/ImportClassLoader.cs b/src/IKVM.Tools.Importer/ImportClassLoader.cs index ffcb94172..08d4327fb 100644 --- a/src/IKVM.Tools.Importer/ImportClassLoader.cs +++ b/src/IKVM.Tools.Importer/ImportClassLoader.cs @@ -41,8 +41,6 @@ Jeroen Frijters using IKVM.Reflection.Emit; using IKVM.Runtime; -using Type = IKVM.Reflection.Type; - namespace IKVM.Tools.Importer { @@ -54,7 +52,9 @@ sealed class ImportClassLoader : RuntimeClassLoader const string DEFAULT_RUNTIME_ARGS_PREFIX = "-J"; + readonly StaticCompiler compiler; readonly IDiagnosticHandler diagnostics; + Dictionary classes; Dictionary remapped = new Dictionary(); string assemblyName; @@ -63,8 +63,7 @@ sealed class ImportClassLoader : RuntimeClassLoader bool targetIsModule; IAssemblySymbolBuilder assemblyBuilder; MapXml.Attribute[] assemblyAttributes; - ImportState state; - private readonly StaticCompiler compiler; + ImportContext state; RuntimeAssemblyClassLoader[] referencedAssemblies; Dictionary nameMappings = new Dictionary(); Packages packages; @@ -98,7 +97,7 @@ sealed class ImportClassLoader : RuntimeClassLoader /// /// /// - public ImportClassLoader(RuntimeContext context, StaticCompiler compiler, IDiagnosticHandler diagnostics, RuntimeAssemblyClassLoader[] referencedAssemblies, ImportState options, FileInfo assemblyPath, bool targetIsModule, string assemblyName, Dictionary classes) : + public ImportClassLoader(RuntimeContext context, StaticCompiler compiler, IDiagnosticHandler diagnostics, RuntimeAssemblyClassLoader[] referencedAssemblies, ImportContext options, FileInfo assemblyPath, bool targetIsModule, string assemblyName, Dictionary classes) : base(context, options.codegenoptions, null) { this.compiler = compiler ?? throw new ArgumentNullException(nameof(compiler)); @@ -136,7 +135,7 @@ internal void AddReference(ImportClassLoader ccl) peerReferences.Add(ccl); } - internal System.Reflection.AssemblyName GetAssemblyName() + internal AssemblyNameInfo GetAssemblyName() { return assemblyBuilder.GetName(); } @@ -166,7 +165,7 @@ internal IModuleSymbolBuilder CreateModuleBuilder() name.Version = state.version; // define a dynamic assembly and module - assemblyBuilder = Context.Resolver.ResolveAssembly(Context.StaticCompiler.Universe.DefineDynamicAssembly(name, AssemblyBuilderAccess.ReflectionOnly, assemblyDir)); + assemblyBuilder = Context.Resolver.ImportAssembly(Context.StaticCompiler.Universe.DefineDynamicAssembly(name, AssemblyBuilderAccess.ReflectionOnly, assemblyDir)); var moduleBuilder = assemblyBuilder.DefineModule(assemblyName, assemblyFile, EmitSymbols); // if configured to emit stack trace info set source file @@ -483,25 +482,24 @@ internal override bool InternalsVisibleToImpl(RuntimeJavaType wrapper, RuntimeJa return false; } - private void AddInternalsVisibleToAttribute(ImportClassLoader ccl) + void AddInternalsVisibleToAttribute(ImportClassLoader ccl) { internalsVisibleTo.Add(ccl); var asm = ccl.assemblyBuilder; var asmName = asm.GetName(); var name = asmName.Name; - var pubkey = asmName.GetPublicKey(); + var pubkey = asmName.PublicKeyOrToken; - if (pubkey == null && asmName.KeyPair != null) - pubkey = asmName.KeyPair.PublicKey; + if (pubkey.IsEmpty && asmName.PublicKeyOrToken.IsEmpty == false) + pubkey = asmName.PublicKeyOrToken; if (pubkey != null && pubkey.Length != 0) { var sb = new StringBuilder(name); sb.Append(", PublicKey="); foreach (byte b in pubkey) - { sb.AppendFormat("{0:X2}", b); - } + name = sb.ToString(); } @@ -904,7 +902,7 @@ internal RemapperTypeWrapper(RuntimeContext context, ImportClassLoader classLoad this.baseTypeWrapper = GetBaseWrapper(context, c); classDef = c; bool baseIsSealed = false; - shadowType = context.Resolver.ResolveType(context.StaticCompiler.Universe.GetType(c.Shadows, true)); + shadowType = context.Resolver.ImportType(context.StaticCompiler.Universe.GetType(c.Shadows, true)); classLoader.SetRemappedType(shadowType, this); var baseType = shadowType; ITypeSymbol baseInterface = null; @@ -1064,8 +1062,8 @@ internal RemappedMethodBaseWrapper(RemapperTypeWrapper typeWrapper, string name, sealed class RemappedConstructorWrapper : RemappedMethodBaseWrapper { - private IKVM.Tools.Importer.MapXml.Constructor m; - private IMethodSymbolBuilder mbHelper; + IKVM.Tools.Importer.MapXml.Constructor m; + IMethodSymbolBuilder mbHelper; internal RemappedConstructorWrapper(RemapperTypeWrapper typeWrapper, IKVM.Tools.Importer.MapXml.Constructor m) : base(typeWrapper, "", m.Sig, (Modifiers)m.Modifiers) @@ -1764,7 +1762,7 @@ private void EmitRedirect(ITypeSymbol baseType, CodeEmitter ilgen) // type specified, or class missing, assume loading .NET type if (m.Redirect.Type != null || m.Redirect.Class == null) { - var type = m.Redirect.Type != null ? DeclaringType.Context.Resolver.ResolveType(DeclaringType.Context.StaticCompiler.Universe.GetType(m.Redirect.Type, true)) : baseType; + var type = m.Redirect.Type != null ? DeclaringType.Context.Resolver.ImportType(DeclaringType.Context.StaticCompiler.Universe.GetType(m.Redirect.Type, true)) : baseType; var redirParamTypes = classLoader.ArgTypeListFromSig(redirSig); var mi = type.GetMethod(m.Redirect.Name, redirParamTypes) ?? throw new InvalidOperationException(); ilgen.Emit(System.Reflection.Emit.OpCodes.Call, mi); @@ -2201,9 +2199,7 @@ internal void EmitRemappedTypes() if (c.Shadows != null) { if (classes.ContainsKey(c.Name)) - { Diagnostics.DuplicateClassName(c.Name); - } remapped.Add(c.Name, new RemapperTypeWrapper(Context, this, c, map)); hasRemappedTypes = true; @@ -2213,13 +2209,10 @@ internal void EmitRemappedTypes() if (hasRemappedTypes) { SetupGhosts(map); + foreach (IKVM.Tools.Importer.MapXml.Class c in map.Assembly.Classes) - { if (c.Shadows != null) - { remapped[c.Name].LoadInterfaces(c); - } - } } } } @@ -2485,7 +2478,7 @@ void SetupGhosts(MapXml.Root map) AddGhost("java.lang.Cloneable", array); } - private void AddGhost(string interfaceName, RuntimeJavaType implementer) + void AddGhost(string interfaceName, RuntimeJavaType implementer) { if (!ghosts.TryGetValue(interfaceName, out var list)) { @@ -2520,53 +2513,49 @@ internal void FinishRemappedTypes() private static bool IsSigned(IAssemblySymbol asm) { - byte[] key = asm.GetName().GetPublicKey(); - return key != null && key.Length != 0; + return asm.GetName().PublicKeyOrToken.IsEmpty == false; } - internal static int Compile(ImportContext importer, RuntimeContext context, StaticCompiler compiler, IDiagnosticHandler diagnostics, string runtimeAssembly, List optionsList) + /// + /// Initiates a compilation of the specified imports. + /// + /// + /// + /// + /// + /// + internal static int Compile(RuntimeContext context, StaticCompiler compiler, IDiagnosticHandler diagnostics, List imports) { - try - { - compiler.runtimeAssembly = compiler.LoadFile(runtimeAssembly ?? Path.Combine(Path.GetDirectoryName(typeof(ImportClassLoader).Assembly.Location), "IKVM.Runtime.dll")); - } - catch (FileNotFoundException) - { - // runtime assembly is required - if (compiler.runtimeAssembly == null) - throw new FatalCompilerErrorException(DiagnosticEvent.RuntimeNotFound()); - - // some unknown error - throw new FatalCompilerErrorException(DiagnosticEvent.FileNotFound(compiler.runtimeAssembly.FullName)); - } - - diagnostics.GenericCompilerInfo($"Loaded runtime assembly: {compiler.runtimeAssembly.FullName}"); - var loaders = new List(); - foreach (var options in optionsList) + + // create class loaders for each import + foreach (var import in imports) { - int rc = CreateCompiler(context, compiler, diagnostics, options, out var loader); + int rc = CreateCompiler(context, compiler, diagnostics, import, out var loader); if (rc != 0) return rc; loaders.Add(loader); - options.sharedclassloader?.Add(loader); + import.sharedclassloader?.Add(loader); } + // add a reference between all of the loaders. foreach (var loader1 in loaders) foreach (var loader2 in loaders) if (loader1 != loader2 && (loader1.state.crossReferenceAllPeers || (loader1.state.peerReferences != null && Array.IndexOf(loader1.state.peerReferences, loader2.state.assembly) != -1))) loader1.AddReference(loader2); + // first compilation pass foreach (var loader in loaders) loader.CompilePass0(); var mainAssemblyTypes = new Dictionary(); + foreach (var loader in loaders) { if (loader.state.sharedclassloader != null) { - if (!mainAssemblyTypes.TryGetValue(loader.state.sharedclassloader[0], out var mainAssemblyType)) + if (mainAssemblyTypes.TryGetValue(loader.state.sharedclassloader[0], out var mainAssemblyType) == false) { var tb = loader.state.sharedclassloader[0].GetTypeWrapperFactory().ModuleBuilder.DefineType("__", System.Reflection.TypeAttributes.NotPublic | System.Reflection.TypeAttributes.Abstract | System.Reflection.TypeAttributes.SpecialName); loader.Context.AttributeHelper.HideFromJava(tb); @@ -2575,21 +2564,18 @@ internal static int Compile(ImportContext importer, RuntimeContext context, Stat mainAssemblyType = tb; mainAssemblyTypes.Add(loader.state.sharedclassloader[0], mainAssemblyType); } + if (loader.state.sharedclassloader[0] != loader) - { ((IAssemblySymbolBuilder)loader.GetTypeWrapperFactory().ModuleBuilder.Assembly).AddTypeForwarder(mainAssemblyType); - } } loader.CompilePass1(); } foreach (var loader in loaders) - { loader.CompilePass2(); - } - if (context.Bootstrap) + if (context.Options.Bootstrap) foreach (var loader in loaders) loader.EmitRemappedTypes2ndPass(); @@ -2605,48 +2591,47 @@ internal static int Compile(ImportContext importer, RuntimeContext context, Stat foreach (var loader in loaders) loader.PrepareSave(); - if (compiler.errorCount > 0) - return 1; + //if (compiler.errorCount > 0) + // return 1; - foreach (ImportClassLoader loader in loaders) + foreach (var loader in loaders) loader.Save(); - return compiler.errorCount == 0 ? 0 : 1; + return 1; } - static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, IDiagnosticHandler diagnostics, ImportState options, out ImportClassLoader loader) + static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, IDiagnosticHandler diagnostics, ImportContext import, out ImportClassLoader loader) { - diagnostics.GenericCompilerInfo($"JVM.Compile path: {options.path}, assembly: {options.assembly}"); + diagnostics.GenericCompilerInfo($"JVM.Compile path: {import.path}, assembly: {import.assembly}"); + + // locate specified runtime assembly + var runtimeAssembly = context.Resolver.ResolveRuntimeAssembly(); + var allReferencesAreStrongNamed = IsSigned(runtimeAssembly); - var runtimeAssemblyName = compiler.runtimeAssembly.GetName(); - bool allReferencesAreStrongNamed = IsSigned(compiler.runtimeAssembly); - List references = new List(); - foreach (var reference in options.references ?? []) + var references = new List(); + + foreach (var reference in import.references ?? []) { + // check that reference is signed references.Add(reference); - allReferencesAreStrongNamed &= IsSigned(context.Resolver.ResolveAssembly(reference)); + allReferencesAreStrongNamed &= IsSigned(reference); diagnostics.GenericCompilerInfo($"Loaded reference assembly: {reference.FullName}"); - // if it's an IKVM compiled assembly, make sure that it was compiled - // against same version of the runtime - foreach (AssemblyName asmref in reference.GetReferencedAssemblies()) + // if it's an IKVM compiled assembly, make sure that it was compiled against same version of the runtime + foreach (var asmref in reference.GetReferencedAssemblies()) { - if (asmref.Name == runtimeAssemblyName.Name) + if (asmref.Name == runtimeAssembly.GetName().Name) { - if (IsSigned(compiler.runtimeAssembly)) + if (IsSigned(runtimeAssembly)) { // TODO we really should support binding redirects here to allow different revisions to be mixed - if (asmref.FullName != runtimeAssemblyName.FullName) - { - throw new FatalCompilerErrorException(DiagnosticEvent.RuntimeMismatch(reference.Location, runtimeAssemblyName.FullName, asmref.FullName)); - } + if (asmref.FullName != runtimeAssembly.FullName) + throw new FatalCompilerErrorException(DiagnosticEvent.RuntimeMismatch(reference.Location, runtimeAssembly.FullName, asmref.FullName)); } else { - if (asmref.GetPublicKeyToken() != null && asmref.GetPublicKeyToken().Length != 0) - { - throw new FatalCompilerErrorException(DiagnosticEvent.RuntimeMismatch(reference.Location, runtimeAssemblyName.FullName, asmref.FullName)); - } + if (asmref.PublicKeyOrToken.IsEmpty == false) + throw new FatalCompilerErrorException(DiagnosticEvent.RuntimeMismatch(reference.Location, runtimeAssembly.FullName, asmref.FullName)); } } } @@ -2655,27 +2640,27 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, IDiag diagnostics.GenericCompilerInfo("Parsing class files"); // map the class names to jar entries - Dictionary h = new Dictionary(); - List classNames = new List(); - foreach (Jar jar in options.jars) + var h = new Dictionary(); + var classNames = new List(); + foreach (var jar in import.jars) { - if (options.IsResourcesJar(jar)) - { + if (import.IsResourcesJar(jar)) continue; - } - foreach (Jar.Item item in jar) + + foreach (var item in jar) { - string name = item.Name; - if (name.EndsWith(".class", StringComparison.Ordinal) - && name.Length > 6 - && name.IndexOf('.') == name.Length - 6) + var name = item.Name; + if (name.EndsWith(".class", StringComparison.Ordinal) && + name.Length > 6 && + name.IndexOf('.') == name.Length - 6) { - string className = name.Substring(0, name.Length - 6).Replace('/', '.'); + var className = name.Substring(0, name.Length - 6).Replace('/', '.'); if (h.ContainsKey(className)) { diagnostics.DuplicateClassName(className); - Jar.Item itemRef = h[className]; - if ((options.classesJar != -1 && itemRef.Jar == options.jars[options.classesJar]) || jar != itemRef.Jar) + + var itemRef = h[className]; + if ((import.classesJar != -1 && itemRef.Jar == import.jars[import.classesJar]) || jar != itemRef.Jar) { // the previous class stays, because it was either in an earlier jar or we're processing the classes.jar // which contains the classes loaded from the file system (where the first encountered class wins) @@ -2688,13 +2673,14 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, IDiag classNames.Remove(className); } } + h.Add(className, item); classNames.Add(className); } } } - if (options.assemblyAttributeAnnotations == null) + if (import.assemblyAttributeAnnotations.Count == 0) { // look for "assembly" type that acts as a placeholder for assembly attributes if (h.TryGetValue("assembly", out var assemblyType)) @@ -2707,7 +2693,8 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, IDiag // that acts as the placeholder for assembly attributes if (f.Name == "assembly" && f.Annotations != null) { - options.assemblyAttributeAnnotations = f.Annotations; + import.assemblyAttributeAnnotations.AddRange(f.Annotations); + // HACK remove "assembly" type that exists only as a placeholder for assembly attributes h.Remove(f.Name); assemblyType.Remove(); @@ -2726,9 +2713,9 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, IDiag } // now look for a main method - if (options.mainClass == null && (options.guessFileKind || options.target != IKVM.CoreLib.Symbols.Emit.PEFileKinds.Dll)) + if (import.mainClass == null && (import.guessFileKind || import.target != IKVM.CoreLib.Symbols.Emit.PEFileKinds.Dll)) { - foreach (string className in classNames) + foreach (var className in classNames) { try { @@ -2740,7 +2727,7 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, IDiag if (m.IsPublic && m.IsStatic && m.Name == "main" && m.Signature == "([Ljava.lang.String;)V") { diagnostics.MainMethodFound(f.Name); - options.mainClass = f.Name; + import.mainClass = f.Name; goto break_outer; } } @@ -2754,83 +2741,68 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, IDiag break_outer:; } - if (options.guessFileKind && options.mainClass == null) - { - options.target = IKVM.CoreLib.Symbols.Emit.PEFileKinds.Dll; - } + if (import.guessFileKind && import.mainClass == null) + import.target = IKVM.CoreLib.Symbols.Emit.PEFileKinds.Dll; - if (options.target != IKVM.CoreLib.Symbols.Emit.PEFileKinds.Dll && options.mainClass == null) - { + if (import.target != IKVM.CoreLib.Symbols.Emit.PEFileKinds.Dll && import.mainClass == null) throw new FatalCompilerErrorException(DiagnosticEvent.ExeRequiresMainClass()); - } - if (options.target == IKVM.CoreLib.Symbols.Emit.PEFileKinds.Dll && options.props.Count != 0) - { + if (import.target == IKVM.CoreLib.Symbols.Emit.PEFileKinds.Dll && import.props.Count != 0) throw new FatalCompilerErrorException(DiagnosticEvent.PropertiesRequireExe()); - } - if (options.path == null) + if (import.path == null) { - if (options.target == IKVM.CoreLib.Symbols.Emit.PEFileKinds.Dll) + if (import.target == IKVM.CoreLib.Symbols.Emit.PEFileKinds.Dll) { - if (options.targetIsModule) - { - options.path = ImportContext.GetFileInfo(options.assembly + ".netmodule"); - } + if (import.targetIsModule) + import.path = ImportContextFactory.GetFileInfo(import.assembly + ".netmodule"); else - { - options.path = ImportContext.GetFileInfo(options.assembly + ".dll"); - } + import.path = ImportContextFactory.GetFileInfo(import.assembly + ".dll"); } else - { - options.path = ImportContext.GetFileInfo(options.assembly + ".exe"); - } + import.path = ImportContextFactory.GetFileInfo(import.assembly + ".exe"); - diagnostics.OutputFileIs(options.path.ToString()); + diagnostics.OutputFileIs(import.path.ToString()); } - if (options.targetIsModule) + if (import.targetIsModule) { - if (options.classLoader != null) - { + if (import.classLoader != null) throw new FatalCompilerErrorException(DiagnosticEvent.ModuleCannotHaveClassLoader()); - } + // TODO if we're overwriting a user specified assembly name, we need to emit a warning - options.assembly = options.path.Name; + import.assembly = import.path.Name; } diagnostics.GenericCompilerInfo("Constructing compiler"); + var referencedAssemblies = new List(references.Count); for (int i = 0; i < references.Count; i++) { - // if reference is to base assembly, set it explicitly for resolution - if (compiler.baseAssembly == null && options.bootstrap == false && IsBaseAssembly(context, context.Resolver.ResolveAssembly(references[i]))) - compiler.baseAssembly = context.Resolver.ResolveAssembly(references[i]); - - var acl = context.AssemblyClassLoaderFactory.FromAssembly(context.Resolver.ResolveAssembly(references[i])); + var acl = context.AssemblyClassLoaderFactory.FromAssembly(references[i]); if (referencedAssemblies.Contains(acl)) diagnostics.DuplicateAssemblyReference(acl.MainAssembly.FullName); referencedAssemblies.Add(acl); } - loader = new ImportClassLoader(context, compiler, diagnostics, referencedAssemblies.ToArray(), options, options.path, options.targetIsModule, options.assembly, h); + loader = new ImportClassLoader(context, compiler, diagnostics, referencedAssemblies.ToArray(), import, import.path, import.targetIsModule, import.assembly, h); loader.classesToCompile = new List(h.Keys); - if (options.remapfile != null) + + if (import.remapfile != null) { - diagnostics.GenericCompilerInfo($"Loading remapped types (1) from {options.remapfile}"); + diagnostics.GenericCompilerInfo($"Loading remapped types (1) from {import.remapfile}"); FileStream fs; try { // NOTE: Using FileShare.ReadWrite ensures other FileStreams (from other processes) can be opened // simultaneously on this file while we are reading it. - fs = new FileStream(options.remapfile.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); + fs = new FileStream(import.remapfile.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); } catch (Exception e) { - throw new FatalCompilerErrorException(DiagnosticEvent.ErrorReadingFile(options.remapfile.FullName, e.Message)); + throw new FatalCompilerErrorException(DiagnosticEvent.ErrorReadingFile(import.remapfile.FullName, e.Message)); } try @@ -2843,7 +2815,7 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, IDiag } catch (MapXml.MapXmlException x) { - throw new FatalCompilerErrorException(DiagnosticEvent.ErrorParsingMapFile(options.remapfile.FullName, x.Message)); + throw new FatalCompilerErrorException(DiagnosticEvent.ErrorParsingMapFile(import.remapfile.FullName, x.Message)); } if (loader.ValidateAndSetMap(map) == false) @@ -2854,53 +2826,17 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, IDiag fs.Close(); } - if (options.bootstrap) + if (import.bootstrap) context.ClassLoaderFactory.SetBootstrapClassLoader(loader); } - // If we do not yet have a reference to the base assembly and we are not compiling the base assembly, - // try to find the base assembly by looking at the assemblies that the runtime references - if (compiler.baseAssembly == null && options.bootstrap == false) - { - foreach (var name in compiler.runtimeAssembly.GetReferencedAssemblies()) - { - IAssemblySymbol asm = null; - - try - { - var path = Path.Combine(Path.GetDirectoryName(compiler.runtimeAssembly.Location), name.Name + ".dll"); - if (File.Exists(path)) - asm = LoadReferencedAssembly(compiler, path); - } - catch (FileNotFoundException) - { - - } - - if (asm != null && IsBaseAssembly(context, asm)) - { - RuntimeAssemblyClassLoader.PreloadExportedAssemblies(context.StaticCompiler, asm); - compiler.baseAssembly = asm; - break; - } - } - - if (compiler.baseAssembly == null) - { - throw new FatalCompilerErrorException(DiagnosticEvent.BootstrapClassesMissing()); - } - - // we need to scan again for remapped types, now that we've loaded the core library - context.ClassLoaderFactory.LoadRemappedTypes(); - } - - if (options.bootstrap == false) + if (import.bootstrap == false) { allReferencesAreStrongNamed &= IsSigned(context.Resolver.ResolveBaseAssembly()); loader.AddReference(context.AssemblyClassLoaderFactory.FromAssembly(context.Resolver.ResolveBaseAssembly())); } - if ((options.keyPair != null || options.publicKey != null) && !allReferencesAreStrongNamed) + if ((import.keyPair != null || import.publicKey != null) && !allReferencesAreStrongNamed) { throw new FatalCompilerErrorException(DiagnosticEvent.StrongNameRequiresStrongNamedRefs()); } @@ -2910,7 +2846,7 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, IDiag loader.LoadMapXml(); } - if (options.bootstrap == false) + if (import.bootstrap == false) { loader.fakeTypes = context.FakeTypes; loader.fakeTypes.Load(context.Resolver.ResolveBaseAssembly()); @@ -3066,7 +3002,7 @@ int CompilePass3() } catch (IKVM.Reflection.MissingMemberException x) { - Context.StaticCompiler.IssueMissingTypeMessage((ITypeSymbol)Context.Resolver.ResolveMember(x.MemberInfo)); + Context.StaticCompiler.IssueMissingTypeMessage((ITypeSymbol)Context.Resolver.ImportMember(x.MemberInfo)); return 1; } } @@ -3127,8 +3063,7 @@ int CompilePass3() throw new FatalCompilerErrorException(DiagnosticEvent.ClassLoaderConstructorMissing()); // apply custom attribute specifying custom class loader - var ci = Context.Resolver.ResolveRuntimeType(typeof(CustomAssemblyClassLoaderAttribute).FullName).GetConstructor(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic, new[] { Context.Types.Type }); - assemblyBuilder.SetCustomAttribute(Context.Resolver.Symbols.CreateCustomAttribute(ci, new object[] { classLoaderType.TypeAsTBD })); + Context.AttributeHelper.SetCustomAssemblyClassLoaderAttribute(assemblyBuilder, classLoaderType.TypeAsTBD); // the class loader type defines a module initialize method, ensure we call it upon module load var mwModuleInit = classLoaderType.GetMethodWrapper("InitializeModule", "(Lcli.System.Reflection.Module;)V", false); @@ -3137,7 +3072,7 @@ int CompilePass3() moduleInitBuilders.Add((mb, il) => { il.Emit(System.Reflection.Emit.OpCodes.Ldtoken, mb); - il.Emit(System.Reflection.Emit.OpCodes.Call, Context.Resolver.ResolveCoreType(typeof(System.Reflection.MethodBase).FullName).GetMethod("GetMethodFromHandle", new[] { Context.Resolver.ResolveCoreType(typeof(RuntimeMethodHandle).FullName) })); + il.Emit(System.Reflection.Emit.OpCodes.Call, Context.Resolver.ResolveCoreType(typeof(System.Reflection.MethodBase).FullName).GetMethod("GetMethodFromHandle", [Context.Resolver.ResolveCoreType(typeof(RuntimeMethodHandle).FullName)])); il.Emit(System.Reflection.Emit.OpCodes.Callvirt, Context.Resolver.ResolveCoreType(typeof(System.Reflection.MemberInfo).FullName).GetProperty("Module").GetGetMethod()); il.Emit(System.Reflection.Emit.OpCodes.Call, Context.Resolver.ResolveRuntimeType("IKVM.Runtime.ByteCodeHelper").GetMethod("InitializeModule")); }); @@ -3146,12 +3081,12 @@ int CompilePass3() if (state.iconfile != null) { - assemblyBuilder.DefineIconResource(ImportContext.ReadAllBytes(state.iconfile)); + assemblyBuilder.DefineIconResource(ImportContextFactory.ReadAllBytes(state.iconfile)); } if (state.manifestFile != null) { - assemblyBuilder.DefineManifestResource(ImportContext.ReadAllBytes(state.manifestFile)); + assemblyBuilder.DefineManifestResource(ImportContextFactory.ReadAllBytes(state.manifestFile)); } assemblyBuilder.DefineVersionInfoResource(); diff --git a/src/IKVM.Tools.Importer/ImportContext.cs b/src/IKVM.Tools.Importer/ImportContext.cs index b8d0f8f5b..ddad70d93 100644 --- a/src/IKVM.Tools.Importer/ImportContext.cs +++ b/src/IKVM.Tools.Importer/ImportContext.cs @@ -1,1334 +1,201 @@ -/* - Copyright (C) 2002-2014 Jeroen Frijters +/* + Copyright (C) 2002-2014 Jeroen Frijters - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jeroen Frijters + jeroen@frijters.net - Jeroen Frijters - jeroen@frijters.net - */ using System; using System.Collections.Generic; using System.IO; -using System.IO.Compression; -using System.Linq; -using System.Reflection.Metadata; -using System.Reflection.PortableExecutable; using System.Text.RegularExpressions; using System.Threading; -using IKVM.ByteCode; -using IKVM.CoreLib.Diagnostics; +using IKVM.CoreLib.Symbols; using IKVM.Reflection; -using IKVM.Reflection.Diagnostics; +using IKVM.Reflection.Emit; using IKVM.Runtime; -using IKVM.Tools.Core.Diagnostics; - -using Microsoft.Extensions.DependencyInjection; namespace IKVM.Tools.Importer { /// - /// Represents the context of an import operation outputing a single assembly. + /// Holds some state for an instance of . /// - class ImportContext + sealed class ImportContext { - /// - /// for the importer. - /// - class CompilerOptionsDiagnosticHandler : FormattedDiagnosticHandler - { - - readonly ImportState _options; - - /// - /// Initializes a new instance. - /// - /// - /// - /// - public CompilerOptionsDiagnosticHandler(ImportState options, string spec, DiagnosticFormatterProvider formatters) : - base(spec, formatters) - { - _options = options ?? throw new ArgumentNullException(nameof(options)); - } - - /// - public override bool IsEnabled(Diagnostic diagnostic) - { - return diagnostic.Level is not DiagnosticLevel.Trace and not DiagnosticLevel.Info; - } - - /// - public override void Report(in DiagnosticEvent @event) - { - if (IsEnabled(@event.Diagnostic) == false) - return; - - var key = @event.Diagnostic.Id.ToString(); - for (int i = 0; ; i++) - { - if (_options.suppressWarnings.Contains(key)) - return; - - if (i == @event.Args.Length) - break; - - key += ":" + @event.Args[i]; - } - - _options.suppressWarnings.Add(key); - - base.Report(@event); - } - - } - - readonly ImportOptions _options; - static readonly AssemblyResolver resolver = new AssemblyResolver(); - string manifestMainClass; - string defaultAssemblyName; - static bool time; - static string runtimeAssembly; - static bool nostdlib; - static bool nonDeterministicOutput; - static DebugMode debugMode; - static readonly List libpaths = new List(); - - public static int Execute(ImportOptions options) - { - DateTime start = DateTime.Now; - Thread.CurrentThread.Name = "compiler"; - - try - { - try - { - return Compile(options); - } - catch (TypeInitializationException x) - { - if (x.InnerException is FatalCompilerErrorException) - throw x.InnerException; - - throw; - } - } - catch (FatalCompilerErrorException x) - { - Console.Error.WriteLine(x.Message); - return 1; - } - catch (Exception x) - { - Console.Error.WriteLine(); - Console.Error.WriteLine("*** COMPILER ERROR ***"); - Console.Error.WriteLine(); - Console.Error.WriteLine(System.Reflection.Assembly.GetExecutingAssembly().FullName); - Console.Error.WriteLine(System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory()); - Console.Error.WriteLine("{0} {1}-bit", Environment.Version, IntPtr.Size * 8); - Console.Error.WriteLine(); - Console.Error.WriteLine(x); - return 2; - } - finally - { - if (time) - { - Console.WriteLine("Total cpu time: {0}", System.Diagnostics.Process.GetCurrentProcess().TotalProcessorTime); - Console.WriteLine("User cpu time: {0}", System.Diagnostics.Process.GetCurrentProcess().UserProcessorTime); - Console.WriteLine("Total wall clock time: {0}", DateTime.Now - start); - Console.WriteLine("Peak virtual memory: {0}", System.Diagnostics.Process.GetCurrentProcess().PeakVirtualMemorySize64); - for (int i = 0; i <= GC.MaxGeneration; i++) - { - Console.WriteLine("GC({0}) count: {1}", i, GC.CollectionCount(i)); - } - } - } - } - - /// - /// Generates a diagnostic instance from the diagnostics options. - /// - /// - /// - /// - /// - static IDiagnosticHandler GetDiagnostics(IServiceProvider services, ImportState options, string spec) - { - if (services is null) - throw new ArgumentNullException(nameof(services)); - if (string.IsNullOrWhiteSpace(spec)) - throw new ArgumentException($"'{nameof(spec)}' cannot be null or whitespace.", nameof(spec)); - - return ActivatorUtilities.CreateInstance(services, options, spec); - } - - /// - /// Initiates a compilation with the given options. - /// - /// - /// - /// - /// - static int Compile(ImportOptions options) - { - // use a service collection to initialize core services - var rootTarget = new ImportState(); - var services = new ServiceCollection(); - services.AddToolsDiagnostics(); - services.AddSingleton(p => GetDiagnostics(p, rootTarget, options.Log)); - services.AddSingleton(); - services.AddSingleton(); - using var provider = services.BuildServiceProvider(); - - var diagnostics = provider.GetRequiredService(); - var compiler = provider.GetRequiredService(); - var targets = new List(); - var context = new RuntimeContext(new RuntimeContextOptions(), diagnostics, provider.GetRequiredService(), options.Bootstrap, compiler); - - // discover the core lib from the references - var coreLibName = FindCoreLibName(rootTarget.unresolvedReferences, libpaths); - if (coreLibName == null) - { - diagnostics.CoreClassesMissing(); - throw new Exception(); - } - - var universeOptions = UniverseOptions.ResolveMissingMembers | UniverseOptions.EnableFunctionPointers; - if (nonDeterministicOutput == false) - universeOptions |= UniverseOptions.DeterministicOutput; - - // configure the universe of types - var universe = new Universe(universeOptions, coreLibName); - universe.ResolvedMissingMember += (requestingModule, member) => - { - if (requestingModule != null && member is IKVM.Reflection.Type type) - diagnostics.UnableToResolveType(requestingModule.Name, type.FullName, member.Module.FullyQualifiedName); - }; - - // enable embedded symbol writer if debug mode is enabled - if (rootTarget.debugMode == DebugMode.Portable) - universe.SetSymbolWriterFactory(module => new PortablePdbSymbolWriter(module)); - - compiler.rootTarget = rootTarget; - var importer = new ImportContext(); - importer.ParseCommandLine(context, compiler, diagnostics, options, targets, rootTarget); - resolver.Warning += (warning, message, parameters) => loader_Warning(compiler, diagnostics, warning, message, parameters); - resolver.Init(universe, nostdlib, rootTarget.unresolvedReferences, libpaths); - ResolveReferences(compiler, diagnostics, targets); - ResolveStrongNameKeys(targets); - - if (targets.Count == 0) - throw new FatalCompilerErrorException(DiagnosticEvent.NoTargetsFound()); - - if (compiler.errorCount != 0) - return 1; - - try - { - return ImportClassLoader.Compile(importer, context, compiler, diagnostics, runtimeAssembly, targets); - } - catch (FileFormatLimitationExceededException x) - { - throw new FatalCompilerErrorException(DiagnosticEvent.FileFormatLimitationExceeded(x.Message)); - } - } - - /// - /// Finds the first potential core library in the reference set. - /// - /// - /// - /// - static string FindCoreLibName(IList references, IList libpaths) - { - if (references != null) - foreach (var reference in references) - if (GetAssemblyNameIfCoreLib(reference) is string coreLibName) - return coreLibName; - - if (libpaths != null) - foreach (var libpath in libpaths) - foreach (var dll in Directory.GetFiles(libpath, "*.dll")) - if (GetAssemblyNameIfCoreLib(dll) is string coreLibName) - return coreLibName; - - return null; - } - - /// - /// Returns true if the given assembly is a core library. - /// - /// - /// - static string GetAssemblyNameIfCoreLib(string path) - { - if (File.Exists(path) == false) - return null; - - using var st = File.OpenRead(path); - using var pe = new PEReader(st); - var mr = pe.GetMetadataReader(); - - foreach (var handle in mr.TypeDefinitions) - if (IsSystemObject(mr, handle)) - return mr.GetString(mr.GetAssemblyDefinition().Name); - - return null; - } + internal string manifestMainClass; + internal string defaultAssemblyName; + internal List jars = new List(); + private Dictionary jarMap = new Dictionary(); + internal int classesJar = -1; + internal int resourcesJar = -1; + internal bool nojarstubs; + internal FileInfo path; + internal FileInfo keyfile; + internal string keycontainer; + internal bool delaysign; + internal byte[] publicKey; + internal StrongNameKeyPair keyPair; + internal Version version; + internal string fileversion; + internal FileInfo iconfile; + internal FileInfo manifestFile; + internal bool targetIsModule; + internal string assembly; + internal string mainClass; + internal ApartmentState apartment; + internal IKVM.CoreLib.Symbols.Emit.PEFileKinds target; + internal bool guessFileKind; + internal List unresolvedReferences = new(); + internal Dictionary legacyStubReferences = new(); // only used during command line parsing + internal List references = new(); + internal string[] peerReferences; + internal bool crossReferenceAllPeers = true; + internal string[] classesToExclude; // only used during command line parsing + internal FileInfo remapfile; + internal Dictionary props; + internal bool noglobbing; + internal CodeGenOptions codegenoptions; + internal DebugMode debugMode = DebugMode.Portable; + internal string debugFileName; + internal bool compressedResources; + internal string[] privatePackages; + internal string[] publicPackages; + internal string sourcepath; + internal Dictionary externalResources; + internal string classLoader; + internal System.Reflection.PortableExecutableKinds pekind = System.Reflection.PortableExecutableKinds.ILOnly; + internal IKVM.CoreLib.Symbols.ImageFileMachine imageFileMachine = IKVM.CoreLib.Symbols.ImageFileMachine.I386; + internal ulong baseAddress; + internal uint fileAlignment; + internal bool highentropyva; + internal List sharedclassloader; // should *not* be deep copied in Copy(), because we want the list of all compilers that share a class loader + internal HashSet suppressWarnings = new HashSet(StringComparer.OrdinalIgnoreCase); + internal HashSet errorWarnings = new HashSet(StringComparer.OrdinalIgnoreCase); + internal bool warnaserror; // treat all warnings as errors + internal List proxies = new(); + internal List assemblyAttributeAnnotations = new(); + internal bool warningLevelHigh; + internal bool noParameterReflection; + internal bool bootstrap; + internal string log; - /// - /// Returns true if the given type definition handle refers to "System.Object". - /// - /// - /// - /// - static bool IsSystemObject(MetadataReader reader, TypeDefinitionHandle th) + internal ImportContext Copy() { - var td = reader.GetTypeDefinition(th); - var ns = reader.GetString(td.Namespace); - var nm = reader.GetString(td.Name); - - return ns == "System" && nm == "Object"; - } - - static void loader_Warning(StaticCompiler compiler, IDiagnosticHandler diagnostics, AssemblyResolver.WarningId warning, string message, string[] parameters) - { - switch (warning) - { - case AssemblyResolver.WarningId.HigherVersion: - diagnostics.AssumeAssemblyVersionMatch(parameters[0], parameters[1]); - break; - case AssemblyResolver.WarningId.InvalidLibDirectoryOption: - diagnostics.InvalidDirectoryInLibOptionPath(parameters[0]); - break; - case AssemblyResolver.WarningId.InvalidLibDirectoryEnvironment: - diagnostics.InvalidDirectoryInLibEnvironmentPath(parameters[0]); - break; - case AssemblyResolver.WarningId.LegacySearchRule: - diagnostics.LegacySearchRule(parameters[0]); - break; - case AssemblyResolver.WarningId.LocationIgnored: - diagnostics.AssemblyLocationIgnored(parameters[0], parameters[1], parameters[2]); - break; - default: - diagnostics.UnknownWarning(string.Format(message, parameters)); - break; - } - } - - static void ResolveStrongNameKeys(List targets) - { - foreach (var options in targets) - { - if (options.keyfile != null && options.keycontainer != null) - throw new FatalCompilerErrorException(DiagnosticEvent.CannotSpecifyBothKeyFileAndContainer()); - - if (options.keyfile == null && options.keycontainer == null && options.delaysign) - throw new FatalCompilerErrorException(DiagnosticEvent.DelaySignRequiresKey()); - - if (options.keyfile != null) - { - if (options.delaysign) - { - var buf = ReadAllBytes(options.keyfile); - try - { - // maybe it is a key pair, if so we need to extract just the public key - buf = new StrongNameKeyPair(buf).PublicKey; - } - catch - { - - } - - options.publicKey = buf; - } - else - { - SetStrongNameKeyPair(ref options.keyPair, options.keyfile, null); - } - } - else if (options.keycontainer != null) - { - StrongNameKeyPair keyPair = null; - SetStrongNameKeyPair(ref keyPair, null, options.keycontainer); - if (options.delaysign) - options.publicKey = keyPair.PublicKey; - else - options.keyPair = keyPair; - } - } - } - - internal static byte[] ReadAllBytes(FileInfo path) - { - try - { - return File.ReadAllBytes(path.FullName); - } - catch (Exception x) - { - throw new FatalCompilerErrorException(DiagnosticEvent.ErrorReadingFile(path.ToString(), x.Message)); - } - } - - void ParseCommandLine(RuntimeContext context, StaticCompiler compiler, IDiagnosticHandler diagnostics, ImportOptions options, List targets, ImportState compilerOptions) - { - compilerOptions.target = IKVM.CoreLib.Symbols.Emit.PEFileKinds.ConsoleApplication; - compilerOptions.guessFileKind = true; - compilerOptions.version = new Version(0, 0, 0, 0); - compilerOptions.apartment = ApartmentState.STA; - compilerOptions.props = new Dictionary(); - ContinueParseCommandLine(context, compiler, diagnostics, options, targets, compilerOptions); - } - - void ContinueParseCommandLine(RuntimeContext context, StaticCompiler compiler, IDiagnosticHandler diagnostics, ImportOptions options, List targets, ImportState compilerOptions) - { - if (options.Output != null) - compilerOptions.path = options.Output; - - if (options.AssemblyName != null) - compilerOptions.assembly = options.AssemblyName; - - switch (options.Target) - { - case ImportTarget.Exe: - compilerOptions.target = IKVM.CoreLib.Symbols.Emit.PEFileKinds.ConsoleApplication; - compilerOptions.guessFileKind = false; - break; - case ImportTarget.WinExe: - compilerOptions.target = IKVM.CoreLib.Symbols.Emit.PEFileKinds.WindowApplication; - compilerOptions.guessFileKind = false; - break; - case ImportTarget.Module: - compilerOptions.targetIsModule = true; - compilerOptions.target = IKVM.CoreLib.Symbols.Emit.PEFileKinds.Dll; - compilerOptions.guessFileKind = false; - nonDeterministicOutput = true; - break; - case ImportTarget.Library: - compilerOptions.target = IKVM.CoreLib.Symbols.Emit.PEFileKinds.Dll; - compilerOptions.guessFileKind = false; - break; - default: - throw new FatalCompilerErrorException(DiagnosticEvent.UnrecognizedTargetType(options.Target.ToString())); - } - - switch (options.Platform) - { - case ImportPlatform.X86: - compilerOptions.pekind = System.Reflection.PortableExecutableKinds.ILOnly | System.Reflection.PortableExecutableKinds.Required32Bit; - compilerOptions.imageFileMachine = IKVM.CoreLib.Symbols.ImageFileMachine.I386; - break; - case ImportPlatform.X64: - compilerOptions.pekind = System.Reflection.PortableExecutableKinds.ILOnly | System.Reflection.PortableExecutableKinds.PE32Plus; - compilerOptions.imageFileMachine = IKVM.CoreLib.Symbols.ImageFileMachine.AMD64; - break; - case ImportPlatform.ARM: - compilerOptions.pekind = System.Reflection.PortableExecutableKinds.ILOnly; - compilerOptions.imageFileMachine = IKVM.CoreLib.Symbols.ImageFileMachine.ARM; - break; - case ImportPlatform.ARM64: - compilerOptions.pekind = System.Reflection.PortableExecutableKinds.ILOnly; - compilerOptions.imageFileMachine = IKVM.CoreLib.Symbols.ImageFileMachine.ARM64; - break; - case ImportPlatform.AnyCpu32BitPreferred: - compilerOptions.pekind = System.Reflection.PortableExecutableKinds.ILOnly | System.Reflection.PortableExecutableKinds.Preferred32Bit; - compilerOptions.imageFileMachine = IKVM.CoreLib.Symbols.ImageFileMachine.Unknown; - break; - case ImportPlatform.AnyCpu: - compilerOptions.pekind = System.Reflection.PortableExecutableKinds.ILOnly; - compilerOptions.imageFileMachine = IKVM.CoreLib.Symbols.ImageFileMachine.Unknown; - break; - default: - throw new FatalCompilerErrorException(DiagnosticEvent.UnrecognizedPlatform(options.Platform.ToString())); - } - - switch (options.Apartment) - { - case ImportApartment.STA: - compilerOptions.apartment = ApartmentState.STA; - break; - case ImportApartment.MTA: - compilerOptions.apartment = ApartmentState.MTA; - break; - case ImportApartment.None: - compilerOptions.apartment = ApartmentState.Unknown; - break; - default: - throw new FatalCompilerErrorException(DiagnosticEvent.UnrecognizedApartment(options.Apartment.ToString())); - } - - if (options.NoGlobbing) - compilerOptions.noglobbing = true; - - if (options.Properties.Count > 0) - foreach (var kvp in options.Properties) - compilerOptions.props[kvp.Key] = kvp.Value; - - if (options.EnableAssertions != null) - { - if (options.EnableAssertions.Length == 0) - compilerOptions.props["ikvm.assert.default"] = "true"; - else - compilerOptions.props["ikvm.assert.enable"] = string.Join(";", options.EnableAssertions); - } - - if (options.DisableAssertions != null) - { - if (options.DisableAssertions.Length == 0) - compilerOptions.props["ikvm.assert.default"] = "false"; - else - compilerOptions.props["ikvm.assert.disable"] = string.Join(";", options.DisableAssertions); - } - - if (options.RemoveAssertions) - compilerOptions.codegenoptions |= CodeGenOptions.RemoveAsserts; - - if (options.Main != null) - compilerOptions.mainClass = options.Main; - - foreach (var reference in options.References) - ArrayAppend(ref compilerOptions.unresolvedReferences, reference); - - foreach (var spec in options.Recurse) - { - var exists = false; - - // MONOBUG On Mono 1.0.2, Directory.Exists throws an exception if we pass an invalid directory name - try - { - exists = Directory.Exists((string)spec); - } - catch (IOException) - { - - } - - var found = false; - if (exists) - { - var dir = new DirectoryInfo(spec); - found = Recurse(context, compiler, compilerOptions, diagnostics, dir, dir, "*"); - } - else - { - try - { - var dir = new DirectoryInfo(Path.GetDirectoryName(spec)); - if (dir.Exists) - { - found = Recurse(context, compiler, compilerOptions, diagnostics, dir, dir, Path.GetFileName(spec)); - } - else - { - found = RecurseJar(context, compiler, compilerOptions, diagnostics, spec); - } - } - catch (PathTooLongException) - { - throw new FatalCompilerErrorException(DiagnosticEvent.PathTooLong(spec)); - } - catch (DirectoryNotFoundException) - { - throw new FatalCompilerErrorException(DiagnosticEvent.PathNotFound(spec)); - } - catch (ArgumentException) - { - throw new FatalCompilerErrorException(DiagnosticEvent.InvalidPath(spec)); - } - } - - if (!found) - throw new FatalCompilerErrorException(DiagnosticEvent.FileNotFound(spec)); - } - - foreach (var kvp in options.Resources) - { - var fileInfo = GetFileInfo(kvp.Value.FullName); - var fileName = kvp.Key.TrimStart('/').TrimEnd('/'); - compilerOptions.GetResourcesJar().Add(fileName, ReadAllBytes(fileInfo), fileInfo); - } - - foreach (var kvp in options.ExternalResources) - { - if (!File.Exists(kvp.Value.FullName)) - throw new FatalCompilerErrorException(DiagnosticEvent.ExternalResourceNotFound(kvp.Value.FullName)); - if (Path.GetFileName(kvp.Value.FullName) != kvp.Value.FullName) - throw new FatalCompilerErrorException(DiagnosticEvent.ExternalResourceNameInvalid(kvp.Value.FullName)); - - // TODO resource name clashes should be tested - compilerOptions.externalResources ??= new Dictionary(); - compilerOptions.externalResources.Add(kvp.Key, kvp.Value.FullName); - } - - if (options.NoJNI) - compilerOptions.codegenoptions |= CodeGenOptions.NoJNI; - - if (options.Exclude != null) - ProcessExclusionFile(ref compilerOptions.classesToExclude, options.Exclude.FullName); - - if (options.Version != null) - compilerOptions.version = options.Version; - - if (options.FileVersion != null) - compilerOptions.fileversion = options.FileVersion.ToString(); - - if (options.Win32Icon != null) - { - compilerOptions.iconfile = GetFileInfo(options.Win32Icon.FullName); - } - - if (options.Win32Manifest != null) - compilerOptions.manifestFile = GetFileInfo(options.Win32Manifest.FullName); - - if (options.KeyFile != null) - compilerOptions.keyfile = GetFileInfo(options.KeyFile.FullName); - - if (options.Key != null) - compilerOptions.keycontainer = options.Key; - - if (options.DelaySign) - compilerOptions.delaysign = true; - - switch (options.Debug) - { - case ImportDebug.Full: - compilerOptions.codegenoptions |= CodeGenOptions.EmitSymbols; - compilerOptions.debugMode = DebugMode.Full; - break; - case ImportDebug.Portable: - compilerOptions.codegenoptions |= CodeGenOptions.EmitSymbols; - compilerOptions.debugMode = DebugMode.Portable; - break; - case ImportDebug.Embedded: - compilerOptions.codegenoptions |= CodeGenOptions.EmitSymbols; - compilerOptions.debugMode = DebugMode.Embedded; - break; - } - - if (options.Deterministic == false) - nonDeterministicOutput = true; - - if (options.Optimize == false) - compilerOptions.codegenoptions |= CodeGenOptions.DisableOptimizations; - - if (options.SourcePath != null) - compilerOptions.sourcepath = options.SourcePath.FullName; - - if (options.Remap != null) - compilerOptions.remapfile = GetFileInfo(options.Remap.FullName); - - if (options.NoStackTraceInfo) - compilerOptions.codegenoptions |= CodeGenOptions.NoStackTraceInfo; - - if (options.RemoveUnusedPrivateFields) - compilerOptions.codegenoptions |= CodeGenOptions.RemoveUnusedFields; - - if (options.CompressResources) - compilerOptions.compressedResources = true; - - if (options.StrictFinalFieldSemantics) - compilerOptions.codegenoptions |= CodeGenOptions.StrictFinalFieldSemantics; - - if (options.PrivatePackages != null) - foreach (var prefix in options.PrivatePackages) - ArrayAppend(ref compilerOptions.privatePackages, prefix); - - if (options.PublicPackages != null) - foreach (var prefix in options.PublicPackages) - ArrayAppend(ref compilerOptions.publicPackages, prefix); - - if (options.NoWarn != null) - foreach (var diagnostic in options.NoWarn) - compilerOptions.suppressWarnings.Add($"IKVM{diagnostic.Id:D4}"); - - // TODO handle specific diagnostic IDs - if (options.WarnAsError != null) - { - if (options.WarnAsError.Length == 0) - compilerOptions.warnaserror = true; - else - foreach (var i in options.WarnAsError) - compilerOptions.errorWarnings.Add($"IKVM{i.Id:D4}"); - } - - if (options.Runtime != null) - runtimeAssembly = options.Runtime.FullName; - - if (options.Time) - time = true; - - if (options.ClassLoader != null) - compilerOptions.classLoader = options.ClassLoader; - - if (options.SharedClassLoader) - compilerOptions.sharedclassloader ??= new List(); - - if (options.BaseAddress != null) - { - var baseAddress = options.BaseAddress; - ulong baseAddressParsed; - if (baseAddress.StartsWith("0x", StringComparison.OrdinalIgnoreCase)) - baseAddressParsed = ulong.Parse(baseAddress.Substring(2), System.Globalization.NumberStyles.AllowHexSpecifier); - else - baseAddressParsed = ulong.Parse(baseAddress); // note that unlike CSC we don't support octal - - compilerOptions.baseAddress = (baseAddressParsed & 0xFFFFFFFFFFFF0000UL); - } - - if (options.FileAlign != null) - { - if (!uint.TryParse(options.FileAlign, out var filealign) || filealign < 512 || filealign > 8192 || (filealign & (filealign - 1)) != 0) - throw new FatalCompilerErrorException(DiagnosticEvent.InvalidFileAlignment(options.FileAlign)); - - compilerOptions.fileAlignment = filealign; - } - - if (options.NoPeerCrossReference) - compilerOptions.crossReferenceAllPeers = false; - - if (options.NoStdLib) - nostdlib = true; - - if (options.Libraries != null) - foreach (var lib in options.Libraries) - libpaths.Add(lib.FullName); - - if (options.NoAutoSerialization) - compilerOptions.codegenoptions |= CodeGenOptions.NoAutomagicSerialization; - - if (options.HighEntropyVA) - { - compilerOptions.highentropyva = true; - } - - if (options.Proxies != null) + ImportContext copy = (ImportContext)MemberwiseClone(); + copy.jars = Copy(jars); + copy.jarMap = new Dictionary(jarMap); + if (props != null) { - foreach (var proxy in options.Proxies) - { - if (compilerOptions.proxies.Contains(proxy)) - diagnostics.DuplicateProxy(proxy); - - compilerOptions.proxies.Add(proxy); - } - } - - if (options.AllowNonVirtualCalls) - JVM.AllowNonVirtualCalls = true; - - if (options.Static) - { - // we abuse -static to also enable support for NoRefEmit scenarios - compilerOptions.codegenoptions |= CodeGenOptions.DisableDynamicBinding | CodeGenOptions.NoRefEmitHelpers; - } - - if (options.NoJarStubs) // undocumented temporary option to mitigate risk - { - compilerOptions.nojarstubs = true; - } - - if (options.AssemblyAttributes != null) - foreach (var i in options.AssemblyAttributes) - ProcessAttributeAnnotationsClass(context, diagnostics, ref compilerOptions.assemblyAttributeAnnotations, i.FullName); - - if (options.WarningLevel4Option) // undocumented option to always warn if a class isn't found - compilerOptions.warningLevelHigh = true; - - if (options.NoParameterReflection) // undocumented option to compile core class libraries with, to disable MethodParameter attribute - compilerOptions.noParameterReflection = true; - - if (options.Bootstrap) - compilerOptions.bootstrap = true; - - if (compilerOptions.targetIsModule && compilerOptions.sharedclassloader != null) - throw new FatalCompilerErrorException(DiagnosticEvent.SharedClassLoaderCannotBeUsedOnModuleTarget()); - - ReadFiles(context, compiler, compilerOptions, diagnostics, options.Inputs.Select(i => i.FullName).ToList()); - - foreach (var nested in options.Nested) - { - var nestedLevel = new ImportContext(); - nestedLevel.manifestMainClass = manifestMainClass; - nestedLevel.defaultAssemblyName = defaultAssemblyName; - nestedLevel.ContinueParseCommandLine(context, compiler, diagnostics, nested, targets, compilerOptions.Copy()); - } - - if (compilerOptions.assembly == null) - { - var basename = compilerOptions.path == null ? defaultAssemblyName : compilerOptions.path.Name; - if (basename == null) - throw new FatalCompilerErrorException(DiagnosticEvent.NoOutputFileSpecified()); - - int idx = basename.LastIndexOf('.'); - if (idx > 0) - compilerOptions.assembly = basename.Substring(0, idx); - else - compilerOptions.assembly = basename; - } - - if (compilerOptions.path != null && compilerOptions.guessFileKind) - { - if (compilerOptions.path.Extension.Equals(".dll", StringComparison.OrdinalIgnoreCase)) - compilerOptions.target = IKVM.CoreLib.Symbols.Emit.PEFileKinds.Dll; - - compilerOptions.guessFileKind = false; + copy.props = new Dictionary(props); } - - if (compilerOptions.mainClass == null && manifestMainClass != null && (compilerOptions.guessFileKind || compilerOptions.target != IKVM.CoreLib.Symbols.Emit.PEFileKinds.Dll)) + if (externalResources != null) { - diagnostics.MainMethodFromManifest(manifestMainClass); - compilerOptions.mainClass = manifestMainClass; + copy.externalResources = new Dictionary(externalResources); } - - // schedule run if leaf-node - if (options.Nested == null || options.Nested.Length == 0) - targets.Add(compilerOptions); + copy.suppressWarnings = new(suppressWarnings, StringComparer.OrdinalIgnoreCase); + copy.errorWarnings = new(errorWarnings, StringComparer.OrdinalIgnoreCase); + return copy; } - internal static FileInfo GetFileInfo(string path) + private static List Copy(List jars) { - try + List newJars = new List(); + foreach (Jar jar in jars) { - FileInfo fileInfo = new FileInfo(path); - if (fileInfo.Directory == null) - { - // this happens with an incorrect unc path (e.g. "\\foo\bar") - throw new FatalCompilerErrorException(DiagnosticEvent.InvalidPath(path)); - } - return fileInfo; - } - catch (ArgumentException) - { - throw new FatalCompilerErrorException(DiagnosticEvent.InvalidPath(path)); - } - catch (NotSupportedException) - { - throw new FatalCompilerErrorException(DiagnosticEvent.InvalidPath(path)); - } - catch (PathTooLongException) - { - throw new FatalCompilerErrorException(DiagnosticEvent.PathTooLong(path)); - } - catch (UnauthorizedAccessException) - { - // this exception does not appear to be possible - throw new FatalCompilerErrorException(DiagnosticEvent.InvalidPath(path)); + newJars.Add(jar.Copy()); } + return newJars; } - void ReadFiles(RuntimeContext context, StaticCompiler compiler, ImportState options, IDiagnosticHandler diagnostics, List fileNames) + internal Jar GetJar(string file) { - foreach (var fileName in fileNames) - { - if (defaultAssemblyName == null) - { - try - { - defaultAssemblyName = new FileInfo(Path.GetFileName(fileName)).Name; - } - catch (ArgumentException) - { - // if the filename contains a wildcard (or any other invalid character), we ignore - // it as a potential default assembly name - } - catch (NotSupportedException) - { - - } - catch (PathTooLongException) - { - - } - } - - string[] files = null; - try - { - var path = Path.GetDirectoryName(fileName); - files = Directory.GetFiles(path == "" ? "." : path, Path.GetFileName(fileName)); - } - catch - { - - } + if (jarMap.TryGetValue(file, out var existingJar)) + return jars[existingJar]; - - if (files == null || files.Length == 0) - { - diagnostics.InputFileNotFound(fileName); - } - else - { - foreach (var f in files) - { - ProcessFile(context, compiler, options, diagnostics, null, f); - } - } - } + jarMap.Add(file, jars.Count); + return CreateJar(Path.GetFileName(file)); } - internal static bool TryParseVersion(string str, out Version version) + Jar CreateJar(string jarName) { - if (str.EndsWith(".*")) + int count = 0; + var name = jarName; + retry: + foreach (var jar in jars) { - str = str.Substring(0, str.Length - 1); - int count = str.Split('.').Length; - // NOTE this is the published algorithm for generating automatic build and revision numbers - // (see AssemblyVersionAttribute constructor docs), but it turns out that the revision - // number is off an hour (on my system)... - DateTime now = DateTime.Now; - int seconds = (int)(now.TimeOfDay.TotalSeconds / 2); - int days = (int)(now - new DateTime(2000, 1, 1)).TotalDays; - if (count == 3) + if (jar.Name == name) { - str += days + "." + seconds; - } - else if (count == 4) - { - str += seconds; - } - else - { - version = null; - return false; + name = Path.GetFileNameWithoutExtension(jarName) + "-" + (++count) + Path.GetExtension(jarName); + goto retry; } } - try - { - version = new Version(str); - return version.Major <= 65535 && version.Minor <= 65535 && version.Build <= 65535 && version.Revision <= 65535; - } - catch (ArgumentException) { } - catch (FormatException) { } - catch (OverflowException) { } - version = null; - return false; - } - - static void SetStrongNameKeyPair(ref StrongNameKeyPair strongNameKeyPair, FileInfo keyFile, string keyContainer) - { - try - { - if (keyFile != null) - strongNameKeyPair = new StrongNameKeyPair(ReadAllBytes(keyFile)); - else - strongNameKeyPair = new StrongNameKeyPair(keyContainer); - - // FXBUG we explicitly try to access the public key force a check (the StrongNameKeyPair constructor doesn't validate the key) - if (strongNameKeyPair.PublicKey != null) - { - } - } - catch (Exception x) - { - throw new FatalCompilerErrorException(DiagnosticEvent.InvalidStrongNameKeyPair(keyFile != null ? "file" : "container", x.Message)); - } + var newJar = new Jar(name); + jars.Add(newJar); + return newJar; } - static void ResolveReferences(StaticCompiler compiler, IDiagnosticHandler diagnostics, List targets) + internal Jar GetClassesJar() { - var cache = new Dictionary(); - - foreach (var target in targets) - { - if (target.unresolvedReferences != null) - { - foreach (string reference in target.unresolvedReferences) - { - foreach (var peer in targets) - { - if (peer.assembly.Equals(reference, StringComparison.OrdinalIgnoreCase)) - { - ArrayAppend(ref target.peerReferences, peer.assembly); - goto next_reference; - } - } - - if (!resolver.ResolveReference(cache, ref target.references, reference)) - { - throw new FatalCompilerErrorException(DiagnosticEvent.ReferenceNotFound(reference)); - } - next_reference:; - } - } - } - - // verify that we didn't reference any secondary assemblies of a shared class loader group - foreach (var target in targets) + if (classesJar == -1) { - if (target.references != null) - { - foreach (var asm in target.references) - { - var forwarder = asm.GetType("__"); - if (forwarder != null && forwarder.Assembly != asm) - diagnostics.NonPrimaryAssemblyReference(asm.Location, forwarder.Assembly.GetName().Name); - } - } + classesJar = jars.Count; + CreateJar("classes.jar"); } - // add legacy references (from stub files) - foreach (var target in targets) - foreach (var assemblyName in target.legacyStubReferences.Keys) - ArrayAppend(ref target.references, resolver.LegacyLoad(new AssemblyName(assemblyName), null)); - - // now pre-load the secondary assemblies of any shared class loader groups - foreach (var target in targets) - if (target.references != null) - foreach (var asm in target.references) - RuntimeAssemblyClassLoader.PreloadExportedAssemblies(compiler, compiler.Symbols.GetOrCreateAssemblySymbol(asm)); + return jars[classesJar]; } - static void ArrayAppend(ref T[] array, T element) + internal bool IsClassesJar(Jar jar) { - if (array == null) - array = [element]; - else - array = ArrayUtil.Concat(array, element); + return classesJar != -1 && jars[classesJar] == jar; } - static void ArrayAppend(ref T[] array, T[] append) + internal Jar GetResourcesJar() { - if (array == null) - { - array = append; - } - else if (append != null) + if (resourcesJar == -1) { - T[] tmp = new T[array.Length + append.Length]; - Array.Copy(array, tmp, array.Length); - Array.Copy(append, 0, tmp, array.Length, append.Length); - array = tmp; + resourcesJar = jars.Count; + CreateJar("resources.jar"); } - } - static byte[] ReadFromZip(ZipArchiveEntry ze) - { - using MemoryStream ms = new MemoryStream(); - using Stream s = ze.Open(); - s.CopyTo(ms); - return ms.ToArray(); + return jars[resourcesJar]; } - static bool EmitStubWarning(RuntimeContext context, StaticCompiler compiler, ImportState options, IDiagnosticHandler diagnostics, byte[] buf) + internal bool IsResourcesJar(Jar jar) { - IKVM.Runtime.ClassFile cf; - - try - { - cf = new IKVM.Runtime.ClassFile(context, diagnostics, IKVM.ByteCode.Decoding.ClassFile.Read(buf), "", ClassFileParseOptions.None, null); - } - catch (ClassFormatError) - { - return false; - } - catch (ByteCodeException) - { - return false; - } - - if (cf.IKVMAssemblyAttribute == null) - { - return false; - } - - if (cf.IKVMAssemblyAttribute.StartsWith("[[")) - { - var r = new Regex(@"\[([^\[\]]+)\]"); - var mc = r.Matches(cf.IKVMAssemblyAttribute); - foreach (Match m in mc) - { - options.legacyStubReferences[m.Groups[1].Value] = null; - diagnostics.StubsAreDeprecated(m.Groups[1].Value); - } - } - else - { - options.legacyStubReferences[cf.IKVMAssemblyAttribute] = null; - diagnostics.StubsAreDeprecated(cf.IKVMAssemblyAttribute); - } - - return true; + return resourcesJar != -1 && jars[resourcesJar] == jar; } - static bool IsExcludedOrStubLegacy(RuntimeContext context, StaticCompiler compiler, ImportState options, IDiagnosticHandler diagnostics, ZipArchiveEntry ze, byte[] data) + internal bool IsExcludedClass(string className) { - if (ze.Name.EndsWith(".class", StringComparison.OrdinalIgnoreCase)) - { - try - { - var name = IKVM.Runtime.ClassFile.GetClassName(data, 0, data.Length, out var stub); - if (options.IsExcludedClass(name) || (stub && EmitStubWarning(context, compiler, options, diagnostics, data))) - { - // we use stubs to add references, but otherwise ignore them + if (classesToExclude != null) + for (int i = 0; i < classesToExclude.Length; i++) + if (Regex.IsMatch(className, classesToExclude[i])) return true; - } - } - catch (ClassFormatError) - { - - } - } return false; } - void ProcessManifest(StaticCompiler compiler, ImportState options, ZipArchiveEntry ze) - { - if (manifestMainClass == null) - { - // read main class from manifest - // TODO find out if we can use other information from manifest - using Stream stream = ze.Open(); - using StreamReader rdr = new StreamReader(stream); - string line; - while ((line = rdr.ReadLine()) != null) - { - if (line.StartsWith("Main-Class: ")) - { - line = line.Substring(12); - string continuation; - while ((continuation = rdr.ReadLine()) != null - && continuation.StartsWith(" ", StringComparison.Ordinal)) - { - line += continuation.Substring(1); - } - manifestMainClass = line.Replace('/', '.'); - break; - } - } - } - } - - bool ProcessZipFile(RuntimeContext context, StaticCompiler compiler, ImportState options, IDiagnosticHandler diagnostics, string file, Predicate filter) - { - try - { - using var zf = ZipFile.OpenRead(file); - - bool found = false; - Jar jar = null; - foreach (var ze in zf.Entries) - { - if (filter != null && !filter(ze)) - { - // skip - } - else - { - found = true; - var data = ReadFromZip(ze); - if (IsExcludedOrStubLegacy(context, compiler, options, diagnostics, ze, data)) - { - continue; - } - if (jar == null) - { - jar = options.GetJar(file); - } - jar.Add(ze.FullName, data); - if (string.Equals(ze.FullName, "META-INF/MANIFEST.MF", StringComparison.OrdinalIgnoreCase)) - { - ProcessManifest(compiler, options, ze); - } - } - } - - // include empty zip file - if (!found) - { - options.GetJar(file); - } - - return found; - } - catch (InvalidDataException x) - { - throw new FatalCompilerErrorException(DiagnosticEvent.ErrorReadingFile(file, x.Message)); - } - } - - void ProcessFile(RuntimeContext context, StaticCompiler compiler, ImportState options, IDiagnosticHandler diagnostics, DirectoryInfo baseDir, string file) - { - var fileInfo = GetFileInfo(file); - if (fileInfo.Extension.Equals(".jar", StringComparison.OrdinalIgnoreCase) || fileInfo.Extension.Equals(".zip", StringComparison.OrdinalIgnoreCase)) - { - ProcessZipFile(context, compiler, options, diagnostics, file, null); - } - else - { - if (fileInfo.Extension.Equals(".class", StringComparison.OrdinalIgnoreCase)) - { - byte[] data = ReadAllBytes(fileInfo); - try - { - var name = IKVM.Runtime.ClassFile.GetClassName(data, 0, data.Length, out var stub); - if (options.IsExcludedClass(name)) - return; - - // we use stubs to add references, but otherwise ignore them - if (stub && EmitStubWarning(context, compiler, options, diagnostics, data)) - return; - - options.GetClassesJar().Add(name.Replace('.', '/') + ".class", data, fileInfo); - return; - } - catch (ClassFormatError x) - { - diagnostics.ClassFormatError(file, x.Message); - } - } - - if (baseDir == null) - { - diagnostics.UnknownFileType(file); - } - else - { - // include as resource - // extract the resource name by chopping off the base directory - var name = file.Substring(baseDir.FullName.Length); - name = name.TrimStart(Path.DirectorySeparatorChar).Replace('\\', '/'); - options.GetResourcesJar().Add(name, ReadAllBytes(fileInfo), fileInfo); - } - } - } - - bool Recurse(RuntimeContext context, StaticCompiler compiler, ImportState options, IDiagnosticHandler diagnostics, DirectoryInfo baseDir, DirectoryInfo dir, string spec) - { - bool found = false; - - foreach (var file in dir.GetFiles(spec)) - { - found = true; - ProcessFile(context, compiler, options, diagnostics, baseDir, file.FullName); - } - - foreach (var sub in dir.GetDirectories()) - { - found |= Recurse(context, compiler, options, diagnostics, baseDir, sub, spec); - } - - return found; - } - - bool RecurseJar(RuntimeContext context, StaticCompiler compiler, ImportState options, IDiagnosticHandler diagnostics, string path) - { - var file = ""; - for (; ; ) - { - file = Path.Combine(Path.GetFileName(path), file); - path = Path.GetDirectoryName(path); - if (Directory.Exists(path)) - { - throw new DirectoryNotFoundException(); - } - else if (File.Exists(path)) - { - var pathFilter = Path.GetDirectoryName(file) + Path.DirectorySeparatorChar; - var fileFilter = "^" + Regex.Escape(Path.GetFileName(file)).Replace("\\*", ".*").Replace("\\?", ".") + "$"; - - return ProcessZipFile(context, compiler, options, diagnostics, path, delegate (ZipArchiveEntry ze) - { - // MONOBUG Path.GetDirectoryName() doesn't normalize / to \ on Windows - var name = ze.FullName.Replace('/', Path.DirectorySeparatorChar); - return (Path.GetDirectoryName(name) + Path.DirectorySeparatorChar).StartsWith(pathFilter) && Regex.IsMatch(Path.GetFileName(ze.FullName), fileFilter); - }); - } - } - } - - //This processes an exclusion file with a single regular expression per line - private static void ProcessExclusionFile(ref string[] classesToExclude, string filename) - { - try - { - var list = classesToExclude == null ? new List() : new List(classesToExclude); - using (var file = new StreamReader(filename)) - { - string line; - while ((line = file.ReadLine()) != null) - { - line = line.Trim(); - if (!line.StartsWith("//") && line.Length != 0) - { - list.Add(line); - } - } - } - - classesToExclude = list.ToArray(); - } - catch (Exception x) - { - throw new FatalCompilerErrorException(DiagnosticEvent.ErrorReadingFile(filename, x.Message)); - } - } - - static void ProcessAttributeAnnotationsClass(RuntimeContext context, IDiagnosticHandler diagnostics, ref object[] annotations, string filename) - { - try - { - using var file = File.OpenRead(filename); - var cf = new IKVM.Runtime.ClassFile(context, diagnostics, IKVM.ByteCode.Decoding.ClassFile.Read(file), null, ClassFileParseOptions.None, null); - ArrayAppend(ref annotations, cf.Annotations); - } - catch (Exception x) - { - throw new FatalCompilerErrorException(DiagnosticEvent.ErrorReadingFile(filename, x.Message)); - } - } - - internal static void HandleWarnArg(ICollection target, string arg) - { - foreach (var w in arg.Split(',')) - { - // Strip IKVM prefix - int prefixStart = w.StartsWith("IKVM", StringComparison.OrdinalIgnoreCase) ? 4 : 0; - int contextIndex = w.IndexOf(':', prefixStart); - string context = string.Empty; - string parse; - if (contextIndex != -1) - { - // context includes ':' separator - context = w.Substring(contextIndex); - parse = w.Substring(prefixStart, contextIndex - prefixStart); - } - else - { - parse = w.Substring(prefixStart); - } - - if (!int.TryParse(parse, out var intResult)) - { - // NamedResults aren't supported - continue; // silently continue - } - - target.Add($"{intResult}{context}"); - } - } - } -} +} \ No newline at end of file diff --git a/src/IKVM.Tools.Importer/ImportContextFactory.cs b/src/IKVM.Tools.Importer/ImportContextFactory.cs new file mode 100644 index 000000000..ad514c740 --- /dev/null +++ b/src/IKVM.Tools.Importer/ImportContextFactory.cs @@ -0,0 +1,1096 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Compression; +using System.Linq; +using System.Text.RegularExpressions; +using System.Threading; + +using IKVM.ByteCode; +using IKVM.CoreLib.Diagnostics; +using IKVM.Reflection; +using IKVM.Runtime; +using IKVM.Tools.Core.Diagnostics; + +namespace IKVM.Tools.Importer +{ + + /// + /// Processes a hierarchy set of s into a hierarchal set of instances. + /// + class ImportContextFactory + { + + /// + /// for the importer. + /// + class CompilerOptionsDiagnosticHandler : FormattedDiagnosticHandler + { + + readonly ImportContext _options; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + public CompilerOptionsDiagnosticHandler(ImportContext options, string spec, DiagnosticFormatterProvider formatters) : + base(spec, formatters) + { + _options = options ?? throw new ArgumentNullException(nameof(options)); + } + + /// + public override bool IsEnabled(Diagnostic diagnostic) + { + return diagnostic.Level is not DiagnosticLevel.Trace and not DiagnosticLevel.Info; + } + + /// + public override void Report(in DiagnosticEvent @event) + { + if (IsEnabled(@event.Diagnostic) == false) + return; + + var key = @event.Diagnostic.Id.ToString(); + for (int i = 0; ; i++) + { + if (_options.suppressWarnings.Contains(key)) + return; + + if (i == @event.Args.Length) + break; + + key += ":" + @event.Args[i]; + } + + _options.suppressWarnings.Add(key); + + base.Report(@event); + } + + } + + readonly RuntimeContext runtime; + readonly ImportAssemblyResolver resolver; + readonly StaticCompiler compiler; + readonly IDiagnosticHandler diagnostics; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + /// + public ImportContextFactory(RuntimeContext runtime, ImportAssemblyResolver resolver, StaticCompiler compiler, IDiagnosticHandler diagnostics) + { + this.runtime = runtime ?? throw new ArgumentNullException(nameof(runtime)); + this.resolver = resolver ?? throw new ArgumentNullException(nameof(resolver)); + this.compiler = compiler ?? throw new ArgumentNullException(nameof(compiler)); + this.diagnostics = diagnostics ?? throw new ArgumentNullException(nameof(diagnostics)); + } + + /// + /// Creates a hierarchy of instances that represent the compilation from a root options. + /// + /// + /// + public List Create(ImportOptions options) + { + if (options is null) + throw new ArgumentNullException(nameof(options)); + + var imports = new List(); + + // create root import context + var import = new ImportContext(); + import.target = IKVM.CoreLib.Symbols.Emit.PEFileKinds.ConsoleApplication; + import.guessFileKind = true; + import.version = new Version(0, 0, 0, 0); + import.apartment = ApartmentState.STA; + import.props = new Dictionary(); + Create(options, import, imports); + ResolveReferences(imports); + ResolveStrongNameKeys(imports); + return imports; + } + + /// + /// Creates a hierarchy of instances that represent the compilation. + /// + /// + /// + /// + /// + void Create(ImportOptions options, ImportContext import, List targets) + { + if (options.Output != null) + import.path = options.Output; + + if (options.AssemblyName != null) + import.assembly = options.AssemblyName; + + switch (options.Target) + { + case ImportTarget.Exe: + import.target = IKVM.CoreLib.Symbols.Emit.PEFileKinds.ConsoleApplication; + import.guessFileKind = false; + break; + case ImportTarget.WinExe: + import.target = IKVM.CoreLib.Symbols.Emit.PEFileKinds.WindowApplication; + import.guessFileKind = false; + break; + case ImportTarget.Module: + import.targetIsModule = true; + import.target = IKVM.CoreLib.Symbols.Emit.PEFileKinds.Dll; + import.guessFileKind = false; + break; + case ImportTarget.Library: + import.target = IKVM.CoreLib.Symbols.Emit.PEFileKinds.Dll; + import.guessFileKind = false; + break; + default: + throw new FatalCompilerErrorException(DiagnosticEvent.UnrecognizedTargetType(options.Target.ToString())); + } + + switch (options.Platform) + { + case ImportPlatform.X86: + import.pekind = System.Reflection.PortableExecutableKinds.ILOnly | System.Reflection.PortableExecutableKinds.Required32Bit; + import.imageFileMachine = IKVM.CoreLib.Symbols.ImageFileMachine.I386; + break; + case ImportPlatform.X64: + import.pekind = System.Reflection.PortableExecutableKinds.ILOnly | System.Reflection.PortableExecutableKinds.PE32Plus; + import.imageFileMachine = IKVM.CoreLib.Symbols.ImageFileMachine.AMD64; + break; + case ImportPlatform.ARM: + import.pekind = System.Reflection.PortableExecutableKinds.ILOnly; + import.imageFileMachine = IKVM.CoreLib.Symbols.ImageFileMachine.ARM; + break; + case ImportPlatform.ARM64: + import.pekind = System.Reflection.PortableExecutableKinds.ILOnly; + import.imageFileMachine = IKVM.CoreLib.Symbols.ImageFileMachine.ARM64; + break; + case ImportPlatform.AnyCpu32BitPreferred: + import.pekind = System.Reflection.PortableExecutableKinds.ILOnly | System.Reflection.PortableExecutableKinds.Preferred32Bit; + import.imageFileMachine = IKVM.CoreLib.Symbols.ImageFileMachine.Unknown; + break; + case ImportPlatform.AnyCpu: + import.pekind = System.Reflection.PortableExecutableKinds.ILOnly; + import.imageFileMachine = IKVM.CoreLib.Symbols.ImageFileMachine.Unknown; + break; + default: + throw new FatalCompilerErrorException(DiagnosticEvent.UnrecognizedPlatform(options.Platform.ToString())); + } + + switch (options.Apartment) + { + case ImportApartment.STA: + import.apartment = ApartmentState.STA; + break; + case ImportApartment.MTA: + import.apartment = ApartmentState.MTA; + break; + case ImportApartment.None: + import.apartment = ApartmentState.Unknown; + break; + default: + throw new FatalCompilerErrorException(DiagnosticEvent.UnrecognizedApartment(options.Apartment.ToString())); + } + + if (options.NoGlobbing) + import.noglobbing = true; + + if (options.Properties.Count > 0) + foreach (var kvp in options.Properties) + import.props[kvp.Key] = kvp.Value; + + if (options.EnableAssertions != null) + { + if (options.EnableAssertions.Length == 0) + import.props["ikvm.assert.default"] = "true"; + else + import.props["ikvm.assert.enable"] = string.Join(";", options.EnableAssertions); + } + + if (options.DisableAssertions != null) + { + if (options.DisableAssertions.Length == 0) + import.props["ikvm.assert.default"] = "false"; + else + import.props["ikvm.assert.disable"] = string.Join(";", options.DisableAssertions); + } + + if (options.RemoveAssertions) + import.codegenoptions |= CodeGenOptions.RemoveAsserts; + + if (options.Main != null) + import.mainClass = options.Main; + + foreach (var reference in options.References) + import.unresolvedReferences.Add(reference); + + foreach (var spec in options.Recurse) + { + var exists = false; + + // MONOBUG On Mono 1.0.2, Directory.Exists throws an exception if we pass an invalid directory name + try + { + exists = Directory.Exists((string)spec); + } + catch (IOException) + { + + } + + var found = false; + if (exists) + { + var dir = new DirectoryInfo(spec); + found = Recurse(import, dir, dir, "*"); + } + else + { + try + { + var dir = new DirectoryInfo(Path.GetDirectoryName(spec)); + if (dir.Exists) + { + found = Recurse(import, dir, dir, Path.GetFileName(spec)); + } + else + { + found = RecurseJar(import, spec); + } + } + catch (PathTooLongException) + { + throw new FatalCompilerErrorException(DiagnosticEvent.PathTooLong(spec)); + } + catch (DirectoryNotFoundException) + { + throw new FatalCompilerErrorException(DiagnosticEvent.PathNotFound(spec)); + } + catch (ArgumentException) + { + throw new FatalCompilerErrorException(DiagnosticEvent.InvalidPath(spec)); + } + } + + if (!found) + throw new FatalCompilerErrorException(DiagnosticEvent.FileNotFound(spec)); + } + + foreach (var kvp in options.Resources) + { + var fileInfo = GetFileInfo(kvp.Value.FullName); + var fileName = kvp.Key.TrimStart('/').TrimEnd('/'); + import.GetResourcesJar().Add(fileName, ReadAllBytes(fileInfo), fileInfo); + } + + foreach (var kvp in options.ExternalResources) + { + if (!File.Exists(kvp.Value.FullName)) + throw new FatalCompilerErrorException(DiagnosticEvent.ExternalResourceNotFound(kvp.Value.FullName)); + if (Path.GetFileName(kvp.Value.FullName) != kvp.Value.FullName) + throw new FatalCompilerErrorException(DiagnosticEvent.ExternalResourceNameInvalid(kvp.Value.FullName)); + + // TODO resource name clashes should be tested + import.externalResources ??= new Dictionary(); + import.externalResources.Add(kvp.Key, kvp.Value.FullName); + } + + if (options.NoJNI) + import.codegenoptions |= CodeGenOptions.NoJNI; + + if (options.Exclude != null) + ProcessExclusionFile(ref import.classesToExclude, options.Exclude.FullName); + + if (options.Version != null) + import.version = options.Version; + + if (options.FileVersion != null) + import.fileversion = options.FileVersion.ToString(); + + if (options.Win32Icon != null) + import.iconfile = GetFileInfo(options.Win32Icon.FullName); + + if (options.Win32Manifest != null) + import.manifestFile = GetFileInfo(options.Win32Manifest.FullName); + + if (options.KeyFile != null) + import.keyfile = GetFileInfo(options.KeyFile.FullName); + + if (options.Key != null) + import.keycontainer = options.Key; + + if (options.DelaySign) + import.delaysign = true; + + switch (options.Debug) + { + case ImportDebug.Full: + import.codegenoptions |= CodeGenOptions.EmitSymbols; + import.debugMode = DebugMode.Full; + break; + case ImportDebug.Portable: + import.codegenoptions |= CodeGenOptions.EmitSymbols; + import.debugMode = DebugMode.Portable; + break; + case ImportDebug.Embedded: + import.codegenoptions |= CodeGenOptions.EmitSymbols; + import.debugMode = DebugMode.Embedded; + break; + } + + if (options.Optimize == false) + import.codegenoptions |= CodeGenOptions.DisableOptimizations; + + if (options.SourcePath != null) + import.sourcepath = options.SourcePath.FullName; + + if (options.Remap != null) + import.remapfile = GetFileInfo(options.Remap.FullName); + + if (options.NoStackTraceInfo) + import.codegenoptions |= CodeGenOptions.NoStackTraceInfo; + + if (options.RemoveUnusedPrivateFields) + import.codegenoptions |= CodeGenOptions.RemoveUnusedFields; + + if (options.CompressResources) + import.compressedResources = true; + + if (options.StrictFinalFieldSemantics) + import.codegenoptions |= CodeGenOptions.StrictFinalFieldSemantics; + + if (options.PrivatePackages != null) + foreach (var prefix in options.PrivatePackages) + import.privatePackages = [.. import.privatePackages, prefix]; + + if (options.PublicPackages != null) + foreach (var prefix in options.PublicPackages) + import.publicPackages = [.. import.privatePackages, prefix]; + + if (options.NoWarn != null) + foreach (var diagnostic in options.NoWarn) + import.suppressWarnings.Add($"IKVM{diagnostic.Id:D4}"); + + // TODO handle specific diagnostic IDs + if (options.WarnAsError != null) + { + if (options.WarnAsError.Length == 0) + import.warnaserror = true; + else + foreach (var i in options.WarnAsError) + import.errorWarnings.Add($"IKVM{i.Id:D4}"); + } + + if (options.ClassLoader != null) + import.classLoader = options.ClassLoader; + + if (options.SharedClassLoader) + import.sharedclassloader ??= new List(); + + if (options.BaseAddress != null) + { + var baseAddress = options.BaseAddress; + ulong baseAddressParsed; + if (baseAddress.StartsWith("0x", StringComparison.OrdinalIgnoreCase)) + baseAddressParsed = ulong.Parse(baseAddress.Substring(2), System.Globalization.NumberStyles.AllowHexSpecifier); + else + baseAddressParsed = ulong.Parse(baseAddress); // note that unlike CSC we don't support octal + + import.baseAddress = (baseAddressParsed & 0xFFFFFFFFFFFF0000UL); + } + + if (options.FileAlign != null) + { + if (!uint.TryParse(options.FileAlign, out var filealign) || filealign < 512 || filealign > 8192 || (filealign & (filealign - 1)) != 0) + throw new FatalCompilerErrorException(DiagnosticEvent.InvalidFileAlignment(options.FileAlign)); + + import.fileAlignment = filealign; + } + + if (options.NoPeerCrossReference) + import.crossReferenceAllPeers = false; + + if (options.NoAutoSerialization) + import.codegenoptions |= CodeGenOptions.NoAutomagicSerialization; + + if (options.HighEntropyVA) + import.highentropyva = true; + + if (options.Proxies != null) + { + foreach (var proxy in options.Proxies) + { + if (import.proxies.Contains(proxy)) + diagnostics.DuplicateProxy(proxy); + + import.proxies.Add(proxy); + } + } + + if (options.AllowNonVirtualCalls) + JVM.AllowNonVirtualCalls = true; + + if (options.Static) + { + // we abuse -static to also enable support for NoRefEmit scenarios + import.codegenoptions |= CodeGenOptions.DisableDynamicBinding | CodeGenOptions.NoRefEmitHelpers; + } + + if (options.NoJarStubs) // undocumented temporary option to mitigate risk + import.nojarstubs = true; + + if (options.AssemblyAttributes != null) + foreach (var i in options.AssemblyAttributes) + ProcessAttributeAnnotationsClass(import.assemblyAttributeAnnotations, i.FullName); + + if (options.WarningLevel4Option) // undocumented option to always warn if a class isn't found + import.warningLevelHigh = true; + + if (options.NoParameterReflection) // undocumented option to compile core class libraries with, to disable MethodParameter attribute + import.noParameterReflection = true; + + if (options.Bootstrap) + import.bootstrap = true; + + if (import.targetIsModule && import.sharedclassloader != null) + throw new FatalCompilerErrorException(DiagnosticEvent.SharedClassLoaderCannotBeUsedOnModuleTarget()); + + ReadFiles(import, options.Inputs.Select(i => i.FullName).ToList()); + + // process nested options + foreach (var nestedOptions in options.Nested) + { + var nestedImport = new ImportContext(); + nestedImport.manifestMainClass = import.manifestMainClass; + nestedImport.defaultAssemblyName = import.defaultAssemblyName; + Create(nestedOptions, nestedImport, targets); + } + + if (import.assembly == null) + { + var basename = import.path == null ? import.defaultAssemblyName : import.path.Name; + if (basename == null) + throw new FatalCompilerErrorException(DiagnosticEvent.NoOutputFileSpecified()); + + int idx = basename.LastIndexOf('.'); + if (idx > 0) + import.assembly = basename.Substring(0, idx); + else + import.assembly = basename; + } + + if (import.path != null && import.guessFileKind) + { + if (import.path.Extension.Equals(".dll", StringComparison.OrdinalIgnoreCase)) + import.target = IKVM.CoreLib.Symbols.Emit.PEFileKinds.Dll; + + import.guessFileKind = false; + } + + if (import.mainClass == null && import.manifestMainClass != null && (import.guessFileKind || import.target != IKVM.CoreLib.Symbols.Emit.PEFileKinds.Dll)) + { + diagnostics.MainMethodFromManifest(import.manifestMainClass); + import.mainClass = import.manifestMainClass; + } + + // schedule run if leaf-node + if (options.Nested == null || options.Nested.Length == 0) + targets.Add(import); + } + + /// + /// Resolves the intra-peer references in the list of imports. + /// + /// + /// + void ResolveReferences(List imports) + { + var cache = new Dictionary(); + + foreach (var import in imports) + { + if (import.unresolvedReferences.Count > 0) + { + var refs = new List(); + var cont = true; + + foreach (var reference in import.unresolvedReferences) + { + if (cont == false) + break; + + foreach (var peer in imports) + { + if (peer.assembly.Equals(reference, StringComparison.OrdinalIgnoreCase)) + { + import.peerReferences = [.. import.peerReferences, peer.assembly]; + cont = false; + break; + } + } + + if (resolver.ResolveReference(cache, refs, reference) == false) + throw new FatalCompilerErrorException(DiagnosticEvent.ReferenceNotFound(reference)); + } + + // transform references into symbols + foreach (var a in refs) + import.references.Add(runtime.Resolver.ImportAssembly(a)); + } + + } + + + // verify that we didn't reference any secondary assemblies of a shared class loader group + foreach (var import in imports) + { + if (import.references != null) + { + foreach (var asm in import.references) + { + var forwarder = asm.GetType("__"); + if (forwarder != null && forwarder.Assembly != asm) + diagnostics.NonPrimaryAssemblyReference(asm.Location, forwarder.Assembly.GetName().Name); + } + } + } + + // now pre-load the secondary assemblies of any shared class loader groups + foreach (var import in imports) + if (import.references != null) + foreach (var asm in import.references) + RuntimeAssemblyClassLoader.PreloadExportedAssemblies(compiler, asm); + } + + /// + /// Resolves any strong name keys. + /// + /// + /// + void ResolveStrongNameKeys(List targets) + { + foreach (var options in targets) + { + if (options.keyfile != null && options.keycontainer != null) + throw new FatalCompilerErrorException(DiagnosticEvent.CannotSpecifyBothKeyFileAndContainer()); + + if (options.keyfile == null && options.keycontainer == null && options.delaysign) + throw new FatalCompilerErrorException(DiagnosticEvent.DelaySignRequiresKey()); + + if (options.keyfile != null) + { + if (options.delaysign) + { + var buf = ReadAllBytes(options.keyfile); + try + { + // maybe it is a key pair, if so we need to extract just the public key + buf = new StrongNameKeyPair(buf).PublicKey; + } + catch + { + + } + + options.publicKey = buf; + } + else + { + SetStrongNameKeyPair(ref options.keyPair, options.keyfile, null); + } + } + else if (options.keycontainer != null) + { + StrongNameKeyPair keyPair = null; + SetStrongNameKeyPair(ref keyPair, null, options.keycontainer); + if (options.delaysign) + options.publicKey = keyPair.PublicKey; + else + options.keyPair = keyPair; + } + } + } + + static internal byte[] ReadAllBytes(FileInfo path) + { + try + { + return File.ReadAllBytes(path.FullName); + } + catch (Exception x) + { + throw new FatalCompilerErrorException(DiagnosticEvent.ErrorReadingFile(path.ToString(), x.Message)); + } + } + + static internal FileInfo GetFileInfo(string path) + { + try + { + var fileInfo = new FileInfo(path); + if (fileInfo.Directory == null) + { + // this happens with an incorrect unc path (e.g. "\\foo\bar") + throw new FatalCompilerErrorException(DiagnosticEvent.InvalidPath(path)); + } + return fileInfo; + } + catch (ArgumentException) + { + throw new FatalCompilerErrorException(DiagnosticEvent.InvalidPath(path)); + } + catch (NotSupportedException) + { + throw new FatalCompilerErrorException(DiagnosticEvent.InvalidPath(path)); + } + catch (PathTooLongException) + { + throw new FatalCompilerErrorException(DiagnosticEvent.PathTooLong(path)); + } + catch (UnauthorizedAccessException) + { + // this exception does not appear to be possible + throw new FatalCompilerErrorException(DiagnosticEvent.InvalidPath(path)); + } + } + + void ReadFiles(ImportContext import, List fileNames) + { + foreach (var fileName in fileNames) + { + if (import.defaultAssemblyName == null) + { + try + { + import.defaultAssemblyName = new FileInfo(Path.GetFileName(fileName)).Name; + } + catch (ArgumentException) + { + // if the filename contains a wildcard (or any other invalid character), we ignore + // it as a potential default assembly name + } + catch (NotSupportedException) + { + + } + catch (PathTooLongException) + { + + } + } + + string[] files = null; + try + { + var path = Path.GetDirectoryName(fileName); + files = Directory.GetFiles(path == "" ? "." : path, Path.GetFileName(fileName)); + } + catch + { + + } + + + if (files == null || files.Length == 0) + { + diagnostics.InputFileNotFound(fileName); + } + else + { + foreach (var f in files) + { + ProcessFile(import, null, f); + } + } + } + } + + static internal bool TryParseVersion(string str, out Version version) + { + if (str.EndsWith(".*")) + { + str = str.Substring(0, str.Length - 1); + int count = str.Split('.').Length; + // NOTE this is the published algorithm for generating automatic build and revision numbers + // (see AssemblyVersionAttribute constructor docs), but it turns out that the revision + // number is off an hour (on my system)... + var now = DateTime.Now; + int seconds = (int)(now.TimeOfDay.TotalSeconds / 2); + int days = (int)(now - new DateTime(2000, 1, 1)).TotalDays; + if (count == 3) + { + str += days + "." + seconds; + } + else if (count == 4) + { + str += seconds; + } + else + { + version = null; + return false; + } + } + try + { + version = new Version(str); + return version.Major <= 65535 && version.Minor <= 65535 && version.Build <= 65535 && version.Revision <= 65535; + } + catch (ArgumentException) + { + + } + catch (FormatException) + { + + } + catch (OverflowException) + { + + } + + version = null; + return false; + } + + void SetStrongNameKeyPair(ref StrongNameKeyPair strongNameKeyPair, FileInfo keyFile, string keyContainer) + { + try + { + if (keyFile != null) + strongNameKeyPair = new StrongNameKeyPair(ReadAllBytes(keyFile)); + else + strongNameKeyPair = new StrongNameKeyPair(keyContainer); + + // FXBUG we explicitly try to access the public key force a check (the StrongNameKeyPair constructor doesn't validate the key) + if (strongNameKeyPair.PublicKey != null) + { + + } + } + catch (Exception e) + { + throw new FatalCompilerErrorException(DiagnosticEvent.InvalidStrongNameKeyPair(keyFile != null ? "file" : "container", e.Message)); + } + } + + byte[] ReadFromZip(ZipArchiveEntry ze) + { + using MemoryStream ms = new MemoryStream(); + using Stream s = ze.Open(); + s.CopyTo(ms); + return ms.ToArray(); + } + + bool EmitStubWarning(ImportContext import, byte[] buf) + { + IKVM.Runtime.ClassFile cf; + + try + { + cf = new IKVM.Runtime.ClassFile(runtime, diagnostics, IKVM.ByteCode.Decoding.ClassFile.Read(buf), "", ClassFileParseOptions.None, null); + } + catch (ClassFormatError) + { + return false; + } + catch (ByteCodeException) + { + return false; + } + + if (cf.IKVMAssemblyAttribute == null) + { + return false; + } + + if (cf.IKVMAssemblyAttribute.StartsWith("[[")) + { + var r = new Regex(@"\[([^\[\]]+)\]"); + var mc = r.Matches(cf.IKVMAssemblyAttribute); + foreach (Match m in mc) + { + import.legacyStubReferences[m.Groups[1].Value] = null; + diagnostics.StubsAreDeprecated(m.Groups[1].Value); + } + } + else + { + import.legacyStubReferences[cf.IKVMAssemblyAttribute] = null; + diagnostics.StubsAreDeprecated(cf.IKVMAssemblyAttribute); + } + + return true; + } + + bool IsExcludedOrStubLegacy(ImportContext import, ZipArchiveEntry ze, byte[] data) + { + if (ze.Name.EndsWith(".class", StringComparison.OrdinalIgnoreCase)) + { + try + { + var name = IKVM.Runtime.ClassFile.GetClassName(data, 0, data.Length, out var stub); + if (import.IsExcludedClass(name) || (stub && EmitStubWarning(import, data))) + { + // we use stubs to add references, but otherwise ignore them + return true; + } + } + catch (ClassFormatError) + { + + } + } + + return false; + } + + void ProcessManifest(ImportContext import, ZipArchiveEntry ze) + { + if (import.manifestMainClass == null) + { + // read main class from manifest + // TODO find out if we can use other information from manifest + using Stream stream = ze.Open(); + using StreamReader rdr = new StreamReader(stream); + string line; + while ((line = rdr.ReadLine()) != null) + { + if (line.StartsWith("Main-Class: ")) + { + line = line.Substring(12); + string continuation; + while ((continuation = rdr.ReadLine()) != null + && continuation.StartsWith(" ", StringComparison.Ordinal)) + { + line += continuation.Substring(1); + } + + import.manifestMainClass = line.Replace('/', '.'); + break; + } + } + } + } + + bool ProcessZipFile(ImportContext import, string file, Predicate filter) + { + try + { + using var zf = ZipFile.OpenRead(file); + + bool found = false; + Jar jar = null; + foreach (var ze in zf.Entries) + { + if (filter != null && !filter(ze)) + { + // skip + } + else + { + found = true; + var data = ReadFromZip(ze); + if (IsExcludedOrStubLegacy(import, ze, data)) + { + continue; + } + if (jar == null) + { + jar = import.GetJar(file); + } + jar.Add(ze.FullName, data); + if (string.Equals(ze.FullName, "META-INF/MANIFEST.MF", StringComparison.OrdinalIgnoreCase)) + { + ProcessManifest(import, ze); + } + } + } + + // include empty zip file + if (!found) + { + import.GetJar(file); + } + + return found; + } + catch (InvalidDataException x) + { + throw new FatalCompilerErrorException(DiagnosticEvent.ErrorReadingFile(file, x.Message)); + } + } + + void ProcessFile(ImportContext import, DirectoryInfo baseDir, string file) + { + var fileInfo = GetFileInfo(file); + if (fileInfo.Extension.Equals(".jar", StringComparison.OrdinalIgnoreCase) || fileInfo.Extension.Equals(".zip", StringComparison.OrdinalIgnoreCase)) + { + ProcessZipFile(import, file, null); + } + else + { + if (fileInfo.Extension.Equals(".class", StringComparison.OrdinalIgnoreCase)) + { + byte[] data = ReadAllBytes(fileInfo); + try + { + var name = IKVM.Runtime.ClassFile.GetClassName(data, 0, data.Length, out var stub); + if (import.IsExcludedClass(name)) + return; + + // we use stubs to add references, but otherwise ignore them + if (stub && EmitStubWarning(import, data)) + return; + + import.GetClassesJar().Add(name.Replace('.', '/') + ".class", data, fileInfo); + return; + } + catch (ClassFormatError x) + { + diagnostics.ClassFormatError(file, x.Message); + } + } + + if (baseDir == null) + { + diagnostics.UnknownFileType(file); + } + else + { + // include as resource + // extract the resource name by chopping off the base directory + var name = file.Substring(baseDir.FullName.Length); + name = name.TrimStart(Path.DirectorySeparatorChar).Replace('\\', '/'); + import.GetResourcesJar().Add(name, ReadAllBytes(fileInfo), fileInfo); + } + } + } + + bool Recurse(ImportContext import, DirectoryInfo baseDir, DirectoryInfo dir, string spec) + { + bool found = false; + + foreach (var file in dir.GetFiles(spec)) + { + found = true; + ProcessFile(import, baseDir, file.FullName); + } + + foreach (var sub in dir.GetDirectories()) + { + found |= Recurse(import, baseDir, sub, spec); + } + + return found; + } + + bool RecurseJar(ImportContext import, string path) + { + var file = ""; + for (; ; ) + { + file = Path.Combine(Path.GetFileName(path), file); + path = Path.GetDirectoryName(path); + if (Directory.Exists(path)) + { + throw new DirectoryNotFoundException(); + } + else if (File.Exists(path)) + { + var pathFilter = Path.GetDirectoryName(file) + Path.DirectorySeparatorChar; + var fileFilter = "^" + Regex.Escape(Path.GetFileName(file)).Replace("\\*", ".*").Replace("\\?", ".") + "$"; + + return ProcessZipFile(import, path, delegate (ZipArchiveEntry ze) + { + // MONOBUG Path.GetDirectoryName() doesn't normalize / to \ on Windows + var name = ze.FullName.Replace('/', Path.DirectorySeparatorChar); + return (Path.GetDirectoryName(name) + Path.DirectorySeparatorChar).StartsWith(pathFilter) && Regex.IsMatch(Path.GetFileName(ze.FullName), fileFilter); + }); + } + } + } + + //This processes an exclusion file with a single regular expression per line + void ProcessExclusionFile(ref string[] classesToExclude, string filename) + { + try + { + var list = classesToExclude == null ? new List() : new List(classesToExclude); + using (var file = new StreamReader(filename)) + { + string line; + while ((line = file.ReadLine()) != null) + { + line = line.Trim(); + if (!line.StartsWith("//") && line.Length != 0) + { + list.Add(line); + } + } + } + + classesToExclude = list.ToArray(); + } + catch (Exception x) + { + throw new FatalCompilerErrorException(DiagnosticEvent.ErrorReadingFile(filename, x.Message)); + } + } + + void ProcessAttributeAnnotationsClass(List annotations, string filename) + { + try + { + using var file = File.OpenRead(filename); + var cf = new IKVM.Runtime.ClassFile(runtime, diagnostics, IKVM.ByteCode.Decoding.ClassFile.Read(file), null, ClassFileParseOptions.None, null); + annotations.AddRange(cf.Annotations); + } + catch (Exception x) + { + throw new FatalCompilerErrorException(DiagnosticEvent.ErrorReadingFile(filename, x.Message)); + } + } + + void HandleWarnArg(ICollection target, string arg) + { + foreach (var w in arg.Split(',')) + { + // Strip IKVM prefix + int prefixStart = w.StartsWith("IKVM", StringComparison.OrdinalIgnoreCase) ? 4 : 0; + int contextIndex = w.IndexOf(':', prefixStart); + string context = string.Empty; + string parse; + if (contextIndex != -1) + { + // context includes ':' separator + context = w.Substring(contextIndex); + parse = w.Substring(prefixStart, contextIndex - prefixStart); + } + else + { + parse = w.Substring(prefixStart); + } + + if (!int.TryParse(parse, out var intResult)) + { + // NamedResults aren't supported + continue; // silently continue + } + + target.Add($"{intResult}{context}"); + } + } + + } + +} diff --git a/src/IKVM.Tools.Importer/ImportRuntimeSymbolResolver.cs b/src/IKVM.Tools.Importer/ImportRuntimeSymbolResolver.cs index 7f3eeecb8..927dbfc67 100644 --- a/src/IKVM.Tools.Importer/ImportRuntimeSymbolResolver.cs +++ b/src/IKVM.Tools.Importer/ImportRuntimeSymbolResolver.cs @@ -22,7 +22,10 @@ Jeroen Frijters */ using System; +using System.IO; +using System.Threading; +using IKVM.CoreLib.Diagnostics; using IKVM.CoreLib.Symbols; using IKVM.CoreLib.Symbols.Emit; using IKVM.CoreLib.Symbols.IkvmReflection; @@ -38,104 +41,178 @@ namespace IKVM.Tools.Importer class ImportRuntimeSymbolResolver : IRuntimeSymbolResolver { - readonly StaticCompiler compiler; - readonly IkvmReflectionSymbolContext context; + readonly IDiagnosticHandler diagnostics; + readonly Universe universe; + readonly IkvmReflectionSymbolContext symbols; + readonly ImportOptions options; + IAssemblySymbol runtimeAssembly; + IAssemblySymbol baseAssembly; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + /// + public ImportRuntimeSymbolResolver(IDiagnosticHandler diagnostics, Universe universe, IkvmReflectionSymbolContext symbols, ImportOptions options) + { + this.diagnostics = diagnostics ?? throw new ArgumentNullException(nameof(diagnostics)); + this.universe = universe ?? throw new ArgumentNullException(nameof(universe)); + this.symbols = symbols ?? throw new ArgumentNullException(nameof(symbols)); + this.options = options ?? throw new ArgumentNullException(nameof(options)); + } + + /// + public ISymbolContext Symbols => symbols; + + /// + public IAssemblySymbol ResolveCoreAssembly() + { + try + { + if (ImportAssembly(universe.CoreLib) is { } a) + return a; + } + catch (FileNotFoundException) + { + + } + + throw new FatalCompilerErrorException(DiagnosticEvent.CoreClassesMissing()); + } /// - public ISymbolContext Symbols => context; + public IAssemblySymbol ResolveRuntimeAssembly() + { + if (runtimeAssembly == null) + Interlocked.CompareExchange(ref runtimeAssembly, LoadRuntimeAssembly(), null); + + return runtimeAssembly; + } /// - /// Initializes a new instance. + /// Attempts to load the runtime assembly. /// - /// - public ImportRuntimeSymbolResolver(StaticCompiler compiler) + /// + IAssemblySymbol LoadRuntimeAssembly() { - this.compiler = compiler ?? throw new ArgumentNullException(nameof(compiler)); - this.context = new IkvmReflectionSymbolContext(compiler.Universe); + foreach (var assembly in universe.GetAssemblies()) + if (assembly.GetType("IKVM.Runtime.JVM") is Type) + return ImportAssembly(assembly); + + throw new FatalCompilerErrorException(DiagnosticEvent.RuntimeNotFound()); } /// public IAssemblySymbol ResolveBaseAssembly() { - return compiler.baseAssembly; + if (baseAssembly == null) + Interlocked.CompareExchange(ref baseAssembly, LoadBaseAssembly(), null); + + return baseAssembly; } - /// - public IAssemblySymbol ResolveAssembly(string assemblyName) + /// + /// Attempts to load the base assembly. + /// + IAssemblySymbol LoadBaseAssembly() { - return compiler.Universe.Load(assemblyName) is { } a ? context.GetOrCreateAssemblySymbol(a) : null; + foreach (var assembly in universe.GetAssemblies()) + if (assembly.GetType("java.lang.Object") is Type) + return ImportAssembly(assembly); + + throw new Exception(); } /// public ITypeSymbol ResolveCoreType(string typeName) { - foreach (var assembly in compiler.Universe.GetAssemblies()) - if (assembly.GetType(typeName) is Type t) - return context.GetOrCreateTypeSymbol(t); - - return null; + return ResolveCoreAssembly().GetType(typeName); } /// public ITypeSymbol ResolveRuntimeType(string typeName) { - return compiler.GetRuntimeType(typeName); + return ResolveRuntimeAssembly().GetType(typeName); } /// - public IAssemblySymbol ResolveAssembly(Assembly assembly) + public ITypeSymbol ResolveBaseType(string typeName) { - return context.GetOrCreateAssemblySymbol(assembly); + return ResolveBaseAssembly().GetType(typeName); } /// - public IAssemblySymbolBuilder ResolveAssembly(AssemblyBuilder assembly) + public IAssemblySymbol ResolveAssembly(string assemblyName) { - return context.GetOrCreateAssemblySymbol(assembly); + return universe.Load(assemblyName) is { } a ? symbols.GetOrCreateAssemblySymbol(a) : null; } /// - public IModuleSymbol ResolveModule(Module module) + public ITypeSymbol ResolveType(string typeName) { - return context.GetOrCreateModuleSymbol(module); + foreach (var assembly in universe.GetAssemblies()) + if (assembly.GetType(typeName) is Type t) + return ImportType(t); + + return null; } /// - public IModuleSymbolBuilder ResolveModule(ModuleBuilder module) + public IAssemblySymbol ImportAssembly(Assembly assembly) { - return context.GetOrCreateModuleSymbol(module); + return symbols.GetOrCreateAssemblySymbol(assembly); } /// - public ITypeSymbol ResolveType(Type type) + public IAssemblySymbolBuilder ImportAssembly(AssemblyBuilder assembly) { - return context.GetOrCreateTypeSymbol(type); + return symbols.GetOrCreateAssemblySymbol(assembly); } /// - public IMemberSymbol ResolveMember(MemberInfo memberInfo) + public IModuleSymbol ImportModule(Module module) { - return context.GetOrCreateMemberSymbol(memberInfo); + return symbols.GetOrCreateModuleSymbol(module); } /// - public IMethodBaseSymbol ResolveMethodBase(MethodBase type) + public IModuleSymbolBuilder ImportModule(ModuleBuilder module) { - return context.GetOrCreateMethodBaseSymbol(type); + return symbols.GetOrCreateModuleSymbol(module); } /// - public IConstructorSymbol ResolveConstructor(ConstructorInfo ctor) + public ITypeSymbol ImportType(Type type) { - return context.GetOrCreateConstructorSymbol(ctor); + return symbols.GetOrCreateTypeSymbol(type); } /// - public IMethodSymbol ResolveMethod(MethodInfo method) + public IMemberSymbol ImportMember(MemberInfo memberInfo) { - return context.GetOrCreateMethodSymbol(method); + return symbols.GetOrCreateMemberSymbol(memberInfo); } + /// + public IMethodBaseSymbol ImportMethodBase(MethodBase type) + { + return symbols.GetOrCreateMethodBaseSymbol(type); + } + + /// + public IConstructorSymbol ImportConstructor(ConstructorInfo ctor) + { + return symbols.GetOrCreateConstructorSymbol(ctor); + } + + /// + public IMethodSymbol ImportMethod(MethodInfo method) + { + return symbols.GetOrCreateMethodSymbol(method); + } } } \ No newline at end of file diff --git a/src/IKVM.Tools.Importer/ImportState.cs b/src/IKVM.Tools.Importer/ImportState.cs deleted file mode 100644 index 38ef6f368..000000000 --- a/src/IKVM.Tools.Importer/ImportState.cs +++ /dev/null @@ -1,198 +0,0 @@ -/* - Copyright (C) 2002-2014 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.IO; -using System.Text.RegularExpressions; -using System.Threading; - -using IKVM.Reflection; -using IKVM.Reflection.Emit; -using IKVM.Runtime; - -namespace IKVM.Tools.Importer -{ - - /// - /// Holds some state for an instance of . - /// - sealed class ImportState - { - - internal List jars = new List(); - private Dictionary jarMap = new Dictionary(); - internal int classesJar = -1; - internal int resourcesJar = -1; - internal bool nojarstubs; - internal FileInfo path; - internal FileInfo keyfile; - internal string keycontainer; - internal bool delaysign; - internal byte[] publicKey; - internal StrongNameKeyPair keyPair; - internal Version version; - internal string fileversion; - internal FileInfo iconfile; - internal FileInfo manifestFile; - internal bool targetIsModule; - internal string assembly; - internal string mainClass; - internal ApartmentState apartment; - internal IKVM.CoreLib.Symbols.Emit.PEFileKinds target; - internal bool guessFileKind; - internal string[] unresolvedReferences; // only used during command line parsing - internal Dictionary legacyStubReferences = new Dictionary(); // only used during command line parsing - internal Assembly[] references; - internal string[] peerReferences; - internal bool crossReferenceAllPeers = true; - internal string[] classesToExclude; // only used during command line parsing - internal FileInfo remapfile; - internal Dictionary props; - internal bool noglobbing; - internal CodeGenOptions codegenoptions; - internal DebugMode debugMode = DebugMode.Portable; - internal string debugFileName; - internal bool compressedResources; - internal string[] privatePackages; - internal string[] publicPackages; - internal string sourcepath; - internal Dictionary externalResources; - internal string classLoader; - internal System.Reflection.PortableExecutableKinds pekind = System.Reflection.PortableExecutableKinds.ILOnly; - internal IKVM.CoreLib.Symbols.ImageFileMachine imageFileMachine = IKVM.CoreLib.Symbols.ImageFileMachine.I386; - internal ulong baseAddress; - internal uint fileAlignment; - internal bool highentropyva; - internal List sharedclassloader; // should *not* be deep copied in Copy(), because we want the list of all compilers that share a class loader - internal HashSet suppressWarnings = new HashSet(StringComparer.OrdinalIgnoreCase); - internal HashSet errorWarnings = new HashSet(StringComparer.OrdinalIgnoreCase); - internal bool warnaserror; // treat all warnings as errors - internal List proxies = new List(); - internal object[] assemblyAttributeAnnotations; - internal bool warningLevelHigh; - internal bool noParameterReflection; - internal bool bootstrap; - internal string log; - - internal ImportState Copy() - { - ImportState copy = (ImportState)MemberwiseClone(); - copy.jars = Copy(jars); - copy.jarMap = new Dictionary(jarMap); - if (props != null) - { - copy.props = new Dictionary(props); - } - if (externalResources != null) - { - copy.externalResources = new Dictionary(externalResources); - } - copy.suppressWarnings = new(suppressWarnings, StringComparer.OrdinalIgnoreCase); - copy.errorWarnings = new(errorWarnings, StringComparer.OrdinalIgnoreCase); - return copy; - } - - private static List Copy(List jars) - { - List newJars = new List(); - foreach (Jar jar in jars) - { - newJars.Add(jar.Copy()); - } - return newJars; - } - - internal Jar GetJar(string file) - { - if (jarMap.TryGetValue(file, out var existingJar)) - return jars[existingJar]; - - jarMap.Add(file, jars.Count); - return CreateJar(Path.GetFileName(file)); - } - - Jar CreateJar(string jarName) - { - int count = 0; - var name = jarName; - retry: - foreach (var jar in jars) - { - if (jar.Name == name) - { - name = Path.GetFileNameWithoutExtension(jarName) + "-" + (++count) + Path.GetExtension(jarName); - goto retry; - } - } - - var newJar = new Jar(name); - jars.Add(newJar); - return newJar; - } - - internal Jar GetClassesJar() - { - if (classesJar == -1) - { - classesJar = jars.Count; - CreateJar("classes.jar"); - } - - return jars[classesJar]; - } - - internal bool IsClassesJar(Jar jar) - { - return classesJar != -1 && jars[classesJar] == jar; - } - - internal Jar GetResourcesJar() - { - if (resourcesJar == -1) - { - resourcesJar = jars.Count; - CreateJar("resources.jar"); - } - - return jars[resourcesJar]; - } - - internal bool IsResourcesJar(Jar jar) - { - return resourcesJar != -1 && jars[resourcesJar] == jar; - } - - internal bool IsExcludedClass(string className) - { - if (classesToExclude != null) - for (int i = 0; i < classesToExclude.Length; i++) - if (Regex.IsMatch(className, classesToExclude[i])) - return true; - - return false; - } - - } - -} \ No newline at end of file diff --git a/src/IKVM.Tools.Importer/ImportTool.cs b/src/IKVM.Tools.Importer/ImportTool.cs index f2d840625..aa4a8e6d9 100644 --- a/src/IKVM.Tools.Importer/ImportTool.cs +++ b/src/IKVM.Tools.Importer/ImportTool.cs @@ -3,10 +3,17 @@ using System.CommandLine; using System.CommandLine.Builder; using System.CommandLine.Parsing; +using System.IO; +using System.Reflection.Metadata; +using System.Reflection.PortableExecutable; using System.Threading; using System.Threading.Tasks; using IKVM.CoreLib.Diagnostics; +using IKVM.CoreLib.Symbols.IkvmReflection; +using IKVM.Reflection; +using IKVM.Reflection.Diagnostics; +using IKVM.Runtime; using IKVM.Tools.Core.CommandLine; using IKVM.Tools.Core.Diagnostics; @@ -51,40 +58,148 @@ internal static async Task ExecuteInContext(string[] args, CancellationToke /// /// /// - static Task ExecuteAsync(ImportOptions options, IDiagnosticHandler diagnostics, CancellationToken cancellationToken = default) + async Task ExecuteImplAsync(ImportOptions options, CancellationToken cancellationToken) { - return ExecuteImplAsync(options, _ => diagnostics, cancellationToken); + var services = new ServiceCollection(); + services.AddToolsDiagnostics(); + services.AddSingleton(options); + services.AddSingleton(p => GetDiagnostics(p, p.GetRequiredService().Log)); + services.AddSingleton(p => CreateResolver(p.GetRequiredService(), p.GetRequiredService())); + services.AddSingleton(p => p.GetRequiredService().Universe); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(p => new RuntimeContextOptions(p.GetRequiredService().Bootstrap)); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + using var provider = services.BuildServiceProvider(); + + // convert options to imports + var imports = provider.GetRequiredService().Create(options); + if (imports.Count == 0) + throw new FatalCompilerErrorException(DiagnosticEvent.NoTargetsFound()); + + // execute the compiler + return await Task.Run(() => Execute( + provider.GetRequiredService(), + provider.GetRequiredService(), + provider.GetRequiredService(), + imports)); } /// - /// Executes the importer. + /// Executes the imports. /// - /// - /// - /// + /// + /// + /// + /// /// - static Task ExecuteImplAsync(ImportOptions options, Func diagnostics, CancellationToken cancellationToken) + int Execute(RuntimeContext runtime, StaticCompiler compiler, IDiagnosticHandler diagnostic, List imports) { - var services = new ServiceCollection(); - services.AddToolsDiagnostics(); - services.AddSingleton(options); - services.AddSingleton(diagnostics); - using var provider = services.BuildServiceProvider(); - return ExecuteImplAsync(options, provider, cancellationToken); + return ImportClassLoader.Compile(runtime, compiler, diagnostic, imports); } /// - /// Executes the importer. + /// Creates the universe of types. /// - /// - /// /// - static Task ExecuteImplAsync(ImportOptions options, IServiceProvider services, CancellationToken cancellationToken) + ImportAssemblyResolver CreateResolver(IDiagnosticHandler diagnostics, ImportOptions options) { - if (services is null) - throw new ArgumentNullException(nameof(services)); + if (diagnostics is null) + throw new ArgumentNullException(nameof(diagnostics)); + if (options is null) + throw new ArgumentNullException(nameof(options)); + + var universeOptions = UniverseOptions.ResolveMissingMembers | UniverseOptions.EnableFunctionPointers; + if (options.Deterministic == false) + universeOptions |= UniverseOptions.DeterministicOutput; + + // discover the core lib from the references + var coreLibName = FindCoreLibName(options.References, options.Libraries); + if (coreLibName == null) + { + diagnostics.CoreClassesMissing(); + throw new Exception(); + } + + // create a new universe of types + var universe = new Universe(universeOptions, coreLibName); + + // warn when unable to resolve a member + universe.ResolvedMissingMember += (Module requestingModule, MemberInfo member) => + { + if (requestingModule != null && member is IKVM.Reflection.Type) + diagnostics.UnableToResolveType(requestingModule.Name, ((IKVM.Reflection.Type)member).FullName, member.Module.FullyQualifiedName); + }; + + // enable embedded symbol writer + if (options.Debug == ImportDebug.Portable) + universe.SetSymbolWriterFactory(module => new PortablePdbSymbolWriter(module)); + + // universe resolver calls back into import + var resolver = new ImportAssemblyResolver(universe, options, diagnostics); + universe.AssemblyResolve += resolver.AssemblyResolve; + + return resolver; + } + + /// + /// Finds the first potential core library in the reference set. + /// + /// + /// + /// + string FindCoreLibName(IList references, IList libpaths) + { + if (references != null) + foreach (var reference in references) + if (GetAssemblyNameIfCoreLib(reference) is string coreLibName) + return coreLibName; + + if (libpaths != null) + foreach (var libpath in libpaths) + foreach (var dll in libpath.GetFiles("*.dll")) + if (GetAssemblyNameIfCoreLib(dll.FullName) is string coreLibName) + return coreLibName; + + return null; + } + + /// + /// Returns true if the given assembly is a core library. + /// + /// + /// + string GetAssemblyNameIfCoreLib(string file) + { + if (File.Exists(file) == false) + return null; + + using var st = File.OpenRead(file); + using var pe = new PEReader(st); + var mr = pe.GetMetadataReader(); + + foreach (var handle in mr.TypeDefinitions) + if (IsSystemObject(mr, handle)) + return mr.GetString(mr.GetAssemblyDefinition().Name); + + return null; + } + + /// + /// Returns true if the given type definition handle refers to "System.Object". + /// + /// + /// + /// + bool IsSystemObject(MetadataReader reader, TypeDefinitionHandle th) + { + var td = reader.GetTypeDefinition(th); + var ns = reader.GetString(td.Namespace); + var nm = reader.GetString(td.Name); - return Task.Run(() => ImportContext.Execute(options)); + return ns == "System" && nm == "Object"; } /// @@ -93,12 +208,12 @@ static Task ExecuteImplAsync(ImportOptions options, IServiceProvider servic /// /// /// - static Task ExecuteAsync(ImportOptions options, CancellationToken cancellationToken = default) + Task ExecuteAsync(ImportOptions options, CancellationToken cancellationToken = default) { if (options is null) throw new ArgumentNullException(nameof(options)); - return ExecuteImplAsync(options, p => GetDiagnostics(p, options.Log), cancellationToken); + return ExecuteImplAsync(options, cancellationToken); } /// diff --git a/src/IKVM.Tools.Importer/MapXml/Call.cs b/src/IKVM.Tools.Importer/MapXml/Call.cs index b2049a101..e6bbe85b8 100644 --- a/src/IKVM.Tools.Importer/MapXml/Call.cs +++ b/src/IKVM.Tools.Importer/MapXml/Call.cs @@ -101,7 +101,7 @@ internal sealed override void Generate(CodeGenContext context, CodeEmitter ilgen Debug.Assert(Class == null && Type != null); var argTypes = context.ClassLoader.ArgTypeListFromSig(Sig); - var ci = context.ClassLoader.Context.Resolver.ResolveCoreType(Type).GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, argTypes); + var ci = context.ClassLoader.Context.Resolver.ResolveType(Type).GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, argTypes); if (ci == null) throw new InvalidOperationException("Missing .ctor: " + Type + "..ctor" + Sig); @@ -115,9 +115,8 @@ internal sealed override void Generate(CodeGenContext context, CodeEmitter ilgen Debug.Assert(Sig != null); var method = context.ClassLoader.LoadClassByName(Class).GetMethodWrapper(Name, Sig, false); if (method == null) - { throw new InvalidOperationException("method not found: " + Class + "." + Name + Sig); - } + method.Link(); // TODO this code is part of what Compiler.CastInterfaceArgs (in compiler.cs) does, // it would be nice if we could avoid this duplication... @@ -126,7 +125,7 @@ internal sealed override void Generate(CodeGenContext context, CodeEmitter ilgen { if (argTypeWrappers[i].IsGhost) { - CodeEmitterLocal[] temps = new CodeEmitterLocal[argTypeWrappers.Length + (method.IsStatic ? 0 : 1)]; + var temps = new CodeEmitterLocal[argTypeWrappers.Length + (method.IsStatic ? 0 : 1)]; for (int j = temps.Length - 1; j >= 0; j--) { RuntimeJavaType tw; @@ -194,15 +193,13 @@ internal sealed override void Generate(CodeGenContext context, CodeEmitter ilgen argTypes = new ITypeSymbol[types.Length]; for (int i = 0; i < types.Length; i++) { - argTypes[i] = context.ClassLoader.Context.Resolver.ResolveCoreType(types[i]); + argTypes[i] = context.ClassLoader.Context.Resolver.ResolveType(types[i]); } } - var ti = context.ClassLoader.Context.Resolver.ResolveCoreType(Type); + var ti = context.ClassLoader.Context.Resolver.ResolveType(Type); if (ti == null) - { throw new InvalidOperationException("Missing type: " + Type); - } var mi = ti.GetMethod(Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static, argTypes); if (mi == null) diff --git a/src/IKVM.Tools.Importer/RuntimeImportByteCodeJavaType.cs b/src/IKVM.Tools.Importer/RuntimeImportByteCodeJavaType.cs index f6b342afd..0cad9fc1f 100644 --- a/src/IKVM.Tools.Importer/RuntimeImportByteCodeJavaType.cs +++ b/src/IKVM.Tools.Importer/RuntimeImportByteCodeJavaType.cs @@ -75,7 +75,7 @@ sealed class ConstructorForwarder : RuntimeJavaMethod readonly RuntimeJavaTypeFactory context; readonly ITypeSymbolBuilder typeBuilder; readonly RuntimeJavaMethod ctor; - IMethodSymbolBuilder constructorBuilder; + IConstructorSymbolBuilder constructorBuilder; /// /// Initializes a new instance. @@ -129,7 +129,7 @@ internal void GetParameterNamesFromXml(string methodName, string methodSig, stri parameterNames[i] = parameters[i].Name; } - internal void AddXmlMapParameterAttributes(IMethodSymbolBuilder method, string className, string methodName, string methodSig, ref IParameterSymbolBuilder[] parameterBuilders) + internal void AddXmlMapParameterAttributes(IMethodBaseSymbolBuilder method, string className, string methodName, string methodSig, ref IParameterSymbolBuilder[] parameterBuilders) { var parameters = classLoader.GetXmlMapParameters(className, methodName, methodSig); if (parameters != null) diff --git a/src/IKVM.Tools.Importer/StaticCompiler.cs b/src/IKVM.Tools.Importer/StaticCompiler.cs index 795568db5..a0ccb68cc 100644 --- a/src/IKVM.Tools.Importer/StaticCompiler.cs +++ b/src/IKVM.Tools.Importer/StaticCompiler.cs @@ -24,145 +24,46 @@ Jeroen Frijters using System; using System.Collections.Concurrent; -using System.Collections.Generic; using System.IO; -using System.Reflection.Metadata; -using System.Reflection.PortableExecutable; using IKVM.CoreLib.Diagnostics; using IKVM.CoreLib.Symbols; using IKVM.CoreLib.Symbols.IkvmReflection; using IKVM.Reflection; -using IKVM.Reflection.Diagnostics; using IKVM.Runtime; -using Type = IKVM.Reflection.Type; - namespace IKVM.Tools.Importer { class StaticCompiler { - readonly ConcurrentDictionary runtimeTypeCache = new(); - readonly IDiagnosticHandler diagnostics; readonly IkvmReflectionSymbolContext symbols; internal Universe universe; - internal IAssemblySymbol runtimeAssembly; - internal IAssemblySymbol baseAssembly; - internal ImportState rootTarget; - internal int errorCount; - - internal Universe Universe => universe; - - internal IkvmReflectionSymbolContext Symbols => symbols; /// /// Initializes a new instance. /// /// + /// /// - public StaticCompiler(IDiagnosticHandler diagnostics, IkvmReflectionSymbolContext symbols) + public StaticCompiler(IDiagnosticHandler diagnostics, Universe universe, IkvmReflectionSymbolContext symbols) { this.diagnostics = diagnostics ?? throw new ArgumentNullException(nameof(diagnostics)); + this.universe = universe ?? throw new ArgumentNullException(nameof(universe)); this.symbols = symbols ?? throw new ArgumentNullException(nameof(symbols)); } /// - /// Initializes the universe. + /// Gets the symbol context. /// - /// - /// - /// - /// - internal void Init(bool nonDeterministicOutput, DebugMode debug, IList libpaths) - { - var options = UniverseOptions.ResolveMissingMembers | UniverseOptions.EnableFunctionPointers; - if (nonDeterministicOutput == false) - options |= UniverseOptions.DeterministicOutput; - - // discover the core lib from the references - var coreLibName = FindCoreLibName(rootTarget.unresolvedReferences, libpaths); - if (coreLibName == null) - { - diagnostics.CoreClassesMissing(); - throw new Exception(); - } - - universe = new Universe(options, coreLibName); - universe.ResolvedMissingMember += ResolvedMissingMember; - - // enable embedded symbol writer - if (debug == DebugMode.Portable) - universe.SetSymbolWriterFactory(module => new PortablePdbSymbolWriter(module)); - } - - /// - /// Finds the first potential core library in the reference set. - /// - /// - /// - /// - static string FindCoreLibName(IList references, IList libpaths) - { - if (references != null) - foreach (var reference in references) - if (GetAssemblyNameIfCoreLib(reference) is string coreLibName) - return coreLibName; - - if (libpaths != null) - foreach (var libpath in libpaths) - foreach (var dll in Directory.GetFiles(libpath, "*.dll")) - if (GetAssemblyNameIfCoreLib(dll) is string coreLibName) - return coreLibName; - - return null; - } - - /// - /// Returns true if the given assembly is a core library. - /// - /// - /// - static string GetAssemblyNameIfCoreLib(string path) - { - if (File.Exists(path) == false) - return null; - - using var st = File.OpenRead(path); - using var pe = new PEReader(st); - var mr = pe.GetMetadataReader(); - - foreach (var handle in mr.TypeDefinitions) - if (IsSystemObject(mr, handle)) - return mr.GetString(mr.GetAssemblyDefinition().Name); - - return null; - } + internal IkvmReflectionSymbolContext Symbols => symbols; /// - /// Returns true if the given type definition handle refers to "System.Object". + /// Gets the universe of types. /// - /// - /// - /// - static bool IsSystemObject(MetadataReader reader, TypeDefinitionHandle th) - { - var td = reader.GetTypeDefinition(th); - var ns = reader.GetString(td.Namespace); - var nm = reader.GetString(td.Name); - - return ns == "System" && nm == "Object"; - } - - void ResolvedMissingMember(Module requestingModule, MemberInfo member) - { - if (requestingModule != null && member is Type) - { - diagnostics.UnableToResolveType(requestingModule.Name, ((Type)member).FullName, member.Module.FullyQualifiedName); - } - } + internal Universe Universe => universe; internal Assembly Load(string assemblyString) { @@ -178,11 +79,6 @@ internal IAssemblySymbol LoadFile(string path) return symbols.GetOrCreateAssemblySymbol( universe.LoadFile(path)); } - internal ITypeSymbol GetRuntimeType(string name) - { - return runtimeTypeCache.GetOrAdd(name, runtimeAssembly.GetType); - } - internal ITypeSymbol GetTypeForMapXml(RuntimeClassLoader loader, string name) { return GetType(loader, name) ?? throw new FatalCompilerErrorException(DiagnosticEvent.MapFileTypeNotFound(name)); @@ -247,7 +143,7 @@ internal void IssueMissingTypeMessage(ITypeSymbol type) diagnostics.MissingType(type.FullName, type.Assembly.FullName); } - internal void SuppressWarning(ImportState options, Diagnostic diagnostic, string name) + internal void SuppressWarning(ImportContext options, Diagnostic diagnostic, string name) { options.suppressWarnings.Add($"{diagnostic.Id}:{name}"); } From 64ae586d601c7b0459b83c93a99d4bfef9e56552 Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Thu, 26 Sep 2024 20:47:51 -0500 Subject: [PATCH 14/51] Put IsMissing back. Remove a number of ifdefs. Add a DiagnosticOptions to allow NoWarn/WarnAsError. These are quite how I want them, but they serve for now. Allow overriding levels using those options. Trap fatal exception. --- .../Diagnostics/DiagnosticEvent.cs | 5 - .../Diagnostics/DiagnosticEvent.g.cs | 1 - .../Diagnostics/DiagnosticLevel.cs | 1 + .../IkvmReflectionAssemblySymbol.cs | 3 + .../IkvmReflectionMemberSymbol.cs | 3 + .../IkvmReflectionModuleSymbol.cs | 3 + .../IkvmReflectionTypeSymbol.cs | 3 + .../IkvmToolTaskDiagnosticWriter.cs | 4 +- src/IKVM.Runtime/AttributeHelper.cs | 8 +- .../Attributes/EnclosingMethodAttribute.cs | 48 ++++---- .../Attributes/InnerClassAttribute.cs | 35 +++--- .../Attributes/RemappedClassAttribute.cs | 9 +- .../Attributes/RemappedTypeAttribute.cs | 6 +- .../Attributes/ThrowsAttribute.cs | 47 ++++---- src/IKVM.Runtime/BootstrapClassLoader.cs | 7 -- src/IKVM.Runtime/ByteCodeHelperMethods.cs | 2 - src/IKVM.Runtime/CodeEmitter.cs | 6 - src/IKVM.Runtime/DefineMethodHelper.cs | 17 +-- src/IKVM.Runtime/DynamicClassLoader.cs | 1 + src/IKVM.Runtime/GhostTag.cs | 5 +- src/IKVM.Runtime/InstructionState.cs | 26 +++- .../Java/Externs/java/io/ObjectStreamClass.cs | 2 +- src/IKVM.Runtime/LambdaMetafactory.cs | 2 +- src/IKVM.Runtime/RuntimeClassLoaderFactory.cs | 8 +- .../AsyncDiagnosticChannelWriter.cs | 19 ++- .../ConsoleDiagnosticFormatterOptions.cs | 2 +- .../Diagnostics/DiagnosticChannelFormatter.cs | 18 ++- .../DiagnosticChannelFormatterOptions.cs | 3 +- .../Diagnostics/DiagnosticFormatterOptions.cs | 37 ++++++ .../Diagnostics/DiagnosticOptions.cs | 33 +++++ .../DiagnosticServiceCollectionExtensions.cs | 1 + ...enericChannelDiagnosticFormatterFactory.cs | 11 +- .../Diagnostics/IDiagnosticFormatter.cs | 5 +- .../Diagnostics/JsonDiagnosticFormatter.cs | 7 +- .../JsonDiagnosticFormatterFactory.cs | 5 +- .../Diagnostics/TextDiagnosticFormatter.cs | 7 +- .../TextDiagnosticFormatterFactory.cs | 5 +- src/IKVM.Tools.Importer/ImportClassLoader.cs | 113 +++++++++--------- src/IKVM.Tools.Importer/ImportCommand.cs | 26 ++-- src/IKVM.Tools.Importer/ImportContext.cs | 20 ++-- .../ImportContextFactory.cs | 65 ---------- .../ImportDiagnosticHandler.cs | 50 ++++++++ .../ImportOptionsBinding.cs | 36 ++++-- src/IKVM.Tools.Importer/ImportTool.cs | 70 ++++++++--- src/IKVM.Tools.Importer/StaticCompiler.cs | 6 - src/ikvmc/Properties/launchSettings.json | 2 +- src/ikvmc/ikvmc.csproj | 2 +- 47 files changed, 460 insertions(+), 335 deletions(-) create mode 100644 src/IKVM.Tools.Core/Diagnostics/DiagnosticFormatterOptions.cs create mode 100644 src/IKVM.Tools.Core/Diagnostics/DiagnosticOptions.cs create mode 100644 src/IKVM.Tools.Importer/ImportDiagnosticHandler.cs diff --git a/src/IKVM.CoreLib/Diagnostics/DiagnosticEvent.cs b/src/IKVM.CoreLib/Diagnostics/DiagnosticEvent.cs index c90a66a89..4b2ebd0f1 100644 --- a/src/IKVM.CoreLib/Diagnostics/DiagnosticEvent.cs +++ b/src/IKVM.CoreLib/Diagnostics/DiagnosticEvent.cs @@ -26,11 +26,6 @@ readonly partial struct DiagnosticEvent(Diagnostic Diagnostic, object?[] Args, E /// public readonly DiagnosticLocation Location = Location; - internal static DiagnosticEvent RuntimeMismatch(object location, string fullName1, string fullName2) - { - throw new NotImplementedException(); - } - /// /// Formats the diagnostic event message. /// diff --git a/src/IKVM.CoreLib/Diagnostics/DiagnosticEvent.g.cs b/src/IKVM.CoreLib/Diagnostics/DiagnosticEvent.g.cs index 3dde983f2..0ad8a07f3 100644 --- a/src/IKVM.CoreLib/Diagnostics/DiagnosticEvent.g.cs +++ b/src/IKVM.CoreLib/Diagnostics/DiagnosticEvent.g.cs @@ -1,6 +1,5 @@ #nullable enable using System; -using System.Text; namespace IKVM.CoreLib.Diagnostics { diff --git a/src/IKVM.CoreLib/Diagnostics/DiagnosticLevel.cs b/src/IKVM.CoreLib/Diagnostics/DiagnosticLevel.cs index 3226f9f80..476fe8d78 100644 --- a/src/IKVM.CoreLib/Diagnostics/DiagnosticLevel.cs +++ b/src/IKVM.CoreLib/Diagnostics/DiagnosticLevel.cs @@ -6,6 +6,7 @@ enum DiagnosticLevel { + Unknown, Trace, Info, Warning, diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs index 73163f1ba..db6ef47b7 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs @@ -68,6 +68,9 @@ public IIkvmReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) /// public IEnumerable Modules => ResolveModuleSymbols(UnderlyingAssembly.Modules); + /// + public override bool IsMissing => UnderlyingAssembly.__IsMissing; + /// public ITypeSymbol[] GetExportedTypes() { diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs index c74eafbf3..7da4302ba 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs @@ -174,6 +174,9 @@ public IkvmReflectionMemberSymbol(IkvmReflectionSymbolContext context, IIkvmRefl /// public virtual string Name => UnderlyingMember.Name; + /// + public override bool IsMissing => UnderlyingMember.__IsMissing; + /// public virtual CustomAttribute[] GetCustomAttributes(bool inherit = false) { diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs index 1775a2692..e1e699c84 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs @@ -65,6 +65,9 @@ public IkvmReflectionModuleSymbol(IkvmReflectionSymbolContext context, IIkvmRefl /// public string ScopeName => UnderlyingModule.ScopeName; + /// + public override bool IsMissing => UnderlyingModule.__IsMissing; + /// public IFieldSymbol? GetField(string name) { diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs index b99a9ef22..405b59f23 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs @@ -283,6 +283,9 @@ public IIkvmReflectionTypeSymbol GetOrCreateGenericTypeSymbol(Type[] genericType /// public IConstructorSymbol? TypeInitializer => ResolveConstructorSymbol(UnderlyingType.TypeInitializer); + /// + public override bool ContainsMissing => UnderlyingType.__ContainsMissingType; + /// public int GetArrayRank() { diff --git a/src/IKVM.MSBuild.Tasks/IkvmToolTaskDiagnosticWriter.cs b/src/IKVM.MSBuild.Tasks/IkvmToolTaskDiagnosticWriter.cs index 259b27dd0..1d73da7d9 100644 --- a/src/IKVM.MSBuild.Tasks/IkvmToolTaskDiagnosticWriter.cs +++ b/src/IKVM.MSBuild.Tasks/IkvmToolTaskDiagnosticWriter.cs @@ -62,7 +62,7 @@ public async ValueTask ReceiveAsync(IkvmToolDiagnosticEvent @event, Cancellation } if (writer != null) - await WriteLogsync(writer, @event, cancellationToken); + await WriteLogAsync(writer, @event, cancellationToken); } catch (Exception e) { @@ -77,7 +77,7 @@ public async ValueTask ReceiveAsync(IkvmToolDiagnosticEvent @event, Cancellation /// /// /// - async Task WriteLogsync(TextWriter writer, IkvmToolDiagnosticEvent @event, CancellationToken cancellationToken) + async Task WriteLogAsync(TextWriter writer, IkvmToolDiagnosticEvent @event, CancellationToken cancellationToken) { await TextDiagnosticFormat.WriteAsync(@event.Id, Convert(@event.Level), @event.Message, @event.Args, null, Convert(@event.Location), writer, cancellationToken); await writer.WriteLineAsync(); diff --git a/src/IKVM.Runtime/AttributeHelper.cs b/src/IKVM.Runtime/AttributeHelper.cs index f51065581..a54bacb1f 100644 --- a/src/IKVM.Runtime/AttributeHelper.cs +++ b/src/IKVM.Runtime/AttributeHelper.cs @@ -374,8 +374,8 @@ ICustomAttributeBuilder GetEditorBrowsableNever() { if (editorBrowsableNever == null) { - var typeofEditorBrowsableAttribute = context.Resolver.ResolveCoreType(typeof(EditorBrowsableAttribute).FullName); - var typeofEditorBrowsableState = context.Resolver.ResolveCoreType(typeof(EditorBrowsableState).FullName); + var typeofEditorBrowsableAttribute = context.Resolver.ResolveType(typeof(EditorBrowsableAttribute).FullName); + var typeofEditorBrowsableState = context.Resolver.ResolveType(typeof(EditorBrowsableState).FullName); var ctor = typeofEditorBrowsableAttribute.GetConstructor([typeofEditorBrowsableState]); editorBrowsableNever = context.Resolver.Symbols.CreateCustomAttribute(ctor, [EditorBrowsableState.Never]); } @@ -700,8 +700,6 @@ internal void SetDebuggingModes(IAssemblySymbolBuilder assemblyBuilder, Debuggab assemblyBuilder.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(debuggableAttribute, [modes])); } -#if IMPORTER - internal void SetModifiers(IMethodBaseSymbolBuilder mb, Modifiers modifiers, bool isInternal) { ICustomAttributeBuilder customAttributeBuilder; @@ -865,8 +863,6 @@ internal void SetParamArrayAttribute(IParameterSymbolBuilder pb) pb.SetCustomAttribute(paramArrayAttribute); } -#endif // IMPORTER - internal NameSigAttribute GetNameSig(IMemberSymbol member) { foreach (var cad in member.GetCustomAttributes(TypeOfNameSigAttribute)) diff --git a/src/IKVM.Runtime/Attributes/EnclosingMethodAttribute.cs b/src/IKVM.Runtime/Attributes/EnclosingMethodAttribute.cs index 39e1efa39..a93dfb48c 100644 --- a/src/IKVM.Runtime/Attributes/EnclosingMethodAttribute.cs +++ b/src/IKVM.Runtime/Attributes/EnclosingMethodAttribute.cs @@ -26,33 +26,35 @@ Jeroen Frijters using IKVM.CoreLib.Symbols; using IKVM.Runtime; -#if IMPORTER || EXPORTER -using Type = IKVM.Reflection.Type; -#endif - namespace IKVM.Attributes { [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)] - public sealed class EnclosingMethodAttribute : Attribute - { - - private string className; - private string methodName; - private string methodSig; - - public EnclosingMethodAttribute(string className, string methodName, string methodSig) - { - this.className = UnicodeUtil.UnescapeInvalidSurrogates(className); - this.methodName = UnicodeUtil.UnescapeInvalidSurrogates(methodName); - this.methodSig = UnicodeUtil.UnescapeInvalidSurrogates(methodSig); - } - - internal EnclosingMethodAttribute SetClassName(RuntimeContext context, ITypeSymbol type) - { - className ??= context.ClassLoaderFactory.GetJavaTypeFromType(type.DeclaringType).Name; - return this; - } + public sealed class EnclosingMethodAttribute : Attribute + { + + string className; + readonly string methodName; + readonly string methodSig; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + public EnclosingMethodAttribute(string className, string methodName, string methodSig) + { + this.className = UnicodeUtil.UnescapeInvalidSurrogates(className); + this.methodName = UnicodeUtil.UnescapeInvalidSurrogates(methodName); + this.methodSig = UnicodeUtil.UnescapeInvalidSurrogates(methodSig); + } + + internal EnclosingMethodAttribute SetClassName(RuntimeContext context, ITypeSymbol type) + { + className ??= context.ClassLoaderFactory.GetJavaTypeFromType(type.DeclaringType).Name; + return this; + } public string ClassName => className; diff --git a/src/IKVM.Runtime/Attributes/InnerClassAttribute.cs b/src/IKVM.Runtime/Attributes/InnerClassAttribute.cs index 08c36ff3f..88dda7985 100644 --- a/src/IKVM.Runtime/Attributes/InnerClassAttribute.cs +++ b/src/IKVM.Runtime/Attributes/InnerClassAttribute.cs @@ -25,40 +25,33 @@ Jeroen Frijters using IKVM.Runtime; -#if IMPORTER || EXPORTER -using Type = IKVM.Reflection.Type; -#endif - namespace IKVM.Attributes { + // NOTE this attribute is also used by annotation attribute classes, // to give them a different name in the Java world ($Proxy[Annotation]). [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)] public sealed class InnerClassAttribute : Attribute { - private string innerClassName; - private Modifiers modifiers; + readonly string innerClassName; + readonly Modifiers modifiers; + + /// + /// Initializes a new instance. + /// + /// + /// public InnerClassAttribute(string innerClassName, Modifiers modifiers) { this.innerClassName = UnicodeUtil.UnescapeInvalidSurrogates(innerClassName); this.modifiers = modifiers; } - public string InnerClassName - { - get - { - return innerClassName; - } - } + public string InnerClassName => innerClassName; + + public Modifiers Modifiers => modifiers; + + } - public Modifiers Modifiers - { - get - { - return modifiers; - } - } - } } diff --git a/src/IKVM.Runtime/Attributes/RemappedClassAttribute.cs b/src/IKVM.Runtime/Attributes/RemappedClassAttribute.cs index 522bb201a..541c6dac4 100644 --- a/src/IKVM.Runtime/Attributes/RemappedClassAttribute.cs +++ b/src/IKVM.Runtime/Attributes/RemappedClassAttribute.cs @@ -34,8 +34,8 @@ namespace IKVM.Attributes public sealed class RemappedClassAttribute : Attribute { - private string name; - private Type remappedType; + readonly string name; + readonly Type remappedType; #if EXPORTER @@ -46,6 +46,11 @@ public RemappedClassAttribute(string name, System.Type remappedType) #endif + /// + /// Initializes a new instance. + /// + /// + /// public RemappedClassAttribute(string name, Type remappedType) { this.name = name; diff --git a/src/IKVM.Runtime/Attributes/RemappedTypeAttribute.cs b/src/IKVM.Runtime/Attributes/RemappedTypeAttribute.cs index da1097978..54358c0a1 100644 --- a/src/IKVM.Runtime/Attributes/RemappedTypeAttribute.cs +++ b/src/IKVM.Runtime/Attributes/RemappedTypeAttribute.cs @@ -34,7 +34,7 @@ namespace IKVM.Attributes public sealed class RemappedTypeAttribute : Attribute { - private Type type; + readonly Type type; #if EXPORTER @@ -45,6 +45,10 @@ public RemappedTypeAttribute(System.Type type) #endif + /// + /// Initializes a new instance. + /// + /// public RemappedTypeAttribute(Type type) { this.type = type; diff --git a/src/IKVM.Runtime/Attributes/ThrowsAttribute.cs b/src/IKVM.Runtime/Attributes/ThrowsAttribute.cs index 94a481223..39b387edf 100644 --- a/src/IKVM.Runtime/Attributes/ThrowsAttribute.cs +++ b/src/IKVM.Runtime/Attributes/ThrowsAttribute.cs @@ -33,27 +33,32 @@ namespace IKVM.Attributes { [AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method)] - public sealed class ThrowsAttribute : Attribute - { - - internal string[] classes; - internal Type[] types; - - // this constructor is used by ikvmc, the other constructors are for use in other .NET languages - public ThrowsAttribute(string[] classes) - { - this.classes = UnicodeUtil.UnescapeInvalidSurrogates(classes); - } - - public ThrowsAttribute(Type type) - : this(new Type[] { type }) - { - } - - public ThrowsAttribute(params Type[] types) - { - this.types = types; - } + public sealed class ThrowsAttribute : Attribute + { + + internal string[] classes; + internal Type[] types; + + // this constructor is used by ikvmc, the other constructors are for use in other .NET languages + public ThrowsAttribute(string[] classes) + { + this.classes = UnicodeUtil.UnescapeInvalidSurrogates(classes); + } + + /// + /// Initializes a new instance. + /// + /// + public ThrowsAttribute(Type type) : + this(new Type[] { type }) + { + + } + + public ThrowsAttribute(params Type[] types) + { + this.types = types; + } // dotted Java class names (e.g. java.lang.Throwable) [Obsolete] diff --git a/src/IKVM.Runtime/BootstrapClassLoader.cs b/src/IKVM.Runtime/BootstrapClassLoader.cs index 1e9d42aeb..758fab374 100644 --- a/src/IKVM.Runtime/BootstrapClassLoader.cs +++ b/src/IKVM.Runtime/BootstrapClassLoader.cs @@ -26,13 +26,6 @@ Jeroen Frijters using IKVM.CoreLib.Symbols; - -#if IMPORTER || EXPORTER -using IKVM.Reflection; - -using Type = IKVM.Reflection.Type; -#endif - namespace IKVM.Runtime { diff --git a/src/IKVM.Runtime/ByteCodeHelperMethods.cs b/src/IKVM.Runtime/ByteCodeHelperMethods.cs index e0691d5f2..fffd0b72b 100644 --- a/src/IKVM.Runtime/ByteCodeHelperMethods.cs +++ b/src/IKVM.Runtime/ByteCodeHelperMethods.cs @@ -21,8 +21,6 @@ Jeroen Frijters jeroen@frijters.net */ -using System.Reflection; - using IKVM.CoreLib.Diagnostics; using IKVM.CoreLib.Symbols; diff --git a/src/IKVM.Runtime/CodeEmitter.cs b/src/IKVM.Runtime/CodeEmitter.cs index 1df5466c4..4f0c6d73e 100644 --- a/src/IKVM.Runtime/CodeEmitter.cs +++ b/src/IKVM.Runtime/CodeEmitter.cs @@ -2405,10 +2405,8 @@ internal void ThrowException(ITypeSymbol excType) internal void SetLineNumber(ushort line) { -#if NETFRAMEWORK || IMPORTER if (symbols != null) EmitPseudoOpCode(CodeType.SequencePoint, (int)line); -#endif EmitPseudoOpCode(CodeType.LineNumber, (int)line); } @@ -2418,16 +2416,12 @@ internal byte[] GetLineNumberTable() return linenums == null ? null : linenums.ToArray(); } -#if IMPORTER - internal void EmitLineNumberTable(IMethodBaseSymbolBuilder mb) { if (linenums != null) context.AttributeHelper.SetLineNumberTable(mb, linenums); } -#endif - internal void EmitThrow(string dottedClassName) { var exception = context.ClassLoaderFactory.GetBootstrapClassLoader().LoadClassByName(dottedClassName); diff --git a/src/IKVM.Runtime/DefineMethodHelper.cs b/src/IKVM.Runtime/DefineMethodHelper.cs index 78a473144..2e0558b14 100644 --- a/src/IKVM.Runtime/DefineMethodHelper.cs +++ b/src/IKVM.Runtime/DefineMethodHelper.cs @@ -21,21 +21,8 @@ Jeroen Frijters jeroen@frijters.net */ -using IKVM.CoreLib.Symbols.Emit; using IKVM.CoreLib.Symbols; - -#if IMPORTER -using IKVM.Reflection; -using IKVM.Reflection.Emit; -using IKVM.Tools.Importer; - -using Type = IKVM.Reflection.Type; -using DynamicOrAotTypeWrapper = IKVM.Tools.Importer.RuntimeImportByteCodeJavaType; -using ProtectionDomain = System.Object; -#else -using System.Reflection; -using System.Reflection.Emit; -#endif +using IKVM.CoreLib.Symbols.Emit; namespace IKVM.Runtime { @@ -43,7 +30,7 @@ namespace IKVM.Runtime sealed class DefineMethodHelper { - private readonly RuntimeJavaMethod mw; + readonly RuntimeJavaMethod mw; internal DefineMethodHelper(RuntimeJavaMethod mw) { diff --git a/src/IKVM.Runtime/DynamicClassLoader.cs b/src/IKVM.Runtime/DynamicClassLoader.cs index dff4b4656..3feb88869 100644 --- a/src/IKVM.Runtime/DynamicClassLoader.cs +++ b/src/IKVM.Runtime/DynamicClassLoader.cs @@ -32,6 +32,7 @@ Jeroen Frijters using IKVM.CoreLib.Symbols; using static System.Diagnostics.DebuggableAttribute; + using System.Collections.Immutable; diff --git a/src/IKVM.Runtime/GhostTag.cs b/src/IKVM.Runtime/GhostTag.cs index 7998b29c5..8bf1e289a 100644 --- a/src/IKVM.Runtime/GhostTag.cs +++ b/src/IKVM.Runtime/GhostTag.cs @@ -71,12 +71,13 @@ internal static bool IsGhostArrayInstance(object obj, RuntimeTypeHandle typeHand #if FIRST_PASS || IMPORTER throw new NotImplementedException(); #else - RuntimeJavaType tw1 = GhostTag.GetTag(obj); + var tw1 = GhostTag.GetTag(obj); if (tw1 != null) { - RuntimeJavaType tw2 = tw1.Context.ClassLoaderFactory.GetJavaTypeFromType(Type.GetTypeFromHandle(typeHandle)).MakeArrayType(rank); + var tw2 = tw1.Context.ClassLoaderFactory.GetJavaTypeFromType(Type.GetTypeFromHandle(typeHandle)).MakeArrayType(rank); return tw1.IsAssignableTo(tw2); } + return false; #endif } diff --git a/src/IKVM.Runtime/InstructionState.cs b/src/IKVM.Runtime/InstructionState.cs index 33c1b3afe..27312c3af 100644 --- a/src/IKVM.Runtime/InstructionState.cs +++ b/src/IKVM.Runtime/InstructionState.cs @@ -34,12 +34,12 @@ namespace IKVM.Runtime sealed class InstructionState { - private struct LocalStoreSites + struct LocalStoreSites { - private int[] data; - private int count; - private bool shared; + int[] data; + int count; + bool shared; internal LocalStoreSites Copy() { @@ -121,8 +121,19 @@ private enum ShareFlags : byte Locals = 2, All = Stack | Locals } + private ShareFlags flags; + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + /// + /// + /// private InstructionState(RuntimeContext context, RuntimeJavaType[] stack, int stackSize, int stackEnd, RuntimeJavaType[] locals, bool unitializedThis) { this.context = context ?? throw new ArgumentNullException(nameof(context)); @@ -134,6 +145,13 @@ private InstructionState(RuntimeContext context, RuntimeJavaType[] stack, int st this.unitializedThis = unitializedThis; } + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// internal InstructionState(RuntimeContext context, int maxLocals, int maxStack) { this.context = context ?? throw new ArgumentNullException(nameof(context)); diff --git a/src/IKVM.Runtime/Java/Externs/java/io/ObjectStreamClass.cs b/src/IKVM.Runtime/Java/Externs/java/io/ObjectStreamClass.cs index 34a955425..22ba98761 100644 --- a/src/IKVM.Runtime/Java/Externs/java/io/ObjectStreamClass.cs +++ b/src/IKVM.Runtime/Java/Externs/java/io/ObjectStreamClass.cs @@ -120,7 +120,7 @@ public static int ReadInt(byte[] buf, int offset) public static float ReadFloat(byte[] buf, int offset) { #if FIRST_PASS || IMPORTER - return 0; + return 0; #else return global::java.lang.Float.intBitsToFloat(ReadInt(buf, offset)); #endif diff --git a/src/IKVM.Runtime/LambdaMetafactory.cs b/src/IKVM.Runtime/LambdaMetafactory.cs index 92079c97a..6b8847200 100644 --- a/src/IKVM.Runtime/LambdaMetafactory.cs +++ b/src/IKVM.Runtime/LambdaMetafactory.cs @@ -41,7 +41,7 @@ namespace IKVM.Runtime sealed class LambdaMetafactory { - private IMethodSymbolBuilder getInstance; + IMethodSymbolBuilder getInstance; internal static bool Emit(RuntimeByteCodeJavaType.FinishContext context, ClassFile classFile, int constantPoolIndex, ClassFile.ConstantPoolItemInvokeDynamic cpi, CodeEmitter ilgen) { diff --git a/src/IKVM.Runtime/RuntimeClassLoaderFactory.cs b/src/IKVM.Runtime/RuntimeClassLoaderFactory.cs index 1625345a5..27f07f5db 100644 --- a/src/IKVM.Runtime/RuntimeClassLoaderFactory.cs +++ b/src/IKVM.Runtime/RuntimeClassLoaderFactory.cs @@ -174,14 +174,10 @@ internal RuntimeClassLoader GetClassLoaderWrapper(java.lang.ClassLoader javaClas /// internal RuntimeJavaType GetJavaTypeFromType(ITypeSymbol type) { -#if IMPORTER - if (type.ContainsMissing) - return new RuntimeUnloadableJavaType(context, type); -#endif - #if !IMPORTER RuntimeJavaType.AssertFinished(type); #endif + Debug.Assert(!type.IsPointer); Debug.Assert(!type.IsByRef); @@ -192,14 +188,12 @@ internal RuntimeJavaType GetJavaTypeFromType(ITypeSymbol type) if (wrapper != null) return wrapper; -#if EXPORTER if (type.IsMissing || type.ContainsMissing) { wrapper = new RuntimeUnloadableJavaType(context, type); globalTypeToTypeWrapper.Add(type, wrapper); return wrapper; } -#endif if (remappedTypes.TryGetValue(type, out var remapped)) { diff --git a/src/IKVM.Tools.Core/Diagnostics/AsyncDiagnosticChannelWriter.cs b/src/IKVM.Tools.Core/Diagnostics/AsyncDiagnosticChannelWriter.cs index 2173ccb24..0b9b2eb5d 100644 --- a/src/IKVM.Tools.Core/Diagnostics/AsyncDiagnosticChannelWriter.cs +++ b/src/IKVM.Tools.Core/Diagnostics/AsyncDiagnosticChannelWriter.cs @@ -1,5 +1,6 @@ using System; using System.Buffers; +using System.IO.Pipelines; using System.Threading; using System.Threading.Channels; using System.Threading.Tasks; @@ -20,7 +21,7 @@ class AsyncDiagnosticChannelWriter : IDiagnosticChannelWriter, IDisposable AllowSynchronousContinuations = true }; - readonly IBufferWriter _writer; + readonly PipeWriter _writer; readonly Channel<(IMemoryOwner Owner, int Length)> _channel = Channel.CreateUnbounded<(IMemoryOwner Owner, int Length)>(unboundedChannelOptions); Task? _task; @@ -31,7 +32,7 @@ class AsyncDiagnosticChannelWriter : IDiagnosticChannelWriter, IDisposable /// /// /// - public AsyncDiagnosticChannelWriter(IBufferWriter writer) + public AsyncDiagnosticChannelWriter(PipeWriter writer) { _writer = writer ?? throw new ArgumentNullException(nameof(writer)); } @@ -71,7 +72,7 @@ async Task DequeueLoop(CancellationToken cancellationToken) { while (await _channel.Reader.WaitToReadAsync(cancellationToken)) while (_channel.Reader.TryRead(out var item)) - WriteData(item.Owner, item.Length); + await WriteData(item.Owner, item.Length, cancellationToken); } catch (OperationCanceledException) { @@ -85,12 +86,13 @@ async Task DequeueLoop(CancellationToken cancellationToken) /// /// /// - void WriteData(IMemoryOwner owner, int length) + async ValueTask WriteData(IMemoryOwner owner, int length, CancellationToken cancellationToken) { // allocate memory and copy data var buffer = _writer.GetMemory(length); owner.Memory.Slice(0, length).CopyTo(buffer); _writer.Advance(length); + await _writer.FlushAsync(cancellationToken); // we are finished with the owner owner.Dispose(); @@ -114,7 +116,14 @@ public void Dispose() item.Owner.Dispose(); // complete the channel - _channel.Writer.Complete(); + try + { + _channel.Writer.Complete(); + } + catch (ChannelClosedException) + { + // ignore + } } } diff --git a/src/IKVM.Tools.Core/Diagnostics/ConsoleDiagnosticFormatterOptions.cs b/src/IKVM.Tools.Core/Diagnostics/ConsoleDiagnosticFormatterOptions.cs index 4b4e58580..d6f159510 100644 --- a/src/IKVM.Tools.Core/Diagnostics/ConsoleDiagnosticFormatterOptions.cs +++ b/src/IKVM.Tools.Core/Diagnostics/ConsoleDiagnosticFormatterOptions.cs @@ -1,7 +1,7 @@ namespace IKVM.Tools.Core.Diagnostics { - class ConsoleDiagnosticFormatterOptions + class ConsoleDiagnosticFormatterOptions : DiagnosticFormatterOptions { diff --git a/src/IKVM.Tools.Core/Diagnostics/DiagnosticChannelFormatter.cs b/src/IKVM.Tools.Core/Diagnostics/DiagnosticChannelFormatter.cs index 310119e22..f407ef8c0 100644 --- a/src/IKVM.Tools.Core/Diagnostics/DiagnosticChannelFormatter.cs +++ b/src/IKVM.Tools.Core/Diagnostics/DiagnosticChannelFormatter.cs @@ -21,11 +21,22 @@ public DiagnosticChannelFormatter(TOptions options) _options = options ?? throw new ArgumentNullException(nameof(options)); } + /// + /// Gets the options. + /// + public TOptions Options => _options; + /// public void Write(in DiagnosticEvent @event) { + var level = @event.Diagnostic.Level; + if (level is DiagnosticLevel.Warning && Options.WarnAsError) + level = DiagnosticLevel.Error; + if (level is DiagnosticLevel.Warning && Options.WarnAsErrorDiagnostics.Contains(@event.Diagnostic)) + level = DiagnosticLevel.Error; + // find the writer for the event's level - var channel = @event.Diagnostic.Level switch + var channel = level switch { DiagnosticLevel.Trace => _options.TraceChannel, DiagnosticLevel.Info => _options.InfoChannel, @@ -39,15 +50,16 @@ public void Write(in DiagnosticEvent @event) if (channel == null) return; - WriteImpl(@event, channel); + WriteImpl(@event, level, channel); } /// /// Implement this method to write the diagnostic event to the channel. /// /// + /// /// - protected abstract void WriteImpl(in DiagnosticEvent @event, IDiagnosticChannel channel); + protected abstract void WriteImpl(in DiagnosticEvent @event, DiagnosticLevel level, IDiagnosticChannel channel); /// /// Disposes of the instance. diff --git a/src/IKVM.Tools.Core/Diagnostics/DiagnosticChannelFormatterOptions.cs b/src/IKVM.Tools.Core/Diagnostics/DiagnosticChannelFormatterOptions.cs index 5bedd556a..8438ec438 100644 --- a/src/IKVM.Tools.Core/Diagnostics/DiagnosticChannelFormatterOptions.cs +++ b/src/IKVM.Tools.Core/Diagnostics/DiagnosticChannelFormatterOptions.cs @@ -1,11 +1,12 @@ using System; +using System.Collections.Generic; using IKVM.CoreLib.Diagnostics; namespace IKVM.Tools.Core.Diagnostics { - abstract class DiagnosticChannelFormatterOptions + abstract class DiagnosticChannelFormatterOptions : DiagnosticFormatterOptions { /// diff --git a/src/IKVM.Tools.Core/Diagnostics/DiagnosticFormatterOptions.cs b/src/IKVM.Tools.Core/Diagnostics/DiagnosticFormatterOptions.cs new file mode 100644 index 000000000..03230ef6b --- /dev/null +++ b/src/IKVM.Tools.Core/Diagnostics/DiagnosticFormatterOptions.cs @@ -0,0 +1,37 @@ +using System.Collections.Generic; +using System.Collections.Immutable; + +using IKVM.CoreLib.Diagnostics; + +namespace IKVM.Tools.Core.Diagnostics +{ + + /// + /// Base class for common diagnostic options. + /// + abstract class DiagnosticFormatterOptions + { + + /// + /// Gets or sets whether all warnings should be suppressed. + /// + public bool NoWarn { get; set; } + + /// + /// Gets or sets whether the specified diagnostics should be suppressed. + /// + public ImmutableArray NoWarnDiagnostics { get; set; } = []; + + /// + /// All warnings should be elevated to errors. + /// + public bool WarnAsError { get; set; } + + /// + /// Set of warning diagnostics that should be elevated to errors. + /// + public ImmutableArray WarnAsErrorDiagnostics { get; set; } = []; + + } + +} \ No newline at end of file diff --git a/src/IKVM.Tools.Core/Diagnostics/DiagnosticOptions.cs b/src/IKVM.Tools.Core/Diagnostics/DiagnosticOptions.cs new file mode 100644 index 000000000..9870c9356 --- /dev/null +++ b/src/IKVM.Tools.Core/Diagnostics/DiagnosticOptions.cs @@ -0,0 +1,33 @@ +using System.Collections.Immutable; + +using IKVM.CoreLib.Diagnostics; + +namespace IKVM.Tools.Core.Diagnostics +{ + + class DiagnosticOptions + { + + /// + /// Gets or sets whether all warnings should be suppressed. + /// + public bool NoWarn { get; set; } + + /// + /// Gets or sets whether the specified diagnostics should be suppressed. + /// + public ImmutableArray NoWarnDiagnostics { get; set; } + + /// + /// Gets or sets whether all warnings should be promoted to errors. + /// + public bool WarnAsError { get; set; } + + /// + /// Gets or sets whether the specified diagnostics should be promoted to errors. + /// + public ImmutableArray WarnAsErrorDiagnostics { get; set; } + + } + +} \ No newline at end of file diff --git a/src/IKVM.Tools.Core/Diagnostics/DiagnosticServiceCollectionExtensions.cs b/src/IKVM.Tools.Core/Diagnostics/DiagnosticServiceCollectionExtensions.cs index d8afd9c95..fef86d45b 100644 --- a/src/IKVM.Tools.Core/Diagnostics/DiagnosticServiceCollectionExtensions.cs +++ b/src/IKVM.Tools.Core/Diagnostics/DiagnosticServiceCollectionExtensions.cs @@ -13,6 +13,7 @@ public static class DiagnosticServiceCollectionExtensions /// public static IServiceCollection AddToolsDiagnostics(this IServiceCollection services) { + services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); diff --git a/src/IKVM.Tools.Core/Diagnostics/GenericChannelDiagnosticFormatterFactory.cs b/src/IKVM.Tools.Core/Diagnostics/GenericChannelDiagnosticFormatterFactory.cs index cbcdee87c..01594b5ae 100644 --- a/src/IKVM.Tools.Core/Diagnostics/GenericChannelDiagnosticFormatterFactory.cs +++ b/src/IKVM.Tools.Core/Diagnostics/GenericChannelDiagnosticFormatterFactory.cs @@ -18,6 +18,7 @@ abstract class GenericChannelDiagnosticFormatterFactory : static readonly char[] SEPARATOR = ['=']; readonly DiagnosticChannelProvider _channels; + readonly DiagnosticOptions _options; readonly string _format; readonly string _formatPrefix; @@ -25,10 +26,13 @@ abstract class GenericChannelDiagnosticFormatterFactory : /// Initializes a new instance. /// /// + /// + /// /// - public GenericChannelDiagnosticFormatterFactory(DiagnosticChannelProvider channels, string format) + public GenericChannelDiagnosticFormatterFactory(DiagnosticChannelProvider channels, DiagnosticOptions options, string format) { _channels = channels ?? throw new ArgumentNullException(nameof(channels)); + _options = options ?? throw new ArgumentNullException(nameof(options)); _format = format ?? throw new ArgumentNullException(nameof(format)); _formatPrefix = $"{_format},"; } @@ -57,6 +61,11 @@ public GenericChannelDiagnosticFormatterFactory(DiagnosticChannelProvider channe opts.ErrorChannel ??= GetOrCreateChannel(chls, FileDiagnosticChannelFactory.STDERR); opts.FatalChannel ??= GetOrCreateChannel(chls, FileDiagnosticChannelFactory.STDERR); + opts.NoWarn = _options.NoWarn; + opts.NoWarnDiagnostics = _options.NoWarnDiagnostics; + opts.WarnAsError = _options.WarnAsError; + opts.WarnAsErrorDiagnostics = _options.WarnAsErrorDiagnostics; + // process options and create formatter return CreateFormatter(opts); } diff --git a/src/IKVM.Tools.Core/Diagnostics/IDiagnosticFormatter.cs b/src/IKVM.Tools.Core/Diagnostics/IDiagnosticFormatter.cs index 900c6daae..02dfebe0a 100644 --- a/src/IKVM.Tools.Core/Diagnostics/IDiagnosticFormatter.cs +++ b/src/IKVM.Tools.Core/Diagnostics/IDiagnosticFormatter.cs @@ -1,7 +1,4 @@ -using System.Threading; -using System.Threading.Tasks; - -using IKVM.CoreLib.Diagnostics; +using IKVM.CoreLib.Diagnostics; namespace IKVM.Tools.Core.Diagnostics { diff --git a/src/IKVM.Tools.Core/Diagnostics/JsonDiagnosticFormatter.cs b/src/IKVM.Tools.Core/Diagnostics/JsonDiagnosticFormatter.cs index 0d24a7ee4..27514b109 100644 --- a/src/IKVM.Tools.Core/Diagnostics/JsonDiagnosticFormatter.cs +++ b/src/IKVM.Tools.Core/Diagnostics/JsonDiagnosticFormatter.cs @@ -25,15 +25,14 @@ public JsonDiagnosticFormatter(JsonDiagnosticFormatterOptions options) : } /// - protected override void WriteImpl(in DiagnosticEvent @event, IDiagnosticChannel channel) + protected override void WriteImpl(in DiagnosticEvent @event, DiagnosticLevel level, IDiagnosticChannel channel) { var encoding = channel.Encoding ?? Encoding.UTF8; - using var buffer = MemoryPool.Shared.Rent(8192); + var buffer = MemoryPool.Shared.Rent(8192); var writer = new MemoryBufferWriter(buffer.Memory); - JsonDiagnosticFormat.Write(@event.Diagnostic.Id, @event.Diagnostic.Level, @event.Diagnostic.Message, @event.Args, @event.Exception, @event.Location, ref writer, encoding); + JsonDiagnosticFormat.Write(@event.Diagnostic.Id, level, @event.Diagnostic.Message, @event.Args, @event.Exception, @event.Location, ref writer, encoding); WriteLine(writer, encoding); channel.Writer.Write(buffer, writer.WrittenCount); - return; } /// diff --git a/src/IKVM.Tools.Core/Diagnostics/JsonDiagnosticFormatterFactory.cs b/src/IKVM.Tools.Core/Diagnostics/JsonDiagnosticFormatterFactory.cs index f10a53052..384f18d17 100644 --- a/src/IKVM.Tools.Core/Diagnostics/JsonDiagnosticFormatterFactory.cs +++ b/src/IKVM.Tools.Core/Diagnostics/JsonDiagnosticFormatterFactory.cs @@ -15,9 +15,10 @@ class JsonDiagnosticFormatterFactory : /// Initializes a new instance. /// /// + /// /// - public JsonDiagnosticFormatterFactory(DiagnosticChannelProvider channels) : - base(channels, "json") + public JsonDiagnosticFormatterFactory(DiagnosticChannelProvider channels, DiagnosticOptions options) : + base(channels, options, "json") { } diff --git a/src/IKVM.Tools.Core/Diagnostics/TextDiagnosticFormatter.cs b/src/IKVM.Tools.Core/Diagnostics/TextDiagnosticFormatter.cs index d1730936f..6ad1db2af 100644 --- a/src/IKVM.Tools.Core/Diagnostics/TextDiagnosticFormatter.cs +++ b/src/IKVM.Tools.Core/Diagnostics/TextDiagnosticFormatter.cs @@ -25,15 +25,14 @@ public TextDiagnosticFormatter(TextDiagnosticFormatterOptions options) : } /// - protected override void WriteImpl(in DiagnosticEvent @event, IDiagnosticChannel channel) + protected override void WriteImpl(in DiagnosticEvent @event, DiagnosticLevel level, IDiagnosticChannel channel) { var encoding = channel.Encoding ?? Encoding.UTF8; - using var buffer = MemoryPool.Shared.Rent(8192); + var buffer = MemoryPool.Shared.Rent(8192); var writer = new MemoryBufferWriter(buffer.Memory); - TextDiagnosticFormat.Write(@event.Diagnostic.Id, @event.Diagnostic.Level, @event.Diagnostic.Message, @event.Args, @event.Exception, @event.Location, ref writer, encoding); + TextDiagnosticFormat.Write(@event.Diagnostic.Id, level, @event.Diagnostic.Message, @event.Args, @event.Exception, @event.Location, ref writer, encoding); WriteLine(writer, encoding); channel.Writer.Write(buffer, writer.WrittenCount); - return; } /// diff --git a/src/IKVM.Tools.Core/Diagnostics/TextDiagnosticFormatterFactory.cs b/src/IKVM.Tools.Core/Diagnostics/TextDiagnosticFormatterFactory.cs index 918930bc6..2aac5bcaa 100644 --- a/src/IKVM.Tools.Core/Diagnostics/TextDiagnosticFormatterFactory.cs +++ b/src/IKVM.Tools.Core/Diagnostics/TextDiagnosticFormatterFactory.cs @@ -15,9 +15,10 @@ class TextDiagnosticFormatterFactory : /// Initializes a new instance. /// /// + /// /// - public TextDiagnosticFormatterFactory(DiagnosticChannelProvider channels) : - base(channels, "text") + public TextDiagnosticFormatterFactory(DiagnosticChannelProvider channels, DiagnosticOptions options) : + base(channels, options, "text") { } diff --git a/src/IKVM.Tools.Importer/ImportClassLoader.cs b/src/IKVM.Tools.Importer/ImportClassLoader.cs index 08d4327fb..b889c289c 100644 --- a/src/IKVM.Tools.Importer/ImportClassLoader.cs +++ b/src/IKVM.Tools.Importer/ImportClassLoader.cs @@ -306,26 +306,22 @@ RuntimeJavaType GetTypeWrapperCompilerHook(string name) } catch (UnsupportedClassVersionException e) { - Context.StaticCompiler.SuppressWarning(state, Diagnostic.ClassNotFound, name); Diagnostics.ClassFormatError(name, e.Message); return null; } catch (ByteCodeException e) { - Context.StaticCompiler.SuppressWarning(state, Diagnostic.ClassNotFound, name); Diagnostics.ClassFormatError(name, e.Message); return null; } catch (ClassFormatError e) { - Context.StaticCompiler.SuppressWarning(state, Diagnostic.ClassNotFound, name); Diagnostics.ClassFormatError(name, e.Message); return null; } if (f.Name != name) { - Context.StaticCompiler.SuppressWarning(state, Diagnostic.ClassNotFound, name); Diagnostics.WrongClassName(name, f.Name); return null; } @@ -434,7 +430,6 @@ RuntimeJavaType GetTypeWrapperCompilerHook(string name) Diagnostics.GenericUnableToCompileError(name, x.GetType().Name, x.Message); } - Context.StaticCompiler.SuppressWarning(state, Diagnostic.ClassNotFound, name); return null; } else @@ -2526,78 +2521,82 @@ private static bool IsSigned(IAssemblySymbol asm) /// internal static int Compile(RuntimeContext context, StaticCompiler compiler, IDiagnosticHandler diagnostics, List imports) { - var loaders = new List(); - - // create class loaders for each import - foreach (var import in imports) + try { - int rc = CreateCompiler(context, compiler, diagnostics, import, out var loader); - if (rc != 0) - return rc; + var loaders = new List(); - loaders.Add(loader); - import.sharedclassloader?.Add(loader); - } + // create class loaders for each import + foreach (var import in imports) + { + int rc = CreateCompiler(context, compiler, diagnostics, import, out var loader); + if (rc != 0) + return rc; - // add a reference between all of the loaders. - foreach (var loader1 in loaders) - foreach (var loader2 in loaders) - if (loader1 != loader2 && (loader1.state.crossReferenceAllPeers || (loader1.state.peerReferences != null && Array.IndexOf(loader1.state.peerReferences, loader2.state.assembly) != -1))) - loader1.AddReference(loader2); + loaders.Add(loader); + import.sharedclassloader?.Add(loader); + } - // first compilation pass - foreach (var loader in loaders) - loader.CompilePass0(); + // add a reference between all of the loaders. + foreach (var loader1 in loaders) + foreach (var loader2 in loaders) + if (loader1 != loader2 && (loader1.state.crossReferenceAllPeers || (loader1.state.peerReferences != null && Array.IndexOf(loader1.state.peerReferences, loader2.state.assembly) != -1))) + loader1.AddReference(loader2); - var mainAssemblyTypes = new Dictionary(); + // first compilation pass + foreach (var loader in loaders) + loader.CompilePass0(); - foreach (var loader in loaders) - { - if (loader.state.sharedclassloader != null) + var mainAssemblyTypes = new Dictionary(); + + foreach (var loader in loaders) { - if (mainAssemblyTypes.TryGetValue(loader.state.sharedclassloader[0], out var mainAssemblyType) == false) + if (loader.state.sharedclassloader != null) { - var tb = loader.state.sharedclassloader[0].GetTypeWrapperFactory().ModuleBuilder.DefineType("__", System.Reflection.TypeAttributes.NotPublic | System.Reflection.TypeAttributes.Abstract | System.Reflection.TypeAttributes.SpecialName); - loader.Context.AttributeHelper.HideFromJava(tb); - tb.Complete(); + if (mainAssemblyTypes.TryGetValue(loader.state.sharedclassloader[0], out var mainAssemblyType) == false) + { + var tb = loader.state.sharedclassloader[0].GetTypeWrapperFactory().ModuleBuilder.DefineType("__", System.Reflection.TypeAttributes.NotPublic | System.Reflection.TypeAttributes.Abstract | System.Reflection.TypeAttributes.SpecialName); + loader.Context.AttributeHelper.HideFromJava(tb); + tb.Complete(); + + mainAssemblyType = tb; + mainAssemblyTypes.Add(loader.state.sharedclassloader[0], mainAssemblyType); + } - mainAssemblyType = tb; - mainAssemblyTypes.Add(loader.state.sharedclassloader[0], mainAssemblyType); + if (loader.state.sharedclassloader[0] != loader) + ((IAssemblySymbolBuilder)loader.GetTypeWrapperFactory().ModuleBuilder.Assembly).AddTypeForwarder(mainAssemblyType); } - if (loader.state.sharedclassloader[0] != loader) - ((IAssemblySymbolBuilder)loader.GetTypeWrapperFactory().ModuleBuilder.Assembly).AddTypeForwarder(mainAssemblyType); + loader.CompilePass1(); } - loader.CompilePass1(); - } - - foreach (var loader in loaders) - loader.CompilePass2(); - - if (context.Options.Bootstrap) foreach (var loader in loaders) - loader.EmitRemappedTypes2ndPass(); + loader.CompilePass2(); - foreach (var loader in loaders) - { - int rc = loader.CompilePass3(); - if (rc != 0) - return rc; - } + if (context.Options.Bootstrap) + foreach (var loader in loaders) + loader.EmitRemappedTypes2ndPass(); - diagnostics.GenericCompilerInfo("CompilerClassLoader.Save..."); + foreach (var loader in loaders) + { + int rc = loader.CompilePass3(); + if (rc != 0) + return rc; + } - foreach (var loader in loaders) - loader.PrepareSave(); + diagnostics.GenericCompilerInfo("CompilerClassLoader.Save..."); - //if (compiler.errorCount > 0) - // return 1; + foreach (var loader in loaders) + loader.PrepareSave(); - foreach (var loader in loaders) - loader.Save(); + foreach (var loader in loaders) + loader.Save(); + } + catch (FileFormatLimitationExceededException e) + { + throw new FatalCompilerErrorException(DiagnosticEvent.FileFormatLimitationExceeded(e.Message)); + } - return 1; + return 0; } static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, IDiagnosticHandler diagnostics, ImportContext import, out ImportClassLoader loader) diff --git a/src/IKVM.Tools.Importer/ImportCommand.cs b/src/IKVM.Tools.Importer/ImportCommand.cs index 10e5803eb..b2e088a8d 100644 --- a/src/IKVM.Tools.Importer/ImportCommand.cs +++ b/src/IKVM.Tools.Importer/ImportCommand.cs @@ -200,15 +200,13 @@ public ImportCommand(bool root = true) aliases: ["-publicpackage"], description: "Mark all classes with a package name starting with as public to the assembly.")); - Add(NoWarnOption = new Option( + Add(NoWarnOption = new Option( aliases: ["-nowarn"], - description: "Disable specific warning messages.", - parseArgument: ParseDiagnosticArray)); + description: "Disable specific warning messages.")); - Add(WarnAsErrorOption = new Option( + Add(WarnAsErrorOption = new Option( aliases: ["-warnaserror"], - description: "Report all warnings as errors.", - parseArgument: ParseDiagnosticArray)); + description: "Report all warnings as errors.")); if (root) Add(RuntimeOption = new Option( @@ -301,23 +299,29 @@ public ImportCommand(bool root = true) /// /// /// - Diagnostic[] ParseDiagnosticArray(ArgumentResult result) + Diagnostic[]? ParseDiagnosticArray(ArgumentResult result) { - var l = new List(); + List? l = null; foreach (var i in result.Tokens) { foreach (var j in i.Value.Split(LIST_SEPARATOR, StringSplitOptions.RemoveEmptyEntries)) { if (int.TryParse(j, out var id) && Diagnostic.GetById(id) is { } diagnostic) + { + l ??= new(); l.Add(diagnostic); + } if (j.StartsWith("IKVM", StringComparison.OrdinalIgnoreCase) && int.TryParse(j["IKVM".Length..], out var id2) && Diagnostic.GetById(id2) is { } diagnostic2) + { + l ??= new(); l.Add(diagnostic2); + } } } - return l.ToArray(); + return l?.ToArray(); } /// @@ -427,9 +431,9 @@ void ValidateResource(OptionResult symbolResult) public Option PublicPackageOption { get; set; } - public Option NoWarnOption { get; set; } + public Option NoWarnOption { get; set; } - public Option WarnAsErrorOption { get; set; } + public Option WarnAsErrorOption { get; set; } public Option? RuntimeOption { get; set; } diff --git a/src/IKVM.Tools.Importer/ImportContext.cs b/src/IKVM.Tools.Importer/ImportContext.cs index ddad70d93..55eefe500 100644 --- a/src/IKVM.Tools.Importer/ImportContext.cs +++ b/src/IKVM.Tools.Importer/ImportContext.cs @@ -29,7 +29,6 @@ Jeroen Frijters using IKVM.CoreLib.Symbols; using IKVM.Reflection; -using IKVM.Reflection.Emit; using IKVM.Runtime; namespace IKVM.Tools.Importer @@ -88,31 +87,28 @@ sealed class ImportContext internal uint fileAlignment; internal bool highentropyva; internal List sharedclassloader; // should *not* be deep copied in Copy(), because we want the list of all compilers that share a class loader - internal HashSet suppressWarnings = new HashSet(StringComparer.OrdinalIgnoreCase); - internal HashSet errorWarnings = new HashSet(StringComparer.OrdinalIgnoreCase); - internal bool warnaserror; // treat all warnings as errors internal List proxies = new(); internal List assemblyAttributeAnnotations = new(); internal bool warningLevelHigh; internal bool noParameterReflection; internal bool bootstrap; - internal string log; + /// + /// Creates a copy of the current . + /// + /// internal ImportContext Copy() { - ImportContext copy = (ImportContext)MemberwiseClone(); + var copy = (ImportContext)MemberwiseClone(); copy.jars = Copy(jars); copy.jarMap = new Dictionary(jarMap); + if (props != null) - { copy.props = new Dictionary(props); - } + if (externalResources != null) - { copy.externalResources = new Dictionary(externalResources); - } - copy.suppressWarnings = new(suppressWarnings, StringComparer.OrdinalIgnoreCase); - copy.errorWarnings = new(errorWarnings, StringComparer.OrdinalIgnoreCase); + return copy; } diff --git a/src/IKVM.Tools.Importer/ImportContextFactory.cs b/src/IKVM.Tools.Importer/ImportContextFactory.cs index ad514c740..b151d670a 100644 --- a/src/IKVM.Tools.Importer/ImportContextFactory.cs +++ b/src/IKVM.Tools.Importer/ImportContextFactory.cs @@ -21,57 +21,6 @@ namespace IKVM.Tools.Importer class ImportContextFactory { - /// - /// for the importer. - /// - class CompilerOptionsDiagnosticHandler : FormattedDiagnosticHandler - { - - readonly ImportContext _options; - - /// - /// Initializes a new instance. - /// - /// - /// - /// - public CompilerOptionsDiagnosticHandler(ImportContext options, string spec, DiagnosticFormatterProvider formatters) : - base(spec, formatters) - { - _options = options ?? throw new ArgumentNullException(nameof(options)); - } - - /// - public override bool IsEnabled(Diagnostic diagnostic) - { - return diagnostic.Level is not DiagnosticLevel.Trace and not DiagnosticLevel.Info; - } - - /// - public override void Report(in DiagnosticEvent @event) - { - if (IsEnabled(@event.Diagnostic) == false) - return; - - var key = @event.Diagnostic.Id.ToString(); - for (int i = 0; ; i++) - { - if (_options.suppressWarnings.Contains(key)) - return; - - if (i == @event.Args.Length) - break; - - key += ":" + @event.Args[i]; - } - - _options.suppressWarnings.Add(key); - - base.Report(@event); - } - - } - readonly RuntimeContext runtime; readonly ImportAssemblyResolver resolver; readonly StaticCompiler compiler; @@ -376,20 +325,6 @@ void Create(ImportOptions options, ImportContext import, List tar foreach (var prefix in options.PublicPackages) import.publicPackages = [.. import.privatePackages, prefix]; - if (options.NoWarn != null) - foreach (var diagnostic in options.NoWarn) - import.suppressWarnings.Add($"IKVM{diagnostic.Id:D4}"); - - // TODO handle specific diagnostic IDs - if (options.WarnAsError != null) - { - if (options.WarnAsError.Length == 0) - import.warnaserror = true; - else - foreach (var i in options.WarnAsError) - import.errorWarnings.Add($"IKVM{i.Id:D4}"); - } - if (options.ClassLoader != null) import.classLoader = options.ClassLoader; diff --git a/src/IKVM.Tools.Importer/ImportDiagnosticHandler.cs b/src/IKVM.Tools.Importer/ImportDiagnosticHandler.cs new file mode 100644 index 000000000..09a816b42 --- /dev/null +++ b/src/IKVM.Tools.Importer/ImportDiagnosticHandler.cs @@ -0,0 +1,50 @@ +using System; +using System.Linq; + +using IKVM.CoreLib.Diagnostics; +using IKVM.Tools.Core.Diagnostics; + +namespace IKVM.Tools.Importer +{ + + /// + /// for the importer. + /// + class ImportDiagnosticHandler : FormattedDiagnosticHandler + { + + readonly ImportOptions _options; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + public ImportDiagnosticHandler(ImportOptions options, string spec, DiagnosticFormatterProvider formatters) : + base(spec, formatters) + { + _options = options ?? throw new ArgumentNullException(nameof(options)); + } + + /// + public override bool IsEnabled(Diagnostic diagnostic) + { + if (diagnostic.Level is DiagnosticLevel.Trace or DiagnosticLevel.Info) + return false; + + if (diagnostic.Level == DiagnosticLevel.Warning && _options.NoWarn.Any(i => i.Id == diagnostic.Id)) + return false; + + return true; + } + + /// + public override void Report(in DiagnosticEvent @event) + { + base.Report(@event); + } + + } + +} diff --git a/src/IKVM.Tools.Importer/ImportOptionsBinding.cs b/src/IKVM.Tools.Importer/ImportOptionsBinding.cs index 97b84affb..be3c464f0 100644 --- a/src/IKVM.Tools.Importer/ImportOptionsBinding.cs +++ b/src/IKVM.Tools.Importer/ImportOptionsBinding.cs @@ -153,10 +153,10 @@ protected override ImportOptions GetBoundValue(BindingContext context) if (context.ParseResult.GetValueForOption(command.PublicPackageOption) is string[] _publicpackages) options.PublicPackages = AppendArray(options.PublicPackages, _publicpackages); - if (context.ParseResult.GetValueForOption(command.NoWarnOption) is Diagnostic[] _nowarn) + if (ParseDiagnosticIdListForOption(context, command.NoWarnOption, LIST_SEPARATOR, null) is Diagnostic[] _nowarn) options.NoWarn = options.NoWarn != null ? AppendArray(options.NoWarn, _nowarn) : _nowarn; - if (context.ParseResult.GetValueForOption(command.WarnAsErrorOption) is Diagnostic[] _warnaserror) + if (ParseDiagnosticIdListForOption(context, command.WarnAsErrorOption, LIST_SEPARATOR, null) is Diagnostic[] _warnaserror) options.WarnAsError = options.WarnAsError != null ? AppendArray(options.WarnAsError, _warnaserror) : _warnaserror; if (command.RuntimeOption != null) @@ -239,10 +239,7 @@ protected override ImportOptions GetBoundValue(BindingContext context) /// T[] AppendArray(T[] a, T[] b) { - var tmp = new T[a.Length + b.Length]; - a.CopyTo(tmp, 0); - b.CopyTo(tmp, a.Length); - return tmp; + return [.. a, .. b]; } /// @@ -299,12 +296,27 @@ T GetParsedValueForOption(BindingContext context, Option option, T d /// /// /// - int[]? ParseDiagnosticIdListForOption(BindingContext context, Option option, char[] separator, int[]? defaultValue) + Diagnostic[]? ParseDiagnosticIdListForOption(BindingContext context, Option option, char[] separator, Diagnostic[]? defaultValue) { if (context.ParseResult.GetValueForOption(option) is string v) - return (int[]?)v.Split(separator, StringSplitOptions.RemoveEmptyEntries).Select(SafeParseDiagnosticId).Where(i => i != null).OfType().ToArray(); - else - return defaultValue; + { + List? l = null; + + foreach (var i in v.Split(separator, StringSplitOptions.RemoveEmptyEntries)) + { + var d = SafeParseDiagnosticId(i); + if (d != null) + { + l ??= []; + l.Add(d); + } + } + + if (l != null) + return l.ToArray(); + } + + return defaultValue; } /// @@ -312,10 +324,10 @@ T GetParsedValueForOption(BindingContext context, Option option, T d /// /// /// - int? SafeParseDiagnosticId(string value) + Diagnostic? SafeParseDiagnosticId(string value) { if (int.TryParse(value, out var i)) - return i; + return Diagnostic.GetById(i); if (value.StartsWith("IKVM", StringComparison.OrdinalIgnoreCase)) return SafeParseDiagnosticId(value["IKVM".Length..]); diff --git a/src/IKVM.Tools.Importer/ImportTool.cs b/src/IKVM.Tools.Importer/ImportTool.cs index aa4a8e6d9..5690e4466 100644 --- a/src/IKVM.Tools.Importer/ImportTool.cs +++ b/src/IKVM.Tools.Importer/ImportTool.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.CommandLine; using System.CommandLine.Builder; using System.CommandLine.Parsing; @@ -25,7 +26,7 @@ namespace IKVM.Tools.Importer /// /// Main entry point for the application. /// - public class ImportTool + public partial class ImportTool { /// @@ -55,7 +56,6 @@ internal static async Task ExecuteInContext(string[] args, CancellationToke /// Executes the importer. /// /// - /// /// /// async Task ExecuteImplAsync(ImportOptions options, CancellationToken cancellationToken) @@ -63,7 +63,9 @@ async Task ExecuteImplAsync(ImportOptions options, CancellationToken cancel var services = new ServiceCollection(); services.AddToolsDiagnostics(); services.AddSingleton(options); - services.AddSingleton(p => GetDiagnostics(p, p.GetRequiredService().Log)); + services.AddSingleton(p => GetDiagnosticOptions(p, p.GetRequiredService())); + services.AddSingleton(p => GetDiagnostics(p, p.GetRequiredService().Log)); + services.AddSingleton(p => p.GetRequiredService()); services.AddSingleton(p => CreateResolver(p.GetRequiredService(), p.GetRequiredService())); services.AddSingleton(p => p.GetRequiredService().Universe); services.AddSingleton(); @@ -74,17 +76,31 @@ async Task ExecuteImplAsync(ImportOptions options, CancellationToken cancel services.AddSingleton(); using var provider = services.BuildServiceProvider(); - // convert options to imports - var imports = provider.GetRequiredService().Create(options); - if (imports.Count == 0) - throw new FatalCompilerErrorException(DiagnosticEvent.NoTargetsFound()); - - // execute the compiler - return await Task.Run(() => Execute( - provider.GetRequiredService(), - provider.GetRequiredService(), - provider.GetRequiredService(), - imports)); + try + { + // convert options to imports + var imports = provider.GetRequiredService().Create(options); + if (imports.Count == 0) + throw new FatalCompilerErrorException(DiagnosticEvent.NoTargetsFound()); + + // execute the compiler + return await Task.Run(() => Execute( + provider.GetRequiredService(), + provider.GetRequiredService(), + provider.GetRequiredService(), + imports)); + } + catch (FatalCompilerErrorException e) + { + provider.GetRequiredService().Report(e.Event); + return e.Event.Diagnostic.Id; + + } + catch (Exception e) + { + provider.GetRequiredService().GenericCompilerError(e.Message); + return Diagnostic.GenericCompilerError.Id; + } } /// @@ -222,14 +238,36 @@ Task ExecuteAsync(ImportOptions options, CancellationToken cancellationToken = d /// /// /// - static FormattedDiagnosticHandler GetDiagnostics(IServiceProvider services, string spec) + static ImportDiagnosticHandler GetDiagnostics(IServiceProvider services, string spec) { if (services is null) throw new ArgumentNullException(nameof(services)); if (string.IsNullOrWhiteSpace(spec)) throw new ArgumentException($"'{nameof(spec)}' cannot be null or whitespace.", nameof(spec)); - return ActivatorUtilities.CreateInstance(services, spec); + return ActivatorUtilities.CreateInstance(services, spec); + } + + /// + /// Generates a diagnostic instance from the diagnostics options. + /// + /// + /// + /// + static DiagnosticOptions GetDiagnosticOptions(IServiceProvider services, ImportOptions options) + { + if (services is null) + throw new ArgumentNullException(nameof(services)); + if (options is null) + throw new ArgumentNullException(nameof(options)); + + return new DiagnosticOptions() + { + NoWarn = options.NoWarn != null && options.NoWarn.Length == 0, + NoWarnDiagnostics = options.NoWarn?.ToImmutableArray() ?? [], + WarnAsError = options.WarnAsError != null && options.WarnAsError.Length == 0, + WarnAsErrorDiagnostics = options.WarnAsError?.ToImmutableArray() ?? [], + }; } /// diff --git a/src/IKVM.Tools.Importer/StaticCompiler.cs b/src/IKVM.Tools.Importer/StaticCompiler.cs index a0ccb68cc..52f8d526c 100644 --- a/src/IKVM.Tools.Importer/StaticCompiler.cs +++ b/src/IKVM.Tools.Importer/StaticCompiler.cs @@ -23,7 +23,6 @@ Jeroen Frijters */ using System; -using System.Collections.Concurrent; using System.IO; using IKVM.CoreLib.Diagnostics; @@ -143,11 +142,6 @@ internal void IssueMissingTypeMessage(ITypeSymbol type) diagnostics.MissingType(type.FullName, type.Assembly.FullName); } - internal void SuppressWarning(ImportContext options, Diagnostic diagnostic, string name) - { - options.suppressWarnings.Add($"{diagnostic.Id}:{name}"); - } - } } \ No newline at end of file diff --git a/src/ikvmc/Properties/launchSettings.json b/src/ikvmc/Properties/launchSettings.json index 31d9cf801..a472b2cda 100644 --- a/src/ikvmc/Properties/launchSettings.json +++ b/src/ikvmc/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "ikvmc": { "commandName": "Project", - "commandLineArgs": "@D:\\ikvm\\src\\IKVM.Java\\obj\\Debug\\net8.0\\IKVM.Java.ikvmc.rsp" + "commandLineArgs": "@D:\\ikvm\\src\\IKVM.Java\\obj\\Debug\\net472\\IKVM.Java.ikvmc.rsp" } } } diff --git a/src/ikvmc/ikvmc.csproj b/src/ikvmc/ikvmc.csproj index 3b5519e29..2be36ac43 100644 --- a/src/ikvmc/ikvmc.csproj +++ b/src/ikvmc/ikvmc.csproj @@ -1,7 +1,7 @@  Exe - net8.0;net472;net6.0; + net472;net8.0;;net6.0; $(_SupportedToolRuntimes) true true From ef32c6287e5fcbffadaca117ee198e687ca8943f Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Fri, 27 Sep 2024 16:13:59 -0500 Subject: [PATCH 15/51] Weee. --- src/IKVM.CoreLib/Diagnostics/Diagnostic.g.cs | 280 ++++++++-------- src/IKVM.CoreLib/Diagnostics/Diagnostic.g.tt | 2 +- src/IKVM.CoreLib/Diagnostics/Diagnostic.t4 | 4 +- .../Diagnostics/DiagnosticEvent.g.cs | 281 ++++++++-------- .../Diagnostics/DiagnosticEvent.g.tt | 2 +- .../Diagnostics/DiagnosticEventException.cs} | 8 +- .../Diagnostics/DiagnosticEventHandler.g.cs | 280 ++++++++-------- .../Diagnostics/DiagnosticEventHandler.g.tt | 2 +- .../Diagnostics/IDiagnosticHandler.g.cs | 280 ++++++++-------- .../Diagnostics/IDiagnosticHandler.g.tt | 2 +- .../Diagnostics/NullDiagnosticHandler.g.cs | 280 ++++++++-------- .../Diagnostics/NullDiagnosticHandler.g.tt | 2 +- .../Tracing/DiagnosticEventSource.g.cs | 280 ++++++++-------- .../Tracing/DiagnosticEventSource.g.tt | 2 +- src/IKVM.CoreLib/Symbols/ISymbolResolver.cs | 6 - .../Emit/IkvmReflectionILGenerator.cs | 2 - src/IKVM.Runtime/AttributeHelper.cs | 26 +- src/IKVM.Runtime/BigEndianBinaryReader.cs | 2 +- src/IKVM.Runtime/BootstrapClassLoader.cs | 2 +- src/IKVM.Runtime/ByteCodeHelper.cs | 4 +- src/IKVM.Runtime/ByteCodeHelperMethods.cs | 2 +- src/IKVM.Runtime/CodeEmitter.cs | 6 +- src/IKVM.Runtime/DynamicCallerIDProvider.cs | 7 +- src/IKVM.Runtime/ExceptionHelper.cs | 4 +- src/IKVM.Runtime/GhostTag.cs | 4 +- src/IKVM.Runtime/IRuntimeSymbolResolver.cs | 64 +++- src/IKVM.Runtime/JNI/JNIEnv.cs | 14 +- src/IKVM.Runtime/JVM.Internal.cs | 20 +- src/IKVM.Runtime/JVM.Properties.cs | 2 +- src/IKVM.Runtime/JVM.Resolver.cs | 184 +++++++++-- .../Java/Externs/ikvm/runtime/Util.cs | 8 +- .../Java/Externs/java/io/ObjectStreamClass.cs | 86 ++--- .../Java/Externs/java/lang/Class.cs | 2 +- .../Java/Externs/java/lang/Package.cs | 2 +- .../Java/Externs/java/lang/reflect/Proxy.cs | 32 +- .../Externs/sun/reflect/ReflectionFactory.cs | 312 +++++++++--------- src/IKVM.Runtime/MethodAnalyzer.cs | 24 +- .../MethodHandleUtil.jniexport.cs | 84 ++--- .../RuntimeAssemblyClassLoader.cs | 2 +- .../RuntimeByteCodeJavaType.FinishContext.cs | 8 +- src/IKVM.Runtime/RuntimeByteCodeJavaType.cs | 6 +- src/IKVM.Runtime/RuntimeClassLoaderFactory.cs | 12 +- src/IKVM.Runtime/RuntimeContextOptions.cs | 9 +- src/IKVM.Runtime/RuntimeJavaType.cs | 2 +- ...anagedByteCodeJavaType.RemappedJavaType.cs | 2 +- .../RuntimeManagedByteCodeJavaType.cs | 12 +- ...gedJavaType.AttributeAnnotationJavaType.cs | 2 +- ...agedJavaType.DelegateInnerClassJavaType.cs | 2 +- ...RuntimeManagedJavaType.EnumEnumJavaType.cs | 2 +- src/IKVM.Runtime/RuntimeManagedJavaType.cs | 2 +- src/IKVM.Runtime/StubGen/StubGenerator.cs | 22 +- .../Invoke/NativeInvokerBytecodeGenerator.cs | 22 +- src/IKVM.Runtime/atomic.cs | 2 +- src/IKVM.Runtime/compiler.cs | 41 ++- src/IKVM.Runtime/intrinsics.cs | 2 +- .../Diagnostics/ConsoleDiagnosticFormatter.cs | 31 +- .../Diagnostics/DiagnosticChannelFormatter.cs | 30 +- .../DiagnosticServiceCollectionExtensions.cs | 1 + .../Diagnostics/IDiagnosticFormatter.cs | 7 + src/IKVM.Tools.Core/IKVM.Tools.Core.csproj | 6 +- src/IKVM.Tools.Exporter/ExportImpl.cs | 9 +- .../ExportRuntimeSymbolResolver.cs | 287 ++++++++++++++++ src/IKVM.Tools.Exporter/ExportTool.cs | 2 +- .../ManagedTypeResolver.cs | 163 --------- .../ImportAssemblyResolver.cs | 4 +- src/IKVM.Tools.Importer/ImportClassLoader.cs | 64 ++-- src/IKVM.Tools.Importer/ImportCommand.cs | 30 -- .../ImportContextFactory.cs | 58 ++-- .../ImportDiagnosticHandler.cs | 4 +- .../ImportRuntimeSymbolResolver.cs | 217 +++++++----- src/IKVM.Tools.Importer/ImportTool.cs | 58 ++-- .../RuntimeImportByteCodeJavaType.cs | 2 +- src/IKVM.Tools.Importer/StaticCompiler.cs | 8 +- src/ikvmc/Properties/launchSettings.json | 2 +- src/ikvmc/ikvmc.csproj | 2 +- src/ikvmstub/Properties/launchSettings.json | 4 +- 76 files changed, 2067 insertions(+), 1676 deletions(-) rename src/{IKVM.Tools.Importer/FatalCompilerErrorException.cs => IKVM.CoreLib/Diagnostics/DiagnosticEventException.cs} (88%) create mode 100644 src/IKVM.Tools.Exporter/ExportRuntimeSymbolResolver.cs delete mode 100644 src/IKVM.Tools.Exporter/ManagedTypeResolver.cs diff --git a/src/IKVM.CoreLib/Diagnostics/Diagnostic.g.cs b/src/IKVM.CoreLib/Diagnostics/Diagnostic.g.cs index 36c9374bf..c5edb304d 100644 --- a/src/IKVM.CoreLib/Diagnostics/Diagnostic.g.cs +++ b/src/IKVM.CoreLib/Diagnostics/Diagnostic.g.cs @@ -302,7 +302,7 @@ partial record class Diagnostic /// The 'MainMethodFound' diagnostic. /// /// -/// Found main method in class "{arg0}". +/// Info: Found main method in class "{arg0}". /// public static readonly Diagnostic MainMethodFound = new Diagnostic(1, nameof(MainMethodFound), "Found main method in class \"{0}\".", DiagnosticLevel.Info); @@ -310,7 +310,7 @@ partial record class Diagnostic /// The 'OutputFileIs' diagnostic. /// /// -/// Output file is "{arg0}". +/// Info: Output file is "{arg0}". /// public static readonly Diagnostic OutputFileIs = new Diagnostic(2, nameof(OutputFileIs), "Output file is \"{0}\".", DiagnosticLevel.Info); @@ -318,7 +318,7 @@ partial record class Diagnostic /// The 'AutoAddRef' diagnostic. /// /// -/// Automatically adding reference to "{arg0}". +/// Info: Automatically adding reference to "{arg0}". /// public static readonly Diagnostic AutoAddRef = new Diagnostic(3, nameof(AutoAddRef), "Automatically adding reference to \"{0}\".", DiagnosticLevel.Info); @@ -326,7 +326,7 @@ partial record class Diagnostic /// The 'MainMethodFromManifest' diagnostic. /// /// -/// Using main class "{arg0}" based on jar manifest. +/// Info: Using main class "{arg0}" based on jar manifest. /// public static readonly Diagnostic MainMethodFromManifest = new Diagnostic(4, nameof(MainMethodFromManifest), "Using main class \"{0}\" based on jar manifest.", DiagnosticLevel.Info); @@ -334,7 +334,7 @@ partial record class Diagnostic /// The 'GenericCompilerInfo' diagnostic. /// /// -/// {arg0} +/// Info: {arg0} /// public static readonly Diagnostic GenericCompilerInfo = new Diagnostic(5, nameof(GenericCompilerInfo), "{0}", DiagnosticLevel.Info); @@ -342,7 +342,7 @@ partial record class Diagnostic /// The 'GenericClassLoadingInfo' diagnostic. /// /// -/// {arg0} +/// Info: {arg0} /// public static readonly Diagnostic GenericClassLoadingInfo = new Diagnostic(6, nameof(GenericClassLoadingInfo), "{0}", DiagnosticLevel.Info); @@ -350,7 +350,7 @@ partial record class Diagnostic /// The 'GenericVerifierInfo' diagnostic. /// /// -/// {arg0} +/// Info: {arg0} /// public static readonly Diagnostic GenericVerifierInfo = new Diagnostic(7, nameof(GenericVerifierInfo), "{0}", DiagnosticLevel.Info); @@ -358,7 +358,7 @@ partial record class Diagnostic /// The 'GenericRuntimeInfo' diagnostic. /// /// -/// {arg0} +/// Info: {arg0} /// public static readonly Diagnostic GenericRuntimeInfo = new Diagnostic(8, nameof(GenericRuntimeInfo), "{0}", DiagnosticLevel.Info); @@ -366,7 +366,7 @@ partial record class Diagnostic /// The 'GenericJniInfo' diagnostic. /// /// -/// {arg0} +/// Info: {arg0} /// public static readonly Diagnostic GenericJniInfo = new Diagnostic(9, nameof(GenericJniInfo), "{0}", DiagnosticLevel.Info); @@ -374,7 +374,7 @@ partial record class Diagnostic /// The 'ClassNotFound' diagnostic. /// /// -/// Class "{arg0}" not found. +/// Warning: Class "{arg0}" not found. /// public static readonly Diagnostic ClassNotFound = new Diagnostic(100, nameof(ClassNotFound), "Class \"{0}\" not found.", DiagnosticLevel.Warning); @@ -382,7 +382,7 @@ partial record class Diagnostic /// The 'ClassFormatError' diagnostic. /// /// -/// Unable to compile class "{arg0}". (class format error "{arg1}") +/// Warning: Unable to compile class "{arg0}". (class format error "{arg1}") /// public static readonly Diagnostic ClassFormatError = new Diagnostic(101, nameof(ClassFormatError), "Unable to compile class \"{0}\". (class format error \"{1}\")", DiagnosticLevel.Warning); @@ -390,7 +390,7 @@ partial record class Diagnostic /// The 'DuplicateClassName' diagnostic. /// /// -/// Duplicate class name: "{arg0}". +/// Warning: Duplicate class name: "{arg0}". /// public static readonly Diagnostic DuplicateClassName = new Diagnostic(102, nameof(DuplicateClassName), "Duplicate class name: \"{0}\".", DiagnosticLevel.Warning); @@ -398,7 +398,7 @@ partial record class Diagnostic /// The 'IllegalAccessError' diagnostic. /// /// -/// Unable to compile class "{arg0}". (illegal access error "{arg1}") +/// Warning: Unable to compile class "{arg0}". (illegal access error "{arg1}") /// public static readonly Diagnostic IllegalAccessError = new Diagnostic(103, nameof(IllegalAccessError), "Unable to compile class \"{0}\". (illegal access error \"{1}\")", DiagnosticLevel.Warning); @@ -406,7 +406,7 @@ partial record class Diagnostic /// The 'VerificationError' diagnostic. /// /// -/// Unable to compile class "{arg0}". (verification error "{arg1}") +/// Warning: Unable to compile class "{arg0}". (verification error "{arg1}") /// public static readonly Diagnostic VerificationError = new Diagnostic(104, nameof(VerificationError), "Unable to compile class \"{0}\". (verification error \"{1}\")", DiagnosticLevel.Warning); @@ -414,7 +414,7 @@ partial record class Diagnostic /// The 'NoClassDefFoundError' diagnostic. /// /// -/// Unable to compile class "{arg0}". (missing class "{arg1}") +/// Warning: Unable to compile class "{arg0}". (missing class "{arg1}") /// public static readonly Diagnostic NoClassDefFoundError = new Diagnostic(105, nameof(NoClassDefFoundError), "Unable to compile class \"{0}\". (missing class \"{1}\")", DiagnosticLevel.Warning); @@ -422,7 +422,7 @@ partial record class Diagnostic /// The 'GenericUnableToCompileError' diagnostic. /// /// -/// Unable to compile class "{arg0}". ("{arg1}": "{arg2}") +/// Warning: Unable to compile class "{arg0}". ("{arg1}": "{arg2}") /// public static readonly Diagnostic GenericUnableToCompileError = new Diagnostic(106, nameof(GenericUnableToCompileError), "Unable to compile class \"{0}\". (\"{1}\": \"{2}\")", DiagnosticLevel.Warning); @@ -430,7 +430,7 @@ partial record class Diagnostic /// The 'DuplicateResourceName' diagnostic. /// /// -/// Skipping resource (name clash): "{arg0}" +/// Warning: Skipping resource (name clash): "{arg0}" /// public static readonly Diagnostic DuplicateResourceName = new Diagnostic(107, nameof(DuplicateResourceName), "Skipping resource (name clash): \"{0}\"", DiagnosticLevel.Warning); @@ -438,7 +438,7 @@ partial record class Diagnostic /// The 'SkippingReferencedClass' diagnostic. /// /// -/// Skipping class: "{arg0}". (class is already available in referenced assembly "{arg1}") +/// Warning: Skipping class: "{arg0}". (class is already available in referenced assembly "{arg1}") /// public static readonly Diagnostic SkippingReferencedClass = new Diagnostic(109, nameof(SkippingReferencedClass), "Skipping class: \"{0}\". (class is already available in referenced assembly \"{1}\")", DiagnosticLevel.Warning); @@ -446,7 +446,7 @@ partial record class Diagnostic /// The 'NoJniRuntime' diagnostic. /// /// -/// Unable to load runtime JNI assembly. +/// Warning: Unable to load runtime JNI assembly. /// public static readonly Diagnostic NoJniRuntime = new Diagnostic(110, nameof(NoJniRuntime), "Unable to load runtime JNI assembly.", DiagnosticLevel.Warning); @@ -454,7 +454,7 @@ partial record class Diagnostic /// The 'EmittedNoClassDefFoundError' diagnostic. /// /// -/// Emitted java.lang.NoClassDefFoundError in "{arg0}". ("{arg1}"). +/// Warning: Emitted java.lang.NoClassDefFoundError in "{arg0}". ("{arg1}"). /// public static readonly Diagnostic EmittedNoClassDefFoundError = new Diagnostic(111, nameof(EmittedNoClassDefFoundError), "Emitted java.lang.NoClassDefFoundError in \"{0}\". (\"{1}\").", DiagnosticLevel.Warning); @@ -462,7 +462,7 @@ partial record class Diagnostic /// The 'EmittedIllegalAccessError' diagnostic. /// /// -/// Emitted java.lang.IllegalAccessError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.IllegalAccessError in "{arg0}". ("{arg1}") /// public static readonly Diagnostic EmittedIllegalAccessError = new Diagnostic(112, nameof(EmittedIllegalAccessError), "Emitted java.lang.IllegalAccessError in \"{0}\". (\"{1}\")", DiagnosticLevel.Warning); @@ -470,7 +470,7 @@ partial record class Diagnostic /// The 'EmittedInstantiationError' diagnostic. /// /// -/// Emitted java.lang.InstantiationError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.InstantiationError in "{arg0}". ("{arg1}") /// public static readonly Diagnostic EmittedInstantiationError = new Diagnostic(113, nameof(EmittedInstantiationError), "Emitted java.lang.InstantiationError in \"{0}\". (\"{1}\")", DiagnosticLevel.Warning); @@ -478,7 +478,7 @@ partial record class Diagnostic /// The 'EmittedIncompatibleClassChangeError' diagnostic. /// /// -/// Emitted java.lang.IncompatibleClassChangeError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.IncompatibleClassChangeError in "{arg0}". ("{arg1}") /// public static readonly Diagnostic EmittedIncompatibleClassChangeError = new Diagnostic(114, nameof(EmittedIncompatibleClassChangeError), "Emitted java.lang.IncompatibleClassChangeError in \"{0}\". (\"{1}\")", DiagnosticLevel.Warning); @@ -486,7 +486,7 @@ partial record class Diagnostic /// The 'EmittedNoSuchFieldError' diagnostic. /// /// -/// Emitted java.lang.NoSuchFieldError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.NoSuchFieldError in "{arg0}". ("{arg1}") /// public static readonly Diagnostic EmittedNoSuchFieldError = new Diagnostic(115, nameof(EmittedNoSuchFieldError), "Emitted java.lang.NoSuchFieldError in \"{0}\". (\"{1}\")", DiagnosticLevel.Warning); @@ -494,7 +494,7 @@ partial record class Diagnostic /// The 'EmittedAbstractMethodError' diagnostic. /// /// -/// Emitted java.lang.AbstractMethodError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.AbstractMethodError in "{arg0}". ("{arg1}") /// public static readonly Diagnostic EmittedAbstractMethodError = new Diagnostic(116, nameof(EmittedAbstractMethodError), "Emitted java.lang.AbstractMethodError in \"{0}\". (\"{1}\")", DiagnosticLevel.Warning); @@ -502,7 +502,7 @@ partial record class Diagnostic /// The 'EmittedNoSuchMethodError' diagnostic. /// /// -/// Emitted java.lang.NoSuchMethodError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.NoSuchMethodError in "{arg0}". ("{arg1}") /// public static readonly Diagnostic EmittedNoSuchMethodError = new Diagnostic(117, nameof(EmittedNoSuchMethodError), "Emitted java.lang.NoSuchMethodError in \"{0}\". (\"{1}\")", DiagnosticLevel.Warning); @@ -510,7 +510,7 @@ partial record class Diagnostic /// The 'EmittedLinkageError' diagnostic. /// /// -/// Emitted java.lang.LinkageError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.LinkageError in "{arg0}". ("{arg1}") /// public static readonly Diagnostic EmittedLinkageError = new Diagnostic(118, nameof(EmittedLinkageError), "Emitted java.lang.LinkageError in \"{0}\". (\"{1}\")", DiagnosticLevel.Warning); @@ -518,7 +518,7 @@ partial record class Diagnostic /// The 'EmittedVerificationError' diagnostic. /// /// -/// Emitted java.lang.VerificationError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.VerificationError in "{arg0}". ("{arg1}") /// public static readonly Diagnostic EmittedVerificationError = new Diagnostic(119, nameof(EmittedVerificationError), "Emitted java.lang.VerificationError in \"{0}\". (\"{1}\")", DiagnosticLevel.Warning); @@ -526,7 +526,7 @@ partial record class Diagnostic /// The 'EmittedClassFormatError' diagnostic. /// /// -/// Emitted java.lang.ClassFormatError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.ClassFormatError in "{arg0}". ("{arg1}") /// public static readonly Diagnostic EmittedClassFormatError = new Diagnostic(120, nameof(EmittedClassFormatError), "Emitted java.lang.ClassFormatError in \"{0}\". (\"{1}\")", DiagnosticLevel.Warning); @@ -534,7 +534,7 @@ partial record class Diagnostic /// The 'InvalidCustomAttribute' diagnostic. /// /// -/// Error emitting "{arg0}" custom attribute. ("{arg1}") +/// Warning: Error emitting "{arg0}" custom attribute. ("{arg1}") /// public static readonly Diagnostic InvalidCustomAttribute = new Diagnostic(121, nameof(InvalidCustomAttribute), "Error emitting \"{0}\" custom attribute. (\"{1}\")", DiagnosticLevel.Warning); @@ -542,7 +542,7 @@ partial record class Diagnostic /// The 'IgnoredCustomAttribute' diagnostic. /// /// -/// Custom attribute "{arg0}" was ignored. ("{arg1}") +/// Warning: Custom attribute "{arg0}" was ignored. ("{arg1}") /// public static readonly Diagnostic IgnoredCustomAttribute = new Diagnostic(122, nameof(IgnoredCustomAttribute), "Custom attribute \"{0}\" was ignored. (\"{1}\")", DiagnosticLevel.Warning); @@ -550,7 +550,7 @@ partial record class Diagnostic /// The 'AssumeAssemblyVersionMatch' diagnostic. /// /// -/// Assuming assembly reference "{arg0}" matches "{arg1}", you may need to supply runtime policy +/// Warning: Assuming assembly reference "{arg0}" matches "{arg1}", you may need to supply runtime policy /// public static readonly Diagnostic AssumeAssemblyVersionMatch = new Diagnostic(123, nameof(AssumeAssemblyVersionMatch), "Assuming assembly reference \"{0}\" matches \"{1}\", you may need to supply runtime p" + "olicy", DiagnosticLevel.Warning); @@ -559,7 +559,7 @@ partial record class Diagnostic /// The 'InvalidDirectoryInLibOptionPath' diagnostic. /// /// -/// Directory "{arg0}" specified in -lib option is not valid. +/// Warning: Directory "{arg0}" specified in -lib option is not valid. /// public static readonly Diagnostic InvalidDirectoryInLibOptionPath = new Diagnostic(124, nameof(InvalidDirectoryInLibOptionPath), "Directory \"{0}\" specified in -lib option is not valid.", DiagnosticLevel.Warning); @@ -567,7 +567,7 @@ partial record class Diagnostic /// The 'InvalidDirectoryInLibEnvironmentPath' diagnostic. /// /// -/// Directory "{arg0}" specified in LIB environment is not valid. +/// Warning: Directory "{arg0}" specified in LIB environment is not valid. /// public static readonly Diagnostic InvalidDirectoryInLibEnvironmentPath = new Diagnostic(125, nameof(InvalidDirectoryInLibEnvironmentPath), "Directory \"{0}\" specified in LIB environment is not valid.", DiagnosticLevel.Warning); @@ -575,7 +575,7 @@ partial record class Diagnostic /// The 'LegacySearchRule' diagnostic. /// /// -/// Found assembly "{arg0}" using legacy search rule, please append '.dll' to the reference. +/// Warning: Found assembly "{arg0}" using legacy search rule, please append '.dll' to the reference. /// public static readonly Diagnostic LegacySearchRule = new Diagnostic(126, nameof(LegacySearchRule), "Found assembly \"{0}\" using legacy search rule, please append \'.dll\' to the refere" + "nce.", DiagnosticLevel.Warning); @@ -584,7 +584,7 @@ partial record class Diagnostic /// The 'AssemblyLocationIgnored' diagnostic. /// /// -/// Assembly "{arg0}" is ignored as previously loaded assembly "{arg1}" has the same identity "{arg2}". +/// Warning: Assembly "{arg0}" is ignored as previously loaded assembly "{arg1}" has the same identity "{arg2}". /// public static readonly Diagnostic AssemblyLocationIgnored = new Diagnostic(127, nameof(AssemblyLocationIgnored), "Assembly \"{0}\" is ignored as previously loaded assembly \"{1}\" has the same identi" + "ty \"{2}\".", DiagnosticLevel.Warning); @@ -593,7 +593,7 @@ partial record class Diagnostic /// The 'InterfaceMethodCantBeInternal' diagnostic. /// /// -/// Ignoring @ikvm.lang.Internal annotation on interface method. ("{arg0}.{arg1}{arg2}") +/// Warning: Ignoring @ikvm.lang.Internal annotation on interface method. ("{arg0}.{arg1}{arg2}") /// public static readonly Diagnostic InterfaceMethodCantBeInternal = new Diagnostic(128, nameof(InterfaceMethodCantBeInternal), "Ignoring @ikvm.lang.Internal annotation on interface method. (\"{0}.{1}{2}\")", DiagnosticLevel.Warning); @@ -601,7 +601,7 @@ partial record class Diagnostic /// The 'DuplicateAssemblyReference' diagnostic. /// /// -/// Duplicate assembly reference "{arg0}" +/// Warning: Duplicate assembly reference "{arg0}" /// public static readonly Diagnostic DuplicateAssemblyReference = new Diagnostic(132, nameof(DuplicateAssemblyReference), "Duplicate assembly reference \"{0}\"", DiagnosticLevel.Warning); @@ -609,7 +609,7 @@ partial record class Diagnostic /// The 'UnableToResolveType' diagnostic. /// /// -/// Reference in "{arg0}" to type "{arg1}" claims it is defined in "{arg2}", but it could not be found. +/// Warning: Reference in "{arg0}" to type "{arg1}" claims it is defined in "{arg2}", but it could not be found. /// public static readonly Diagnostic UnableToResolveType = new Diagnostic(133, nameof(UnableToResolveType), "Reference in \"{0}\" to type \"{1}\" claims it is defined in \"{2}\", but it could not " + "be found.", DiagnosticLevel.Warning); @@ -618,7 +618,7 @@ partial record class Diagnostic /// The 'StubsAreDeprecated' diagnostic. /// /// -/// Compiling stubs is deprecated. Please add a reference to assembly "{arg0}" instead. +/// Warning: Compiling stubs is deprecated. Please add a reference to assembly "{arg0}" instead. /// public static readonly Diagnostic StubsAreDeprecated = new Diagnostic(134, nameof(StubsAreDeprecated), "Compiling stubs is deprecated. Please add a reference to assembly \"{0}\" instead.", DiagnosticLevel.Warning); @@ -626,7 +626,7 @@ partial record class Diagnostic /// The 'WrongClassName' diagnostic. /// /// -/// Unable to compile "{arg0}" (wrong name: "{arg1}") +/// Warning: Unable to compile "{arg0}" (wrong name: "{arg1}") /// public static readonly Diagnostic WrongClassName = new Diagnostic(135, nameof(WrongClassName), "Unable to compile \"{0}\" (wrong name: \"{1}\")", DiagnosticLevel.Warning); @@ -634,7 +634,7 @@ partial record class Diagnostic /// The 'ReflectionCallerClassRequiresCallerID' diagnostic. /// /// -/// Reflection.getCallerClass() called from non-CallerID method. ("{arg0}.{arg1}{arg2}") +/// Warning: Reflection.getCallerClass() called from non-CallerID method. ("{arg0}.{arg1}{arg2}") /// public static readonly Diagnostic ReflectionCallerClassRequiresCallerID = new Diagnostic(136, nameof(ReflectionCallerClassRequiresCallerID), "Reflection.getCallerClass() called from non-CallerID method. (\"{0}.{1}{2}\")", DiagnosticLevel.Warning); @@ -642,7 +642,7 @@ partial record class Diagnostic /// The 'LegacyAssemblyAttributesFound' diagnostic. /// /// -/// Legacy assembly attributes container found. Please use the -assemblyattributes: option. +/// Warning: Legacy assembly attributes container found. Please use the -assemblyattributes: option. /// public static readonly Diagnostic LegacyAssemblyAttributesFound = new Diagnostic(137, nameof(LegacyAssemblyAttributesFound), "Legacy assembly attributes container found. Please use the -assemblyattributes: option.", DiagnosticLevel.Warning); @@ -651,7 +651,7 @@ partial record class Diagnostic /// The 'UnableToCreateLambdaFactory' diagnostic. /// /// -/// Unable to create static lambda factory. +/// Warning: Unable to create static lambda factory. /// public static readonly Diagnostic UnableToCreateLambdaFactory = new Diagnostic(138, nameof(UnableToCreateLambdaFactory), "Unable to create static lambda factory.", DiagnosticLevel.Warning); @@ -659,7 +659,7 @@ partial record class Diagnostic /// The 'UnknownWarning' diagnostic. /// /// -/// {arg0} +/// Warning: {arg0} /// public static readonly Diagnostic UnknownWarning = new Diagnostic(999, nameof(UnknownWarning), "{0}", DiagnosticLevel.Warning); @@ -667,7 +667,7 @@ partial record class Diagnostic /// The 'DuplicateIkvmLangProperty' diagnostic. /// /// -/// Ignoring duplicate ikvm.lang.Property annotation on {arg0}.{arg1}. +/// Warning: Ignoring duplicate ikvm.lang.Property annotation on {arg0}.{arg1}. /// public static readonly Diagnostic DuplicateIkvmLangProperty = new Diagnostic(139, nameof(DuplicateIkvmLangProperty), "Ignoring duplicate ikvm.lang.Property annotation on {0}.{1}.", DiagnosticLevel.Warning); @@ -675,7 +675,7 @@ partial record class Diagnostic /// The 'MalformedIkvmLangProperty' diagnostic. /// /// -/// Ignoring duplicate ikvm.lang.Property annotation on {arg0}.{arg1}. +/// Warning: Ignoring duplicate ikvm.lang.Property annotation on {arg0}.{arg1}. /// public static readonly Diagnostic MalformedIkvmLangProperty = new Diagnostic(140, nameof(MalformedIkvmLangProperty), "Ignoring duplicate ikvm.lang.Property annotation on {0}.{1}.", DiagnosticLevel.Warning); @@ -683,7 +683,7 @@ partial record class Diagnostic /// The 'GenericCompilerWarning' diagnostic. /// /// -/// {arg0} +/// Warning: {arg0} /// public static readonly Diagnostic GenericCompilerWarning = new Diagnostic(141, nameof(GenericCompilerWarning), "{0}", DiagnosticLevel.Warning); @@ -691,7 +691,7 @@ partial record class Diagnostic /// The 'GenericClassLoadingWarning' diagnostic. /// /// -/// {arg0} +/// Warning: {arg0} /// public static readonly Diagnostic GenericClassLoadingWarning = new Diagnostic(142, nameof(GenericClassLoadingWarning), "{0}", DiagnosticLevel.Warning); @@ -699,7 +699,7 @@ partial record class Diagnostic /// The 'GenericVerifierWarning' diagnostic. /// /// -/// {arg0} +/// Warning: {arg0} /// public static readonly Diagnostic GenericVerifierWarning = new Diagnostic(143, nameof(GenericVerifierWarning), "{0}", DiagnosticLevel.Warning); @@ -707,7 +707,7 @@ partial record class Diagnostic /// The 'GenericRuntimeWarning' diagnostic. /// /// -/// {arg0} +/// Warning: {arg0} /// public static readonly Diagnostic GenericRuntimeWarning = new Diagnostic(144, nameof(GenericRuntimeWarning), "{0}", DiagnosticLevel.Warning); @@ -715,7 +715,7 @@ partial record class Diagnostic /// The 'GenericJniWarning' diagnostic. /// /// -/// {arg0} +/// Warning: {arg0} /// public static readonly Diagnostic GenericJniWarning = new Diagnostic(145, nameof(GenericJniWarning), "{0}", DiagnosticLevel.Warning); @@ -723,7 +723,7 @@ partial record class Diagnostic /// The 'UnableToCreateProxy' diagnostic. /// /// -/// Unable to create proxy "{arg0}". ("{arg1}") +/// Error: Unable to create proxy "{arg0}". ("{arg1}") /// public static readonly Diagnostic UnableToCreateProxy = new Diagnostic(4001, nameof(UnableToCreateProxy), "Unable to create proxy \"{0}\". (\"{1}\")", DiagnosticLevel.Error); @@ -731,7 +731,7 @@ partial record class Diagnostic /// The 'DuplicateProxy' diagnostic. /// /// -/// Duplicate proxy "{arg0}". +/// Error: Duplicate proxy "{arg0}". /// public static readonly Diagnostic DuplicateProxy = new Diagnostic(4002, nameof(DuplicateProxy), "Duplicate proxy \"{0}\".", DiagnosticLevel.Error); @@ -739,7 +739,7 @@ partial record class Diagnostic /// The 'MapXmlUnableToResolveOpCode' diagnostic. /// /// -/// Unable to resolve opcode in remap file: {arg0}. +/// Error: Unable to resolve opcode in remap file: {arg0}. /// public static readonly Diagnostic MapXmlUnableToResolveOpCode = new Diagnostic(4003, nameof(MapXmlUnableToResolveOpCode), "Unable to resolve opcode in remap file: {0}.", DiagnosticLevel.Error); @@ -747,7 +747,7 @@ partial record class Diagnostic /// The 'MapXmlError' diagnostic. /// /// -/// Error in remap file: {arg0}. +/// Error: Error in remap file: {arg0}. /// public static readonly Diagnostic MapXmlError = new Diagnostic(4004, nameof(MapXmlError), "Error in remap file: {0}.", DiagnosticLevel.Error); @@ -755,7 +755,7 @@ partial record class Diagnostic /// The 'InputFileNotFound' diagnostic. /// /// -/// Source file '{arg0}' not found. +/// Error: Source file '{arg0}' not found. /// public static readonly Diagnostic InputFileNotFound = new Diagnostic(4005, nameof(InputFileNotFound), "Source file \'{0}\' not found.", DiagnosticLevel.Error); @@ -763,7 +763,7 @@ partial record class Diagnostic /// The 'UnknownFileType' diagnostic. /// /// -/// Unknown file type: {arg0}. +/// Error: Unknown file type: {arg0}. /// public static readonly Diagnostic UnknownFileType = new Diagnostic(4006, nameof(UnknownFileType), "Unknown file type: {0}.", DiagnosticLevel.Error); @@ -771,7 +771,7 @@ partial record class Diagnostic /// The 'UnknownElementInMapFile' diagnostic. /// /// -/// Unknown element {arg0} in remap file, line {arg1}, column {arg2}. +/// Error: Unknown element {arg0} in remap file, line {arg1}, column {arg2}. /// public static readonly Diagnostic UnknownElementInMapFile = new Diagnostic(4007, nameof(UnknownElementInMapFile), "Unknown element {0} in remap file, line {1}, column {2}.", DiagnosticLevel.Error); @@ -779,7 +779,7 @@ partial record class Diagnostic /// The 'UnknownAttributeInMapFile' diagnostic. /// /// -/// Unknown attribute {arg0} in remap file, line {arg1}, column {arg2}. +/// Error: Unknown attribute {arg0} in remap file, line {arg1}, column {arg2}. /// public static readonly Diagnostic UnknownAttributeInMapFile = new Diagnostic(4008, nameof(UnknownAttributeInMapFile), "Unknown attribute {0} in remap file, line {1}, column {2}.", DiagnosticLevel.Error); @@ -787,7 +787,7 @@ partial record class Diagnostic /// The 'InvalidMemberNameInMapFile' diagnostic. /// /// -/// Invalid {arg0} name '{arg1}' in remap file in class {arg2}. +/// Error: Invalid {arg0} name '{arg1}' in remap file in class {arg2}. /// public static readonly Diagnostic InvalidMemberNameInMapFile = new Diagnostic(4009, nameof(InvalidMemberNameInMapFile), "Invalid {0} name \'{1}\' in remap file in class {2}.", DiagnosticLevel.Error); @@ -795,7 +795,7 @@ partial record class Diagnostic /// The 'InvalidMemberSignatureInMapFile' diagnostic. /// /// -/// Invalid {arg0} signature '{arg3}' in remap file for {arg0} {arg1}.{arg2}. +/// Error: Invalid {arg0} signature '{arg3}' in remap file for {arg0} {arg1}.{arg2}. /// public static readonly Diagnostic InvalidMemberSignatureInMapFile = new Diagnostic(4010, nameof(InvalidMemberSignatureInMapFile), "Invalid {0} signature \'{3}\' in remap file for {0} {1}.{2}.", DiagnosticLevel.Error); @@ -803,7 +803,7 @@ partial record class Diagnostic /// The 'InvalidPropertyNameInMapFile' diagnostic. /// /// -/// Invalid property {arg0} name '{arg3}' in remap file for property {arg1}.{arg2}. +/// Error: Invalid property {arg0} name '{arg3}' in remap file for property {arg1}.{arg2}. /// public static readonly Diagnostic InvalidPropertyNameInMapFile = new Diagnostic(4011, nameof(InvalidPropertyNameInMapFile), "Invalid property {0} name \'{3}\' in remap file for property {1}.{2}.", DiagnosticLevel.Error); @@ -811,7 +811,7 @@ partial record class Diagnostic /// The 'InvalidPropertySignatureInMapFile' diagnostic. /// /// -/// Invalid property {arg0} signature '{arg3}' in remap file for property {arg1}.{arg2}. +/// Error: Invalid property {arg0} signature '{arg3}' in remap file for property {arg1}.{arg2}. /// public static readonly Diagnostic InvalidPropertySignatureInMapFile = new Diagnostic(4012, nameof(InvalidPropertySignatureInMapFile), "Invalid property {0} signature \'{3}\' in remap file for property {1}.{2}.", DiagnosticLevel.Error); @@ -819,7 +819,7 @@ partial record class Diagnostic /// The 'NonPrimaryAssemblyReference' diagnostic. /// /// -/// Referenced assembly "{arg0}" is not the primary assembly of a shared class loader group, please reference primary assembly "{arg1}" instead. +/// Error: Referenced assembly "{arg0}" is not the primary assembly of a shared class loader group, please reference primary assembly "{arg1}" instead. /// public static readonly Diagnostic NonPrimaryAssemblyReference = new Diagnostic(4013, nameof(NonPrimaryAssemblyReference), "Referenced assembly \"{0}\" is not the primary assembly of a shared class loader gr" + "oup, please reference primary assembly \"{1}\" instead.", DiagnosticLevel.Error); @@ -828,7 +828,7 @@ partial record class Diagnostic /// The 'MissingType' diagnostic. /// /// -/// Reference to type "{arg0}" claims it is defined in "{arg1}", but it could not be found. +/// Error: Reference to type "{arg0}" claims it is defined in "{arg1}", but it could not be found. /// public static readonly Diagnostic MissingType = new Diagnostic(4014, nameof(MissingType), "Reference to type \"{0}\" claims it is defined in \"{1}\", but it could not be found." + "", DiagnosticLevel.Error); @@ -837,7 +837,7 @@ partial record class Diagnostic /// The 'MissingReference' diagnostic. /// /// -/// The type '{arg0}' is defined in an assembly that is notResponseFileDepthExceeded referenced. You must add a reference to assembly '{arg1}'. +/// Error: The type '{arg0}' is defined in an assembly that is notResponseFileDepthExceeded referenced. You must add a reference to assembly '{arg1}'. /// public static readonly Diagnostic MissingReference = new Diagnostic(4015, nameof(MissingReference), "The type \'{0}\' is defined in an assembly that is notResponseFileDepthExceeded ref" + "erenced. You must add a reference to assembly \'{1}\'.", DiagnosticLevel.Error); @@ -846,7 +846,7 @@ partial record class Diagnostic /// The 'CallerSensitiveOnUnsupportedMethod' diagnostic. /// /// -/// CallerSensitive annotation on unsupported method. ("{arg0}.{arg1}{arg2}") +/// Error: CallerSensitive annotation on unsupported method. ("{arg0}.{arg1}{arg2}") /// public static readonly Diagnostic CallerSensitiveOnUnsupportedMethod = new Diagnostic(4016, nameof(CallerSensitiveOnUnsupportedMethod), "CallerSensitive annotation on unsupported method. (\"{0}.{1}{2}\")", DiagnosticLevel.Error); @@ -854,7 +854,7 @@ partial record class Diagnostic /// The 'RemappedTypeMissingDefaultInterfaceMethod' diagnostic. /// /// -/// {arg0} does not implement default interface method {arg1}. +/// Error: {arg0} does not implement default interface method {arg1}. /// public static readonly Diagnostic RemappedTypeMissingDefaultInterfaceMethod = new Diagnostic(4017, nameof(RemappedTypeMissingDefaultInterfaceMethod), "{0} does not implement default interface method {1}.", DiagnosticLevel.Error); @@ -862,7 +862,7 @@ partial record class Diagnostic /// The 'GenericCompilerError' diagnostic. /// /// -/// {arg0} +/// Error: {arg0} /// public static readonly Diagnostic GenericCompilerError = new Diagnostic(4018, nameof(GenericCompilerError), "{0}", DiagnosticLevel.Error); @@ -870,7 +870,7 @@ partial record class Diagnostic /// The 'GenericClassLoadingError' diagnostic. /// /// -/// {arg0} +/// Error: {arg0} /// public static readonly Diagnostic GenericClassLoadingError = new Diagnostic(4019, nameof(GenericClassLoadingError), "{0}", DiagnosticLevel.Error); @@ -878,7 +878,7 @@ partial record class Diagnostic /// The 'GenericVerifierError' diagnostic. /// /// -/// {arg0} +/// Error: {arg0} /// public static readonly Diagnostic GenericVerifierError = new Diagnostic(4020, nameof(GenericVerifierError), "{0}", DiagnosticLevel.Error); @@ -886,7 +886,7 @@ partial record class Diagnostic /// The 'GenericRuntimeError' diagnostic. /// /// -/// {arg0} +/// Error: {arg0} /// public static readonly Diagnostic GenericRuntimeError = new Diagnostic(4021, nameof(GenericRuntimeError), "{0}", DiagnosticLevel.Error); @@ -894,7 +894,7 @@ partial record class Diagnostic /// The 'GenericJniError' diagnostic. /// /// -/// {arg0} +/// Error: {arg0} /// public static readonly Diagnostic GenericJniError = new Diagnostic(4022, nameof(GenericJniError), "{0}", DiagnosticLevel.Error); @@ -902,7 +902,7 @@ partial record class Diagnostic /// The 'ExportingImportsNotSupported' diagnostic. /// /// -/// Exporting previously imported assemblies is not supported. +/// Error: Exporting previously imported assemblies is not supported. /// public static readonly Diagnostic ExportingImportsNotSupported = new Diagnostic(4023, nameof(ExportingImportsNotSupported), "Exporting previously imported assemblies is not supported.", DiagnosticLevel.Error); @@ -910,7 +910,7 @@ partial record class Diagnostic /// The 'ResponseFileDepthExceeded' diagnostic. /// /// -/// Response file nesting depth exceeded. +/// Fatal: Response file nesting depth exceeded. /// public static readonly Diagnostic ResponseFileDepthExceeded = new Diagnostic(5000, nameof(ResponseFileDepthExceeded), "Response file nesting depth exceeded.", DiagnosticLevel.Fatal); @@ -918,7 +918,7 @@ partial record class Diagnostic /// The 'ErrorReadingFile' diagnostic. /// /// -/// Unable to read file: {arg0}. ({arg1}) +/// Fatal: Unable to read file: {arg0}. ({arg1}) /// public static readonly Diagnostic ErrorReadingFile = new Diagnostic(5001, nameof(ErrorReadingFile), "Unable to read file: {0}. ({1})", DiagnosticLevel.Fatal); @@ -926,7 +926,7 @@ partial record class Diagnostic /// The 'NoTargetsFound' diagnostic. /// /// -/// No targets found +/// Fatal: No targets found /// public static readonly Diagnostic NoTargetsFound = new Diagnostic(5002, nameof(NoTargetsFound), "No targets found", DiagnosticLevel.Fatal); @@ -934,7 +934,7 @@ partial record class Diagnostic /// The 'FileFormatLimitationExceeded' diagnostic. /// /// -/// File format limitation exceeded: {arg0}. +/// Fatal: File format limitation exceeded: {arg0}. /// public static readonly Diagnostic FileFormatLimitationExceeded = new Diagnostic(5003, nameof(FileFormatLimitationExceeded), "File format limitation exceeded: {0}.", DiagnosticLevel.Fatal); @@ -942,7 +942,7 @@ partial record class Diagnostic /// The 'CannotSpecifyBothKeyFileAndContainer' diagnostic. /// /// -/// You cannot specify both a key file and container. +/// Fatal: You cannot specify both a key file and container. /// public static readonly Diagnostic CannotSpecifyBothKeyFileAndContainer = new Diagnostic(5004, nameof(CannotSpecifyBothKeyFileAndContainer), "You cannot specify both a key file and container.", DiagnosticLevel.Fatal); @@ -950,7 +950,7 @@ partial record class Diagnostic /// The 'DelaySignRequiresKey' diagnostic. /// /// -/// You cannot delay sign without a key file or container. +/// Fatal: You cannot delay sign without a key file or container. /// public static readonly Diagnostic DelaySignRequiresKey = new Diagnostic(5005, nameof(DelaySignRequiresKey), "You cannot delay sign without a key file or container.", DiagnosticLevel.Fatal); @@ -958,7 +958,7 @@ partial record class Diagnostic /// The 'InvalidStrongNameKeyPair' diagnostic. /// /// -/// Invalid key {arg0} specified. ("{arg1}") +/// Fatal: Invalid key {arg0} specified. ("{arg1}") /// public static readonly Diagnostic InvalidStrongNameKeyPair = new Diagnostic(5006, nameof(InvalidStrongNameKeyPair), "Invalid key {0} specified. (\"{1}\")", DiagnosticLevel.Fatal); @@ -966,7 +966,7 @@ partial record class Diagnostic /// The 'ReferenceNotFound' diagnostic. /// /// -/// Reference not found: {arg0} +/// Fatal: Reference not found: {arg0} /// public static readonly Diagnostic ReferenceNotFound = new Diagnostic(5007, nameof(ReferenceNotFound), "Reference not found: {0}", DiagnosticLevel.Fatal); @@ -974,7 +974,7 @@ partial record class Diagnostic /// The 'OptionsMustPreceedChildLevels' diagnostic. /// /// -/// You can only specify options before any child levels. +/// Fatal: You can only specify options before any child levels. /// public static readonly Diagnostic OptionsMustPreceedChildLevels = new Diagnostic(5008, nameof(OptionsMustPreceedChildLevels), "You can only specify options before any child levels.", DiagnosticLevel.Fatal); @@ -982,7 +982,7 @@ partial record class Diagnostic /// The 'UnrecognizedTargetType' diagnostic. /// /// -/// Invalid value '{arg0}' for -target option. +/// Fatal: Invalid value '{arg0}' for -target option. /// public static readonly Diagnostic UnrecognizedTargetType = new Diagnostic(5009, nameof(UnrecognizedTargetType), "Invalid value \'{0}\' for -target option.", DiagnosticLevel.Fatal); @@ -990,7 +990,7 @@ partial record class Diagnostic /// The 'UnrecognizedPlatform' diagnostic. /// /// -/// Invalid value '{arg0}' for -platform option. +/// Fatal: Invalid value '{arg0}' for -platform option. /// public static readonly Diagnostic UnrecognizedPlatform = new Diagnostic(5010, nameof(UnrecognizedPlatform), "Invalid value \'{0}\' for -platform option.", DiagnosticLevel.Fatal); @@ -998,7 +998,7 @@ partial record class Diagnostic /// The 'UnrecognizedApartment' diagnostic. /// /// -/// Invalid value '{arg0}' for -apartment option. +/// Fatal: Invalid value '{arg0}' for -apartment option. /// public static readonly Diagnostic UnrecognizedApartment = new Diagnostic(5011, nameof(UnrecognizedApartment), "Invalid value \'{0}\' for -apartment option.", DiagnosticLevel.Fatal); @@ -1006,7 +1006,7 @@ partial record class Diagnostic /// The 'MissingFileSpecification' diagnostic. /// /// -/// Missing file specification for '{arg0}' option. +/// Fatal: Missing file specification for '{arg0}' option. /// public static readonly Diagnostic MissingFileSpecification = new Diagnostic(5012, nameof(MissingFileSpecification), "Missing file specification for \'{0}\' option.", DiagnosticLevel.Fatal); @@ -1014,7 +1014,7 @@ partial record class Diagnostic /// The 'PathTooLong' diagnostic. /// /// -/// Path too long: {arg0}. +/// Fatal: Path too long: {arg0}. /// public static readonly Diagnostic PathTooLong = new Diagnostic(5013, nameof(PathTooLong), "Path too long: {0}.", DiagnosticLevel.Fatal); @@ -1022,7 +1022,7 @@ partial record class Diagnostic /// The 'PathNotFound' diagnostic. /// /// -/// Path not found: {arg0}. +/// Fatal: Path not found: {arg0}. /// public static readonly Diagnostic PathNotFound = new Diagnostic(5014, nameof(PathNotFound), "Path not found: {0}.", DiagnosticLevel.Fatal); @@ -1030,7 +1030,7 @@ partial record class Diagnostic /// The 'InvalidPath' diagnostic. /// /// -/// Invalid path: {arg0}. +/// Fatal: Invalid path: {arg0}. /// public static readonly Diagnostic InvalidPath = new Diagnostic(5015, nameof(InvalidPath), "Invalid path: {0}.", DiagnosticLevel.Fatal); @@ -1038,7 +1038,7 @@ partial record class Diagnostic /// The 'InvalidOptionSyntax' diagnostic. /// /// -/// Invalid option: {arg0}. +/// Fatal: Invalid option: {arg0}. /// public static readonly Diagnostic InvalidOptionSyntax = new Diagnostic(5016, nameof(InvalidOptionSyntax), "Invalid option: {0}.", DiagnosticLevel.Fatal); @@ -1046,7 +1046,7 @@ partial record class Diagnostic /// The 'ExternalResourceNotFound' diagnostic. /// /// -/// External resource file does not exist: {arg0}. +/// Fatal: External resource file does not exist: {arg0}. /// public static readonly Diagnostic ExternalResourceNotFound = new Diagnostic(5017, nameof(ExternalResourceNotFound), "External resource file does not exist: {0}.", DiagnosticLevel.Fatal); @@ -1054,7 +1054,7 @@ partial record class Diagnostic /// The 'ExternalResourceNameInvalid' diagnostic. /// /// -/// External resource file may not include path specification: {arg0}. +/// Fatal: External resource file may not include path specification: {arg0}. /// public static readonly Diagnostic ExternalResourceNameInvalid = new Diagnostic(5018, nameof(ExternalResourceNameInvalid), "External resource file may not include path specification: {0}.", DiagnosticLevel.Fatal); @@ -1062,7 +1062,7 @@ partial record class Diagnostic /// The 'InvalidVersionFormat' diagnostic. /// /// -/// Invalid version specified: {arg0}. +/// Fatal: Invalid version specified: {arg0}. /// public static readonly Diagnostic InvalidVersionFormat = new Diagnostic(5019, nameof(InvalidVersionFormat), "Invalid version specified: {0}.", DiagnosticLevel.Fatal); @@ -1070,7 +1070,7 @@ partial record class Diagnostic /// The 'InvalidFileAlignment' diagnostic. /// /// -/// Invalid value '{arg0}' for -filealign option. +/// Fatal: Invalid value '{arg0}' for -filealign option. /// public static readonly Diagnostic InvalidFileAlignment = new Diagnostic(5020, nameof(InvalidFileAlignment), "Invalid value \'{0}\' for -filealign option.", DiagnosticLevel.Fatal); @@ -1078,7 +1078,7 @@ partial record class Diagnostic /// The 'ErrorWritingFile' diagnostic. /// /// -/// Unable to write file: {arg0}. ({arg1}) +/// Fatal: Unable to write file: {arg0}. ({arg1}) /// public static readonly Diagnostic ErrorWritingFile = new Diagnostic(5021, nameof(ErrorWritingFile), "Unable to write file: {0}. ({1})", DiagnosticLevel.Fatal); @@ -1086,7 +1086,7 @@ partial record class Diagnostic /// The 'UnrecognizedOption' diagnostic. /// /// -/// Unrecognized option: {arg0}. +/// Fatal: Unrecognized option: {arg0}. /// public static readonly Diagnostic UnrecognizedOption = new Diagnostic(5022, nameof(UnrecognizedOption), "Unrecognized option: {0}.", DiagnosticLevel.Fatal); @@ -1094,7 +1094,7 @@ partial record class Diagnostic /// The 'NoOutputFileSpecified' diagnostic. /// /// -/// No output file specified. +/// Fatal: No output file specified. /// public static readonly Diagnostic NoOutputFileSpecified = new Diagnostic(5023, nameof(NoOutputFileSpecified), "No output file specified.", DiagnosticLevel.Fatal); @@ -1102,7 +1102,7 @@ partial record class Diagnostic /// The 'SharedClassLoaderCannotBeUsedOnModuleTarget' diagnostic. /// /// -/// Incompatible options: -target:module and -sharedclassloader cannot be combined. +/// Fatal: Incompatible options: -target:module and -sharedclassloader cannot be combined. /// public static readonly Diagnostic SharedClassLoaderCannotBeUsedOnModuleTarget = new Diagnostic(5024, nameof(SharedClassLoaderCannotBeUsedOnModuleTarget), "Incompatible options: -target:module and -sharedclassloader cannot be combined.", DiagnosticLevel.Fatal); @@ -1110,7 +1110,7 @@ partial record class Diagnostic /// The 'RuntimeNotFound' diagnostic. /// /// -/// Unable to load runtime assembly. +/// Fatal: Unable to load runtime assembly. /// public static readonly Diagnostic RuntimeNotFound = new Diagnostic(5025, nameof(RuntimeNotFound), "Unable to load runtime assembly.", DiagnosticLevel.Fatal); @@ -1118,7 +1118,7 @@ partial record class Diagnostic /// The 'MainClassRequiresExe' diagnostic. /// /// -/// Main class cannot be specified for library or module. +/// Fatal: Main class cannot be specified for library or module. /// public static readonly Diagnostic MainClassRequiresExe = new Diagnostic(5026, nameof(MainClassRequiresExe), "Main class cannot be specified for library or module.", DiagnosticLevel.Fatal); @@ -1126,7 +1126,7 @@ partial record class Diagnostic /// The 'ExeRequiresMainClass' diagnostic. /// /// -/// No main method found. +/// Fatal: No main method found. /// public static readonly Diagnostic ExeRequiresMainClass = new Diagnostic(5027, nameof(ExeRequiresMainClass), "No main method found.", DiagnosticLevel.Fatal); @@ -1134,7 +1134,7 @@ partial record class Diagnostic /// The 'PropertiesRequireExe' diagnostic. /// /// -/// Properties cannot be specified for library or module. +/// Fatal: Properties cannot be specified for library or module. /// public static readonly Diagnostic PropertiesRequireExe = new Diagnostic(5028, nameof(PropertiesRequireExe), "Properties cannot be specified for library or module.", DiagnosticLevel.Fatal); @@ -1142,7 +1142,7 @@ partial record class Diagnostic /// The 'ModuleCannotHaveClassLoader' diagnostic. /// /// -/// Cannot specify assembly class loader for modules. +/// Fatal: Cannot specify assembly class loader for modules. /// public static readonly Diagnostic ModuleCannotHaveClassLoader = new Diagnostic(5029, nameof(ModuleCannotHaveClassLoader), "Cannot specify assembly class loader for modules.", DiagnosticLevel.Fatal); @@ -1150,7 +1150,7 @@ partial record class Diagnostic /// The 'ErrorParsingMapFile' diagnostic. /// /// -/// Unable to parse remap file: {arg0}. ({arg1}) +/// Fatal: Unable to parse remap file: {arg0}. ({arg1}) /// public static readonly Diagnostic ErrorParsingMapFile = new Diagnostic(5030, nameof(ErrorParsingMapFile), "Unable to parse remap file: {0}. ({1})", DiagnosticLevel.Fatal); @@ -1158,7 +1158,7 @@ partial record class Diagnostic /// The 'BootstrapClassesMissing' diagnostic. /// /// -/// Bootstrap classes missing and core assembly not found. +/// Fatal: Bootstrap classes missing and core assembly not found. /// public static readonly Diagnostic BootstrapClassesMissing = new Diagnostic(5031, nameof(BootstrapClassesMissing), "Bootstrap classes missing and core assembly not found.", DiagnosticLevel.Fatal); @@ -1166,7 +1166,7 @@ partial record class Diagnostic /// The 'StrongNameRequiresStrongNamedRefs' diagnostic. /// /// -/// All referenced assemblies must be strong named, to be able to sign the output assembly. +/// Fatal: All referenced assemblies must be strong named, to be able to sign the output assembly. /// public static readonly Diagnostic StrongNameRequiresStrongNamedRefs = new Diagnostic(5032, nameof(StrongNameRequiresStrongNamedRefs), "All referenced assemblies must be strong named, to be able to sign the output ass" + "embly.", DiagnosticLevel.Fatal); @@ -1175,7 +1175,7 @@ partial record class Diagnostic /// The 'MainClassNotFound' diagnostic. /// /// -/// Main class not found. +/// Fatal: Main class not found. /// public static readonly Diagnostic MainClassNotFound = new Diagnostic(5033, nameof(MainClassNotFound), "Main class not found.", DiagnosticLevel.Fatal); @@ -1183,7 +1183,7 @@ partial record class Diagnostic /// The 'MainMethodNotFound' diagnostic. /// /// -/// Main method not found. +/// Fatal: Main method not found. /// public static readonly Diagnostic MainMethodNotFound = new Diagnostic(5034, nameof(MainMethodNotFound), "Main method not found.", DiagnosticLevel.Fatal); @@ -1191,7 +1191,7 @@ partial record class Diagnostic /// The 'UnsupportedMainMethod' diagnostic. /// /// -/// Redirected main method not supported. +/// Fatal: Redirected main method not supported. /// public static readonly Diagnostic UnsupportedMainMethod = new Diagnostic(5035, nameof(UnsupportedMainMethod), "Redirected main method not supported.", DiagnosticLevel.Fatal); @@ -1199,7 +1199,7 @@ partial record class Diagnostic /// The 'ExternalMainNotAccessible' diagnostic. /// /// -/// External main method must be public and in a public class. +/// Fatal: External main method must be public and in a public class. /// public static readonly Diagnostic ExternalMainNotAccessible = new Diagnostic(5036, nameof(ExternalMainNotAccessible), "External main method must be public and in a public class.", DiagnosticLevel.Fatal); @@ -1207,7 +1207,7 @@ partial record class Diagnostic /// The 'ClassLoaderNotFound' diagnostic. /// /// -/// Custom assembly class loader class not found. +/// Fatal: Custom assembly class loader class not found. /// public static readonly Diagnostic ClassLoaderNotFound = new Diagnostic(5037, nameof(ClassLoaderNotFound), "Custom assembly class loader class not found.", DiagnosticLevel.Fatal); @@ -1215,7 +1215,7 @@ partial record class Diagnostic /// The 'ClassLoaderNotAccessible' diagnostic. /// /// -/// Custom assembly class loader class is not accessible. +/// Fatal: Custom assembly class loader class is not accessible. /// public static readonly Diagnostic ClassLoaderNotAccessible = new Diagnostic(5038, nameof(ClassLoaderNotAccessible), "Custom assembly class loader class is not accessible.", DiagnosticLevel.Fatal); @@ -1223,7 +1223,7 @@ partial record class Diagnostic /// The 'ClassLoaderIsAbstract' diagnostic. /// /// -/// Custom assembly class loader class is abstract. +/// Fatal: Custom assembly class loader class is abstract. /// public static readonly Diagnostic ClassLoaderIsAbstract = new Diagnostic(5039, nameof(ClassLoaderIsAbstract), "Custom assembly class loader class is abstract.", DiagnosticLevel.Fatal); @@ -1231,7 +1231,7 @@ partial record class Diagnostic /// The 'ClassLoaderNotClassLoader' diagnostic. /// /// -/// Custom assembly class loader class does not extend java.lang.ClassLoader. +/// Fatal: Custom assembly class loader class does not extend java.lang.ClassLoader. /// public static readonly Diagnostic ClassLoaderNotClassLoader = new Diagnostic(5040, nameof(ClassLoaderNotClassLoader), "Custom assembly class loader class does not extend java.lang.ClassLoader.", DiagnosticLevel.Fatal); @@ -1239,7 +1239,7 @@ partial record class Diagnostic /// The 'ClassLoaderConstructorMissing' diagnostic. /// /// -/// Custom assembly class loader constructor is missing. +/// Fatal: Custom assembly class loader constructor is missing. /// public static readonly Diagnostic ClassLoaderConstructorMissing = new Diagnostic(5041, nameof(ClassLoaderConstructorMissing), "Custom assembly class loader constructor is missing.", DiagnosticLevel.Fatal); @@ -1247,7 +1247,7 @@ partial record class Diagnostic /// The 'MapFileTypeNotFound' diagnostic. /// /// -/// Type '{arg0}' referenced in remap file was not found. +/// Fatal: Type '{arg0}' referenced in remap file was not found. /// public static readonly Diagnostic MapFileTypeNotFound = new Diagnostic(5042, nameof(MapFileTypeNotFound), "Type \'{0}\' referenced in remap file was not found.", DiagnosticLevel.Fatal); @@ -1255,7 +1255,7 @@ partial record class Diagnostic /// The 'MapFileClassNotFound' diagnostic. /// /// -/// Class '{arg0}' referenced in remap file was not found. +/// Fatal: Class '{arg0}' referenced in remap file was not found. /// public static readonly Diagnostic MapFileClassNotFound = new Diagnostic(5043, nameof(MapFileClassNotFound), "Class \'{0}\' referenced in remap file was not found.", DiagnosticLevel.Fatal); @@ -1263,7 +1263,7 @@ partial record class Diagnostic /// The 'MaximumErrorCountReached' diagnostic. /// /// -/// Maximum error count reached. +/// Fatal: Maximum error count reached. /// public static readonly Diagnostic MaximumErrorCountReached = new Diagnostic(5044, nameof(MaximumErrorCountReached), "Maximum error count reached.", DiagnosticLevel.Fatal); @@ -1271,7 +1271,7 @@ partial record class Diagnostic /// The 'LinkageError' diagnostic. /// /// -/// Link error: {arg0} +/// Fatal: Link error: {arg0} /// public static readonly Diagnostic LinkageError = new Diagnostic(5045, nameof(LinkageError), "Link error: {0}", DiagnosticLevel.Fatal); @@ -1279,7 +1279,7 @@ partial record class Diagnostic /// The 'RuntimeMismatch' diagnostic. /// /// -/// Referenced assembly {referencedAssemblyPath} was compiled with an incompatible IKVM.Runtime version. Current runtime: {runtimeAssemblyName}. Referenced assembly runtime: {referencedAssemblyName} +/// Fatal: Referenced assembly {referencedAssemblyPath} was compiled with an incompatible IKVM.Runtime version. Current runtime: {runtimeAssemblyName}. Referenced assembly runtime: {referencedAssemblyName} /// public static readonly Diagnostic RuntimeMismatch = new Diagnostic(5046, nameof(RuntimeMismatch), "Referenced assembly {0} was compiled with an incompatible IKVM.Runtime version. C" + "urrent runtime: {1}. Referenced assembly runtime: {2}", DiagnosticLevel.Fatal); @@ -1288,7 +1288,7 @@ partial record class Diagnostic /// The 'RuntimeMismatchStrongName' diagnostic. /// /// -/// +/// Fatal: /// public static readonly Diagnostic RuntimeMismatchStrongName = new Diagnostic(5047, nameof(RuntimeMismatchStrongName), "", DiagnosticLevel.Fatal); @@ -1296,7 +1296,7 @@ partial record class Diagnostic /// The 'CoreClassesMissing' diagnostic. /// /// -/// Failed to find core classes in core library. +/// Fatal: Failed to find core classes in core library. /// public static readonly Diagnostic CoreClassesMissing = new Diagnostic(5048, nameof(CoreClassesMissing), "Failed to find core classes in core library.", DiagnosticLevel.Fatal); @@ -1304,7 +1304,7 @@ partial record class Diagnostic /// The 'CriticalClassNotFound' diagnostic. /// /// -/// Unable to load critical class '{arg0}'. +/// Fatal: Unable to load critical class '{arg0}'. /// public static readonly Diagnostic CriticalClassNotFound = new Diagnostic(5049, nameof(CriticalClassNotFound), "Unable to load critical class \'{0}\'.", DiagnosticLevel.Fatal); @@ -1312,7 +1312,7 @@ partial record class Diagnostic /// The 'AssemblyContainsDuplicateClassNames' diagnostic. /// /// -/// Type '{arg0}' and '{arg1}' both map to the same name '{arg2}'. ({arg3}) +/// Fatal: Type '{arg0}' and '{arg1}' both map to the same name '{arg2}'. ({arg3}) /// public static readonly Diagnostic AssemblyContainsDuplicateClassNames = new Diagnostic(5050, nameof(AssemblyContainsDuplicateClassNames), "Type \'{0}\' and \'{1}\' both map to the same name \'{2}\'. ({3})", DiagnosticLevel.Fatal); @@ -1320,7 +1320,7 @@ partial record class Diagnostic /// The 'CallerIDRequiresHasCallerIDAnnotation' diagnostic. /// /// -/// CallerID.getCallerID() requires a HasCallerID annotation. +/// Fatal: CallerID.getCallerID() requires a HasCallerID annotation. /// public static readonly Diagnostic CallerIDRequiresHasCallerIDAnnotation = new Diagnostic(5051, nameof(CallerIDRequiresHasCallerIDAnnotation), "CallerID.getCallerID() requires a HasCallerID annotation.", DiagnosticLevel.Fatal); @@ -1328,7 +1328,7 @@ partial record class Diagnostic /// The 'UnableToResolveInterface' diagnostic. /// /// -/// Unable to resolve interface '{arg0}' on type '{arg1}'. +/// Fatal: Unable to resolve interface '{arg0}' on type '{arg1}'. /// public static readonly Diagnostic UnableToResolveInterface = new Diagnostic(5052, nameof(UnableToResolveInterface), "Unable to resolve interface \'{0}\' on type \'{1}\'.", DiagnosticLevel.Fatal); @@ -1336,7 +1336,7 @@ partial record class Diagnostic /// The 'MissingBaseType' diagnostic. /// /// -/// The base class or interface '{arg0}' in assembly '{arg1}' referenced by type '{arg2}' in '{arg3}' could not be resolved. +/// Fatal: The base class or interface '{arg0}' in assembly '{arg1}' referenced by type '{arg2}' in '{arg3}' could not be resolved. /// public static readonly Diagnostic MissingBaseType = new Diagnostic(5053, nameof(MissingBaseType), "The base class or interface \'{0}\' in assembly \'{1}\' referenced by type \'{2}\' in \'" + "{3}\' could not be resolved.", DiagnosticLevel.Fatal); @@ -1345,7 +1345,7 @@ partial record class Diagnostic /// The 'MissingBaseTypeReference' diagnostic. /// /// -/// The type '{arg0}' is defined in an assembly that is not referenced. You must add a reference to assembly '{arg1}'. +/// Fatal: The type '{arg0}' is defined in an assembly that is not referenced. You must add a reference to assembly '{arg1}'. /// public static readonly Diagnostic MissingBaseTypeReference = new Diagnostic(5054, nameof(MissingBaseTypeReference), "The type \'{0}\' is defined in an assembly that is not referenced. You must add a r" + "eference to assembly \'{1}\'.", DiagnosticLevel.Fatal); @@ -1354,7 +1354,7 @@ partial record class Diagnostic /// The 'FileNotFound' diagnostic. /// /// -/// File not found: {arg0}. +/// Fatal: File not found: {arg0}. /// public static readonly Diagnostic FileNotFound = new Diagnostic(5055, nameof(FileNotFound), "File not found: {0}.", DiagnosticLevel.Fatal); @@ -1362,7 +1362,7 @@ partial record class Diagnostic /// The 'RuntimeMethodMissing' diagnostic. /// /// -/// Runtime method '{arg0}' not found. +/// Fatal: Runtime method '{arg0}' not found. /// public static readonly Diagnostic RuntimeMethodMissing = new Diagnostic(5056, nameof(RuntimeMethodMissing), "Runtime method \'{0}\' not found.", DiagnosticLevel.Fatal); @@ -1370,7 +1370,7 @@ partial record class Diagnostic /// The 'MapFileFieldNotFound' diagnostic. /// /// -/// Field '{arg0}' referenced in remap file was not found in class '{arg1}'. +/// Fatal: Field '{arg0}' referenced in remap file was not found in class '{arg1}'. /// public static readonly Diagnostic MapFileFieldNotFound = new Diagnostic(5057, nameof(MapFileFieldNotFound), "Field \'{0}\' referenced in remap file was not found in class \'{1}\'.", DiagnosticLevel.Fatal); @@ -1378,7 +1378,7 @@ partial record class Diagnostic /// The 'GhostInterfaceMethodMissing' diagnostic. /// /// -/// Remapped class '{arg0}' does not implement ghost interface method. ({arg1}.{arg2}{arg3}) +/// Fatal: Remapped class '{arg0}' does not implement ghost interface method. ({arg1}.{arg2}{arg3}) /// public static readonly Diagnostic GhostInterfaceMethodMissing = new Diagnostic(5058, nameof(GhostInterfaceMethodMissing), "Remapped class \'{0}\' does not implement ghost interface method. ({1}.{2}{3})", DiagnosticLevel.Fatal); @@ -1386,7 +1386,7 @@ partial record class Diagnostic /// The 'ModuleInitializerMethodRequirements' diagnostic. /// /// -/// Method '{arg1}.{arg2}{arg3}' does not meet the requirements of a module initializer. +/// Fatal: Method '{arg1}.{arg2}{arg3}' does not meet the requirements of a module initializer. /// public static readonly Diagnostic ModuleInitializerMethodRequirements = new Diagnostic(5059, nameof(ModuleInitializerMethodRequirements), "Method \'{0}.{1}{2}\' does not meet the requirements of a module initializer.", DiagnosticLevel.Fatal); @@ -1394,7 +1394,7 @@ partial record class Diagnostic /// The 'InvalidZip' diagnostic. /// /// -/// Invalid zip: {name}. +/// Fatal: Invalid zip: {name}. /// public static readonly Diagnostic InvalidZip = new Diagnostic(5060, nameof(InvalidZip), "Invalid zip: {0}.", DiagnosticLevel.Fatal); @@ -1402,7 +1402,7 @@ partial record class Diagnostic /// The 'CoreAssemblyVersionMismatch' diagnostic. /// /// -/// Unable to load assembly '{0}' as it depends on a higher version of {1} than the one currently loaded. +/// Fatal: Unable to load assembly '{0}' as it depends on a higher version of {1} than the one currently loaded. /// public static readonly Diagnostic CoreAssemblyVersionMismatch = new Diagnostic(5061, nameof(CoreAssemblyVersionMismatch), "Unable to load assembly \'{-1}\' as it depends on a higher version of {-1} than the" + " one currently loaded.", DiagnosticLevel.Fatal); @@ -1411,7 +1411,7 @@ partial record class Diagnostic /// The 'GenericRuntimeTrace' diagnostic. /// /// -/// {arg0} +/// Trace: {arg0} /// public static readonly Diagnostic GenericRuntimeTrace = new Diagnostic(6000, nameof(GenericRuntimeTrace), "{0}", DiagnosticLevel.Trace); @@ -1419,7 +1419,7 @@ partial record class Diagnostic /// The 'GenericJniTrace' diagnostic. /// /// -/// {arg0} +/// Trace: {arg0} /// public static readonly Diagnostic GenericJniTrace = new Diagnostic(6001, nameof(GenericJniTrace), "{0}", DiagnosticLevel.Trace); @@ -1427,7 +1427,7 @@ partial record class Diagnostic /// The 'GenericCompilerTrace' diagnostic. /// /// -/// {arg0} +/// Trace: {arg0} /// public static readonly Diagnostic GenericCompilerTrace = new Diagnostic(6002, nameof(GenericCompilerTrace), "{0}", DiagnosticLevel.Trace); diff --git a/src/IKVM.CoreLib/Diagnostics/Diagnostic.g.tt b/src/IKVM.CoreLib/Diagnostics/Diagnostic.g.tt index 975d42ffb..6d64b0865 100644 --- a/src/IKVM.CoreLib/Diagnostics/Diagnostic.g.tt +++ b/src/IKVM.CoreLib/Diagnostics/Diagnostic.g.tt @@ -63,7 +63,7 @@ foreach (var kvp in DiagnosticFile.Read(Host.ResolvePath(Path.Combine("Diagnosti /// <#= desc #> /// /// -<#= Util.ToCommentString(kvp.Value.Message ?? "") #> +<#= Util.ToCommentString(kvp.Value) #> /// public static readonly Diagnostic <#= kvp.Key #> = new Diagnostic(<#= kvp.Value.Id #>, nameof(<#= kvp.Key #>), <#= Util.ToStringLiteral(string.Join("", message)) #>, DiagnosticLevel.<#= kvp.Value.Level #>); diff --git a/src/IKVM.CoreLib/Diagnostics/Diagnostic.t4 b/src/IKVM.CoreLib/Diagnostics/Diagnostic.t4 index e7fe51849..eaf85ec04 100644 --- a/src/IKVM.CoreLib/Diagnostics/Diagnostic.t4 +++ b/src/IKVM.CoreLib/Diagnostics/Diagnostic.t4 @@ -56,13 +56,13 @@ public static class Util } } - public static string ToCommentString(string input) + public static string ToCommentString(Diagnostic diagnostic) { using (var writer = new StringWriter()) { using (var provider = CodeDomProvider.CreateProvider("CSharp")) { - provider.GenerateCodeFromStatement(new CodeCommentStatement(input, true), writer, null); + provider.GenerateCodeFromStatement(new CodeCommentStatement(diagnostic.Level + ": " + diagnostic.Message, true), writer, null); return writer.ToString().Trim(); } } diff --git a/src/IKVM.CoreLib/Diagnostics/DiagnosticEvent.g.cs b/src/IKVM.CoreLib/Diagnostics/DiagnosticEvent.g.cs index 0ad8a07f3..6d96eb2c8 100644 --- a/src/IKVM.CoreLib/Diagnostics/DiagnosticEvent.g.cs +++ b/src/IKVM.CoreLib/Diagnostics/DiagnosticEvent.g.cs @@ -1,5 +1,6 @@ #nullable enable using System; +using System.Text; namespace IKVM.CoreLib.Diagnostics { @@ -11,7 +12,7 @@ readonly partial struct DiagnosticEvent /// The 'MainMethodFound' diagnostic. /// /// -/// Found main method in class "{arg0}". +/// Info: Found main method in class "{arg0}". /// public static DiagnosticEvent MainMethodFound(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.MainMethodFound.Event([arg0], exception, location); @@ -19,7 +20,7 @@ readonly partial struct DiagnosticEvent /// The 'OutputFileIs' diagnostic. /// /// -/// Output file is "{arg0}". +/// Info: Output file is "{arg0}". /// public static DiagnosticEvent OutputFileIs(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.OutputFileIs.Event([arg0], exception, location); @@ -27,7 +28,7 @@ readonly partial struct DiagnosticEvent /// The 'AutoAddRef' diagnostic. /// /// -/// Automatically adding reference to "{arg0}". +/// Info: Automatically adding reference to "{arg0}". /// public static DiagnosticEvent AutoAddRef(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.AutoAddRef.Event([arg0], exception, location); @@ -35,7 +36,7 @@ readonly partial struct DiagnosticEvent /// The 'MainMethodFromManifest' diagnostic. /// /// -/// Using main class "{arg0}" based on jar manifest. +/// Info: Using main class "{arg0}" based on jar manifest. /// public static DiagnosticEvent MainMethodFromManifest(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.MainMethodFromManifest.Event([arg0], exception, location); @@ -43,7 +44,7 @@ readonly partial struct DiagnosticEvent /// The 'GenericCompilerInfo' diagnostic. /// /// -/// {arg0} +/// Info: {arg0} /// public static DiagnosticEvent GenericCompilerInfo(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.GenericCompilerInfo.Event([arg0], exception, location); @@ -51,7 +52,7 @@ readonly partial struct DiagnosticEvent /// The 'GenericClassLoadingInfo' diagnostic. /// /// -/// {arg0} +/// Info: {arg0} /// public static DiagnosticEvent GenericClassLoadingInfo(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.GenericClassLoadingInfo.Event([arg0], exception, location); @@ -59,7 +60,7 @@ readonly partial struct DiagnosticEvent /// The 'GenericVerifierInfo' diagnostic. /// /// -/// {arg0} +/// Info: {arg0} /// public static DiagnosticEvent GenericVerifierInfo(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.GenericVerifierInfo.Event([arg0], exception, location); @@ -67,7 +68,7 @@ readonly partial struct DiagnosticEvent /// The 'GenericRuntimeInfo' diagnostic. /// /// -/// {arg0} +/// Info: {arg0} /// public static DiagnosticEvent GenericRuntimeInfo(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.GenericRuntimeInfo.Event([arg0], exception, location); @@ -75,7 +76,7 @@ readonly partial struct DiagnosticEvent /// The 'GenericJniInfo' diagnostic. /// /// -/// {arg0} +/// Info: {arg0} /// public static DiagnosticEvent GenericJniInfo(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.GenericJniInfo.Event([arg0], exception, location); @@ -83,7 +84,7 @@ readonly partial struct DiagnosticEvent /// The 'ClassNotFound' diagnostic. /// /// -/// Class "{arg0}" not found. +/// Warning: Class "{arg0}" not found. /// public static DiagnosticEvent ClassNotFound(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.ClassNotFound.Event([arg0], exception, location); @@ -91,7 +92,7 @@ readonly partial struct DiagnosticEvent /// The 'ClassFormatError' diagnostic. /// /// -/// Unable to compile class "{arg0}". (class format error "{arg1}") +/// Warning: Unable to compile class "{arg0}". (class format error "{arg1}") /// public static DiagnosticEvent ClassFormatError(string arg0, string arg1, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.ClassFormatError.Event([arg0, arg1], exception, location); @@ -99,7 +100,7 @@ readonly partial struct DiagnosticEvent /// The 'DuplicateClassName' diagnostic. /// /// -/// Duplicate class name: "{arg0}". +/// Warning: Duplicate class name: "{arg0}". /// public static DiagnosticEvent DuplicateClassName(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.DuplicateClassName.Event([arg0], exception, location); @@ -107,7 +108,7 @@ readonly partial struct DiagnosticEvent /// The 'IllegalAccessError' diagnostic. /// /// -/// Unable to compile class "{arg0}". (illegal access error "{arg1}") +/// Warning: Unable to compile class "{arg0}". (illegal access error "{arg1}") /// public static DiagnosticEvent IllegalAccessError(string arg0, string arg1, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.IllegalAccessError.Event([arg0, arg1], exception, location); @@ -115,7 +116,7 @@ readonly partial struct DiagnosticEvent /// The 'VerificationError' diagnostic. /// /// -/// Unable to compile class "{arg0}". (verification error "{arg1}") +/// Warning: Unable to compile class "{arg0}". (verification error "{arg1}") /// public static DiagnosticEvent VerificationError(string arg0, string arg1, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.VerificationError.Event([arg0, arg1], exception, location); @@ -123,7 +124,7 @@ readonly partial struct DiagnosticEvent /// The 'NoClassDefFoundError' diagnostic. /// /// -/// Unable to compile class "{arg0}". (missing class "{arg1}") +/// Warning: Unable to compile class "{arg0}". (missing class "{arg1}") /// public static DiagnosticEvent NoClassDefFoundError(string arg0, string arg1, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.NoClassDefFoundError.Event([arg0, arg1], exception, location); @@ -131,7 +132,7 @@ readonly partial struct DiagnosticEvent /// The 'GenericUnableToCompileError' diagnostic. /// /// -/// Unable to compile class "{arg0}". ("{arg1}": "{arg2}") +/// Warning: Unable to compile class "{arg0}". ("{arg1}": "{arg2}") /// public static DiagnosticEvent GenericUnableToCompileError(string arg0, string arg1, string arg2, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.GenericUnableToCompileError.Event([arg0, arg1, arg2], exception, location); @@ -139,7 +140,7 @@ readonly partial struct DiagnosticEvent /// The 'DuplicateResourceName' diagnostic. /// /// -/// Skipping resource (name clash): "{arg0}" +/// Warning: Skipping resource (name clash): "{arg0}" /// public static DiagnosticEvent DuplicateResourceName(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.DuplicateResourceName.Event([arg0], exception, location); @@ -147,7 +148,7 @@ readonly partial struct DiagnosticEvent /// The 'SkippingReferencedClass' diagnostic. /// /// -/// Skipping class: "{arg0}". (class is already available in referenced assembly "{arg1}") +/// Warning: Skipping class: "{arg0}". (class is already available in referenced assembly "{arg1}") /// public static DiagnosticEvent SkippingReferencedClass(string arg0, string arg1, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.SkippingReferencedClass.Event([arg0, arg1], exception, location); @@ -155,7 +156,7 @@ readonly partial struct DiagnosticEvent /// The 'NoJniRuntime' diagnostic. /// /// -/// Unable to load runtime JNI assembly. +/// Warning: Unable to load runtime JNI assembly. /// public static DiagnosticEvent NoJniRuntime(Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.NoJniRuntime.Event([], exception, location); @@ -163,7 +164,7 @@ readonly partial struct DiagnosticEvent /// The 'EmittedNoClassDefFoundError' diagnostic. /// /// -/// Emitted java.lang.NoClassDefFoundError in "{arg0}". ("{arg1}"). +/// Warning: Emitted java.lang.NoClassDefFoundError in "{arg0}". ("{arg1}"). /// public static DiagnosticEvent EmittedNoClassDefFoundError(string arg0, string arg1, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.EmittedNoClassDefFoundError.Event([arg0, arg1], exception, location); @@ -171,7 +172,7 @@ readonly partial struct DiagnosticEvent /// The 'EmittedIllegalAccessError' diagnostic. /// /// -/// Emitted java.lang.IllegalAccessError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.IllegalAccessError in "{arg0}". ("{arg1}") /// public static DiagnosticEvent EmittedIllegalAccessError(string arg0, string arg1, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.EmittedIllegalAccessError.Event([arg0, arg1], exception, location); @@ -179,7 +180,7 @@ readonly partial struct DiagnosticEvent /// The 'EmittedInstantiationError' diagnostic. /// /// -/// Emitted java.lang.InstantiationError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.InstantiationError in "{arg0}". ("{arg1}") /// public static DiagnosticEvent EmittedInstantiationError(string arg0, string arg1, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.EmittedInstantiationError.Event([arg0, arg1], exception, location); @@ -187,7 +188,7 @@ readonly partial struct DiagnosticEvent /// The 'EmittedIncompatibleClassChangeError' diagnostic. /// /// -/// Emitted java.lang.IncompatibleClassChangeError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.IncompatibleClassChangeError in "{arg0}". ("{arg1}") /// public static DiagnosticEvent EmittedIncompatibleClassChangeError(string arg0, string arg1, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.EmittedIncompatibleClassChangeError.Event([arg0, arg1], exception, location); @@ -195,7 +196,7 @@ readonly partial struct DiagnosticEvent /// The 'EmittedNoSuchFieldError' diagnostic. /// /// -/// Emitted java.lang.NoSuchFieldError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.NoSuchFieldError in "{arg0}". ("{arg1}") /// public static DiagnosticEvent EmittedNoSuchFieldError(string arg0, string arg1, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.EmittedNoSuchFieldError.Event([arg0, arg1], exception, location); @@ -203,7 +204,7 @@ readonly partial struct DiagnosticEvent /// The 'EmittedAbstractMethodError' diagnostic. /// /// -/// Emitted java.lang.AbstractMethodError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.AbstractMethodError in "{arg0}". ("{arg1}") /// public static DiagnosticEvent EmittedAbstractMethodError(string arg0, string arg1, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.EmittedAbstractMethodError.Event([arg0, arg1], exception, location); @@ -211,7 +212,7 @@ readonly partial struct DiagnosticEvent /// The 'EmittedNoSuchMethodError' diagnostic. /// /// -/// Emitted java.lang.NoSuchMethodError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.NoSuchMethodError in "{arg0}". ("{arg1}") /// public static DiagnosticEvent EmittedNoSuchMethodError(string arg0, string arg1, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.EmittedNoSuchMethodError.Event([arg0, arg1], exception, location); @@ -219,7 +220,7 @@ readonly partial struct DiagnosticEvent /// The 'EmittedLinkageError' diagnostic. /// /// -/// Emitted java.lang.LinkageError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.LinkageError in "{arg0}". ("{arg1}") /// public static DiagnosticEvent EmittedLinkageError(string arg0, string arg1, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.EmittedLinkageError.Event([arg0, arg1], exception, location); @@ -227,7 +228,7 @@ readonly partial struct DiagnosticEvent /// The 'EmittedVerificationError' diagnostic. /// /// -/// Emitted java.lang.VerificationError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.VerificationError in "{arg0}". ("{arg1}") /// public static DiagnosticEvent EmittedVerificationError(string arg0, string arg1, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.EmittedVerificationError.Event([arg0, arg1], exception, location); @@ -235,7 +236,7 @@ readonly partial struct DiagnosticEvent /// The 'EmittedClassFormatError' diagnostic. /// /// -/// Emitted java.lang.ClassFormatError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.ClassFormatError in "{arg0}". ("{arg1}") /// public static DiagnosticEvent EmittedClassFormatError(string arg0, string arg1, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.EmittedClassFormatError.Event([arg0, arg1], exception, location); @@ -243,7 +244,7 @@ readonly partial struct DiagnosticEvent /// The 'InvalidCustomAttribute' diagnostic. /// /// -/// Error emitting "{arg0}" custom attribute. ("{arg1}") +/// Warning: Error emitting "{arg0}" custom attribute. ("{arg1}") /// public static DiagnosticEvent InvalidCustomAttribute(string arg0, string arg1, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.InvalidCustomAttribute.Event([arg0, arg1], exception, location); @@ -251,7 +252,7 @@ readonly partial struct DiagnosticEvent /// The 'IgnoredCustomAttribute' diagnostic. /// /// -/// Custom attribute "{arg0}" was ignored. ("{arg1}") +/// Warning: Custom attribute "{arg0}" was ignored. ("{arg1}") /// public static DiagnosticEvent IgnoredCustomAttribute(string arg0, string arg1, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.IgnoredCustomAttribute.Event([arg0, arg1], exception, location); @@ -259,7 +260,7 @@ readonly partial struct DiagnosticEvent /// The 'AssumeAssemblyVersionMatch' diagnostic. /// /// -/// Assuming assembly reference "{arg0}" matches "{arg1}", you may need to supply runtime policy +/// Warning: Assuming assembly reference "{arg0}" matches "{arg1}", you may need to supply runtime policy /// public static DiagnosticEvent AssumeAssemblyVersionMatch(string arg0, string arg1, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.AssumeAssemblyVersionMatch.Event([arg0, arg1], exception, location); @@ -267,7 +268,7 @@ readonly partial struct DiagnosticEvent /// The 'InvalidDirectoryInLibOptionPath' diagnostic. /// /// -/// Directory "{arg0}" specified in -lib option is not valid. +/// Warning: Directory "{arg0}" specified in -lib option is not valid. /// public static DiagnosticEvent InvalidDirectoryInLibOptionPath(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.InvalidDirectoryInLibOptionPath.Event([arg0], exception, location); @@ -275,7 +276,7 @@ readonly partial struct DiagnosticEvent /// The 'InvalidDirectoryInLibEnvironmentPath' diagnostic. /// /// -/// Directory "{arg0}" specified in LIB environment is not valid. +/// Warning: Directory "{arg0}" specified in LIB environment is not valid. /// public static DiagnosticEvent InvalidDirectoryInLibEnvironmentPath(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.InvalidDirectoryInLibEnvironmentPath.Event([arg0], exception, location); @@ -283,7 +284,7 @@ readonly partial struct DiagnosticEvent /// The 'LegacySearchRule' diagnostic. /// /// -/// Found assembly "{arg0}" using legacy search rule, please append '.dll' to the reference. +/// Warning: Found assembly "{arg0}" using legacy search rule, please append '.dll' to the reference. /// public static DiagnosticEvent LegacySearchRule(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.LegacySearchRule.Event([arg0], exception, location); @@ -291,7 +292,7 @@ readonly partial struct DiagnosticEvent /// The 'AssemblyLocationIgnored' diagnostic. /// /// -/// Assembly "{arg0}" is ignored as previously loaded assembly "{arg1}" has the same identity "{arg2}". +/// Warning: Assembly "{arg0}" is ignored as previously loaded assembly "{arg1}" has the same identity "{arg2}". /// public static DiagnosticEvent AssemblyLocationIgnored(string arg0, string arg1, string arg2, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.AssemblyLocationIgnored.Event([arg0, arg1, arg2], exception, location); @@ -299,7 +300,7 @@ readonly partial struct DiagnosticEvent /// The 'InterfaceMethodCantBeInternal' diagnostic. /// /// -/// Ignoring @ikvm.lang.Internal annotation on interface method. ("{arg0}.{arg1}{arg2}") +/// Warning: Ignoring @ikvm.lang.Internal annotation on interface method. ("{arg0}.{arg1}{arg2}") /// public static DiagnosticEvent InterfaceMethodCantBeInternal(string arg0, string arg1, string arg2, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.InterfaceMethodCantBeInternal.Event([arg0, arg1, arg2], exception, location); @@ -307,7 +308,7 @@ readonly partial struct DiagnosticEvent /// The 'DuplicateAssemblyReference' diagnostic. /// /// -/// Duplicate assembly reference "{arg0}" +/// Warning: Duplicate assembly reference "{arg0}" /// public static DiagnosticEvent DuplicateAssemblyReference(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.DuplicateAssemblyReference.Event([arg0], exception, location); @@ -315,7 +316,7 @@ readonly partial struct DiagnosticEvent /// The 'UnableToResolveType' diagnostic. /// /// -/// Reference in "{arg0}" to type "{arg1}" claims it is defined in "{arg2}", but it could not be found. +/// Warning: Reference in "{arg0}" to type "{arg1}" claims it is defined in "{arg2}", but it could not be found. /// public static DiagnosticEvent UnableToResolveType(string arg0, string arg1, string arg2, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.UnableToResolveType.Event([arg0, arg1, arg2], exception, location); @@ -323,7 +324,7 @@ readonly partial struct DiagnosticEvent /// The 'StubsAreDeprecated' diagnostic. /// /// -/// Compiling stubs is deprecated. Please add a reference to assembly "{arg0}" instead. +/// Warning: Compiling stubs is deprecated. Please add a reference to assembly "{arg0}" instead. /// public static DiagnosticEvent StubsAreDeprecated(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.StubsAreDeprecated.Event([arg0], exception, location); @@ -331,7 +332,7 @@ readonly partial struct DiagnosticEvent /// The 'WrongClassName' diagnostic. /// /// -/// Unable to compile "{arg0}" (wrong name: "{arg1}") +/// Warning: Unable to compile "{arg0}" (wrong name: "{arg1}") /// public static DiagnosticEvent WrongClassName(string arg0, string arg1, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.WrongClassName.Event([arg0, arg1], exception, location); @@ -339,7 +340,7 @@ readonly partial struct DiagnosticEvent /// The 'ReflectionCallerClassRequiresCallerID' diagnostic. /// /// -/// Reflection.getCallerClass() called from non-CallerID method. ("{arg0}.{arg1}{arg2}") +/// Warning: Reflection.getCallerClass() called from non-CallerID method. ("{arg0}.{arg1}{arg2}") /// public static DiagnosticEvent ReflectionCallerClassRequiresCallerID(string arg0, string arg1, string arg2, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.ReflectionCallerClassRequiresCallerID.Event([arg0, arg1, arg2], exception, location); @@ -347,7 +348,7 @@ readonly partial struct DiagnosticEvent /// The 'LegacyAssemblyAttributesFound' diagnostic. /// /// -/// Legacy assembly attributes container found. Please use the -assemblyattributes: option. +/// Warning: Legacy assembly attributes container found. Please use the -assemblyattributes: option. /// public static DiagnosticEvent LegacyAssemblyAttributesFound(Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.LegacyAssemblyAttributesFound.Event([], exception, location); @@ -355,7 +356,7 @@ readonly partial struct DiagnosticEvent /// The 'UnableToCreateLambdaFactory' diagnostic. /// /// -/// Unable to create static lambda factory. +/// Warning: Unable to create static lambda factory. /// public static DiagnosticEvent UnableToCreateLambdaFactory(Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.UnableToCreateLambdaFactory.Event([], exception, location); @@ -363,7 +364,7 @@ readonly partial struct DiagnosticEvent /// The 'UnknownWarning' diagnostic. /// /// -/// {arg0} +/// Warning: {arg0} /// public static DiagnosticEvent UnknownWarning(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.UnknownWarning.Event([arg0], exception, location); @@ -371,7 +372,7 @@ readonly partial struct DiagnosticEvent /// The 'DuplicateIkvmLangProperty' diagnostic. /// /// -/// Ignoring duplicate ikvm.lang.Property annotation on {arg0}.{arg1}. +/// Warning: Ignoring duplicate ikvm.lang.Property annotation on {arg0}.{arg1}. /// public static DiagnosticEvent DuplicateIkvmLangProperty(string arg0, string arg1, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.DuplicateIkvmLangProperty.Event([arg0, arg1], exception, location); @@ -379,7 +380,7 @@ readonly partial struct DiagnosticEvent /// The 'MalformedIkvmLangProperty' diagnostic. /// /// -/// Ignoring duplicate ikvm.lang.Property annotation on {arg0}.{arg1}. +/// Warning: Ignoring duplicate ikvm.lang.Property annotation on {arg0}.{arg1}. /// public static DiagnosticEvent MalformedIkvmLangProperty(string arg0, string arg1, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.MalformedIkvmLangProperty.Event([arg0, arg1], exception, location); @@ -387,7 +388,7 @@ readonly partial struct DiagnosticEvent /// The 'GenericCompilerWarning' diagnostic. /// /// -/// {arg0} +/// Warning: {arg0} /// public static DiagnosticEvent GenericCompilerWarning(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.GenericCompilerWarning.Event([arg0], exception, location); @@ -395,7 +396,7 @@ readonly partial struct DiagnosticEvent /// The 'GenericClassLoadingWarning' diagnostic. /// /// -/// {arg0} +/// Warning: {arg0} /// public static DiagnosticEvent GenericClassLoadingWarning(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.GenericClassLoadingWarning.Event([arg0], exception, location); @@ -403,7 +404,7 @@ readonly partial struct DiagnosticEvent /// The 'GenericVerifierWarning' diagnostic. /// /// -/// {arg0} +/// Warning: {arg0} /// public static DiagnosticEvent GenericVerifierWarning(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.GenericVerifierWarning.Event([arg0], exception, location); @@ -411,7 +412,7 @@ readonly partial struct DiagnosticEvent /// The 'GenericRuntimeWarning' diagnostic. /// /// -/// {arg0} +/// Warning: {arg0} /// public static DiagnosticEvent GenericRuntimeWarning(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.GenericRuntimeWarning.Event([arg0], exception, location); @@ -419,7 +420,7 @@ readonly partial struct DiagnosticEvent /// The 'GenericJniWarning' diagnostic. /// /// -/// {arg0} +/// Warning: {arg0} /// public static DiagnosticEvent GenericJniWarning(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.GenericJniWarning.Event([arg0], exception, location); @@ -427,7 +428,7 @@ readonly partial struct DiagnosticEvent /// The 'UnableToCreateProxy' diagnostic. /// /// -/// Unable to create proxy "{arg0}". ("{arg1}") +/// Error: Unable to create proxy "{arg0}". ("{arg1}") /// public static DiagnosticEvent UnableToCreateProxy(string arg0, string arg1, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.UnableToCreateProxy.Event([arg0, arg1], exception, location); @@ -435,7 +436,7 @@ readonly partial struct DiagnosticEvent /// The 'DuplicateProxy' diagnostic. /// /// -/// Duplicate proxy "{arg0}". +/// Error: Duplicate proxy "{arg0}". /// public static DiagnosticEvent DuplicateProxy(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.DuplicateProxy.Event([arg0], exception, location); @@ -443,7 +444,7 @@ readonly partial struct DiagnosticEvent /// The 'MapXmlUnableToResolveOpCode' diagnostic. /// /// -/// Unable to resolve opcode in remap file: {arg0}. +/// Error: Unable to resolve opcode in remap file: {arg0}. /// public static DiagnosticEvent MapXmlUnableToResolveOpCode(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.MapXmlUnableToResolveOpCode.Event([arg0], exception, location); @@ -451,7 +452,7 @@ readonly partial struct DiagnosticEvent /// The 'MapXmlError' diagnostic. /// /// -/// Error in remap file: {arg0}. +/// Error: Error in remap file: {arg0}. /// public static DiagnosticEvent MapXmlError(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.MapXmlError.Event([arg0], exception, location); @@ -459,7 +460,7 @@ readonly partial struct DiagnosticEvent /// The 'InputFileNotFound' diagnostic. /// /// -/// Source file '{arg0}' not found. +/// Error: Source file '{arg0}' not found. /// public static DiagnosticEvent InputFileNotFound(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.InputFileNotFound.Event([arg0], exception, location); @@ -467,7 +468,7 @@ readonly partial struct DiagnosticEvent /// The 'UnknownFileType' diagnostic. /// /// -/// Unknown file type: {arg0}. +/// Error: Unknown file type: {arg0}. /// public static DiagnosticEvent UnknownFileType(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.UnknownFileType.Event([arg0], exception, location); @@ -475,7 +476,7 @@ readonly partial struct DiagnosticEvent /// The 'UnknownElementInMapFile' diagnostic. /// /// -/// Unknown element {arg0} in remap file, line {arg1}, column {arg2}. +/// Error: Unknown element {arg0} in remap file, line {arg1}, column {arg2}. /// public static DiagnosticEvent UnknownElementInMapFile(string arg0, string arg1, string arg2, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.UnknownElementInMapFile.Event([arg0, arg1, arg2], exception, location); @@ -483,7 +484,7 @@ readonly partial struct DiagnosticEvent /// The 'UnknownAttributeInMapFile' diagnostic. /// /// -/// Unknown attribute {arg0} in remap file, line {arg1}, column {arg2}. +/// Error: Unknown attribute {arg0} in remap file, line {arg1}, column {arg2}. /// public static DiagnosticEvent UnknownAttributeInMapFile(string arg0, string arg1, string arg2, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.UnknownAttributeInMapFile.Event([arg0, arg1, arg2], exception, location); @@ -491,7 +492,7 @@ readonly partial struct DiagnosticEvent /// The 'InvalidMemberNameInMapFile' diagnostic. /// /// -/// Invalid {arg0} name '{arg1}' in remap file in class {arg2}. +/// Error: Invalid {arg0} name '{arg1}' in remap file in class {arg2}. /// public static DiagnosticEvent InvalidMemberNameInMapFile(string arg0, string arg1, string arg2, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.InvalidMemberNameInMapFile.Event([arg0, arg1, arg2], exception, location); @@ -499,7 +500,7 @@ readonly partial struct DiagnosticEvent /// The 'InvalidMemberSignatureInMapFile' diagnostic. /// /// -/// Invalid {arg0} signature '{arg3}' in remap file for {arg0} {arg1}.{arg2}. +/// Error: Invalid {arg0} signature '{arg3}' in remap file for {arg0} {arg1}.{arg2}. /// public static DiagnosticEvent InvalidMemberSignatureInMapFile(string arg0, string arg1, string arg2, string arg3, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.InvalidMemberSignatureInMapFile.Event([arg0, arg1, arg2, arg3], exception, location); @@ -507,7 +508,7 @@ readonly partial struct DiagnosticEvent /// The 'InvalidPropertyNameInMapFile' diagnostic. /// /// -/// Invalid property {arg0} name '{arg3}' in remap file for property {arg1}.{arg2}. +/// Error: Invalid property {arg0} name '{arg3}' in remap file for property {arg1}.{arg2}. /// public static DiagnosticEvent InvalidPropertyNameInMapFile(string arg0, string arg1, string arg2, string arg3, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.InvalidPropertyNameInMapFile.Event([arg0, arg1, arg2, arg3], exception, location); @@ -515,7 +516,7 @@ readonly partial struct DiagnosticEvent /// The 'InvalidPropertySignatureInMapFile' diagnostic. /// /// -/// Invalid property {arg0} signature '{arg3}' in remap file for property {arg1}.{arg2}. +/// Error: Invalid property {arg0} signature '{arg3}' in remap file for property {arg1}.{arg2}. /// public static DiagnosticEvent InvalidPropertySignatureInMapFile(string arg0, string arg1, string arg2, string arg3, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.InvalidPropertySignatureInMapFile.Event([arg0, arg1, arg2, arg3], exception, location); @@ -523,7 +524,7 @@ readonly partial struct DiagnosticEvent /// The 'NonPrimaryAssemblyReference' diagnostic. /// /// -/// Referenced assembly "{arg0}" is not the primary assembly of a shared class loader group, please reference primary assembly "{arg1}" instead. +/// Error: Referenced assembly "{arg0}" is not the primary assembly of a shared class loader group, please reference primary assembly "{arg1}" instead. /// public static DiagnosticEvent NonPrimaryAssemblyReference(string arg0, string arg1, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.NonPrimaryAssemblyReference.Event([arg0, arg1], exception, location); @@ -531,7 +532,7 @@ readonly partial struct DiagnosticEvent /// The 'MissingType' diagnostic. /// /// -/// Reference to type "{arg0}" claims it is defined in "{arg1}", but it could not be found. +/// Error: Reference to type "{arg0}" claims it is defined in "{arg1}", but it could not be found. /// public static DiagnosticEvent MissingType(string arg0, string arg1, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.MissingType.Event([arg0, arg1], exception, location); @@ -539,7 +540,7 @@ readonly partial struct DiagnosticEvent /// The 'MissingReference' diagnostic. /// /// -/// The type '{arg0}' is defined in an assembly that is notResponseFileDepthExceeded referenced. You must add a reference to assembly '{arg1}'. +/// Error: The type '{arg0}' is defined in an assembly that is notResponseFileDepthExceeded referenced. You must add a reference to assembly '{arg1}'. /// public static DiagnosticEvent MissingReference(string arg0, string arg1, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.MissingReference.Event([arg0, arg1], exception, location); @@ -547,7 +548,7 @@ readonly partial struct DiagnosticEvent /// The 'CallerSensitiveOnUnsupportedMethod' diagnostic. /// /// -/// CallerSensitive annotation on unsupported method. ("{arg0}.{arg1}{arg2}") +/// Error: CallerSensitive annotation on unsupported method. ("{arg0}.{arg1}{arg2}") /// public static DiagnosticEvent CallerSensitiveOnUnsupportedMethod(string arg0, string arg1, string arg2, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.CallerSensitiveOnUnsupportedMethod.Event([arg0, arg1, arg2], exception, location); @@ -555,7 +556,7 @@ readonly partial struct DiagnosticEvent /// The 'RemappedTypeMissingDefaultInterfaceMethod' diagnostic. /// /// -/// {arg0} does not implement default interface method {arg1}. +/// Error: {arg0} does not implement default interface method {arg1}. /// public static DiagnosticEvent RemappedTypeMissingDefaultInterfaceMethod(string arg0, string arg1, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.RemappedTypeMissingDefaultInterfaceMethod.Event([arg0, arg1], exception, location); @@ -563,7 +564,7 @@ readonly partial struct DiagnosticEvent /// The 'GenericCompilerError' diagnostic. /// /// -/// {arg0} +/// Error: {arg0} /// public static DiagnosticEvent GenericCompilerError(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.GenericCompilerError.Event([arg0], exception, location); @@ -571,7 +572,7 @@ readonly partial struct DiagnosticEvent /// The 'GenericClassLoadingError' diagnostic. /// /// -/// {arg0} +/// Error: {arg0} /// public static DiagnosticEvent GenericClassLoadingError(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.GenericClassLoadingError.Event([arg0], exception, location); @@ -579,7 +580,7 @@ readonly partial struct DiagnosticEvent /// The 'GenericVerifierError' diagnostic. /// /// -/// {arg0} +/// Error: {arg0} /// public static DiagnosticEvent GenericVerifierError(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.GenericVerifierError.Event([arg0], exception, location); @@ -587,7 +588,7 @@ readonly partial struct DiagnosticEvent /// The 'GenericRuntimeError' diagnostic. /// /// -/// {arg0} +/// Error: {arg0} /// public static DiagnosticEvent GenericRuntimeError(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.GenericRuntimeError.Event([arg0], exception, location); @@ -595,7 +596,7 @@ readonly partial struct DiagnosticEvent /// The 'GenericJniError' diagnostic. /// /// -/// {arg0} +/// Error: {arg0} /// public static DiagnosticEvent GenericJniError(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.GenericJniError.Event([arg0], exception, location); @@ -603,7 +604,7 @@ readonly partial struct DiagnosticEvent /// The 'ExportingImportsNotSupported' diagnostic. /// /// -/// Exporting previously imported assemblies is not supported. +/// Error: Exporting previously imported assemblies is not supported. /// public static DiagnosticEvent ExportingImportsNotSupported(Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.ExportingImportsNotSupported.Event([], exception, location); @@ -611,7 +612,7 @@ readonly partial struct DiagnosticEvent /// The 'ResponseFileDepthExceeded' diagnostic. /// /// -/// Response file nesting depth exceeded. +/// Fatal: Response file nesting depth exceeded. /// public static DiagnosticEvent ResponseFileDepthExceeded(Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.ResponseFileDepthExceeded.Event([], exception, location); @@ -619,7 +620,7 @@ readonly partial struct DiagnosticEvent /// The 'ErrorReadingFile' diagnostic. /// /// -/// Unable to read file: {arg0}. ({arg1}) +/// Fatal: Unable to read file: {arg0}. ({arg1}) /// public static DiagnosticEvent ErrorReadingFile(string arg0, string arg1, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.ErrorReadingFile.Event([arg0, arg1], exception, location); @@ -627,7 +628,7 @@ readonly partial struct DiagnosticEvent /// The 'NoTargetsFound' diagnostic. /// /// -/// No targets found +/// Fatal: No targets found /// public static DiagnosticEvent NoTargetsFound(Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.NoTargetsFound.Event([], exception, location); @@ -635,7 +636,7 @@ readonly partial struct DiagnosticEvent /// The 'FileFormatLimitationExceeded' diagnostic. /// /// -/// File format limitation exceeded: {arg0}. +/// Fatal: File format limitation exceeded: {arg0}. /// public static DiagnosticEvent FileFormatLimitationExceeded(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.FileFormatLimitationExceeded.Event([arg0], exception, location); @@ -643,7 +644,7 @@ readonly partial struct DiagnosticEvent /// The 'CannotSpecifyBothKeyFileAndContainer' diagnostic. /// /// -/// You cannot specify both a key file and container. +/// Fatal: You cannot specify both a key file and container. /// public static DiagnosticEvent CannotSpecifyBothKeyFileAndContainer(Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.CannotSpecifyBothKeyFileAndContainer.Event([], exception, location); @@ -651,7 +652,7 @@ readonly partial struct DiagnosticEvent /// The 'DelaySignRequiresKey' diagnostic. /// /// -/// You cannot delay sign without a key file or container. +/// Fatal: You cannot delay sign without a key file or container. /// public static DiagnosticEvent DelaySignRequiresKey(Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.DelaySignRequiresKey.Event([], exception, location); @@ -659,7 +660,7 @@ readonly partial struct DiagnosticEvent /// The 'InvalidStrongNameKeyPair' diagnostic. /// /// -/// Invalid key {arg0} specified. ("{arg1}") +/// Fatal: Invalid key {arg0} specified. ("{arg1}") /// public static DiagnosticEvent InvalidStrongNameKeyPair(string arg0, string arg1, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.InvalidStrongNameKeyPair.Event([arg0, arg1], exception, location); @@ -667,7 +668,7 @@ readonly partial struct DiagnosticEvent /// The 'ReferenceNotFound' diagnostic. /// /// -/// Reference not found: {arg0} +/// Fatal: Reference not found: {arg0} /// public static DiagnosticEvent ReferenceNotFound(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.ReferenceNotFound.Event([arg0], exception, location); @@ -675,7 +676,7 @@ readonly partial struct DiagnosticEvent /// The 'OptionsMustPreceedChildLevels' diagnostic. /// /// -/// You can only specify options before any child levels. +/// Fatal: You can only specify options before any child levels. /// public static DiagnosticEvent OptionsMustPreceedChildLevels(Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.OptionsMustPreceedChildLevels.Event([], exception, location); @@ -683,7 +684,7 @@ readonly partial struct DiagnosticEvent /// The 'UnrecognizedTargetType' diagnostic. /// /// -/// Invalid value '{arg0}' for -target option. +/// Fatal: Invalid value '{arg0}' for -target option. /// public static DiagnosticEvent UnrecognizedTargetType(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.UnrecognizedTargetType.Event([arg0], exception, location); @@ -691,7 +692,7 @@ readonly partial struct DiagnosticEvent /// The 'UnrecognizedPlatform' diagnostic. /// /// -/// Invalid value '{arg0}' for -platform option. +/// Fatal: Invalid value '{arg0}' for -platform option. /// public static DiagnosticEvent UnrecognizedPlatform(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.UnrecognizedPlatform.Event([arg0], exception, location); @@ -699,7 +700,7 @@ readonly partial struct DiagnosticEvent /// The 'UnrecognizedApartment' diagnostic. /// /// -/// Invalid value '{arg0}' for -apartment option. +/// Fatal: Invalid value '{arg0}' for -apartment option. /// public static DiagnosticEvent UnrecognizedApartment(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.UnrecognizedApartment.Event([arg0], exception, location); @@ -707,7 +708,7 @@ readonly partial struct DiagnosticEvent /// The 'MissingFileSpecification' diagnostic. /// /// -/// Missing file specification for '{arg0}' option. +/// Fatal: Missing file specification for '{arg0}' option. /// public static DiagnosticEvent MissingFileSpecification(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.MissingFileSpecification.Event([arg0], exception, location); @@ -715,7 +716,7 @@ readonly partial struct DiagnosticEvent /// The 'PathTooLong' diagnostic. /// /// -/// Path too long: {arg0}. +/// Fatal: Path too long: {arg0}. /// public static DiagnosticEvent PathTooLong(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.PathTooLong.Event([arg0], exception, location); @@ -723,7 +724,7 @@ readonly partial struct DiagnosticEvent /// The 'PathNotFound' diagnostic. /// /// -/// Path not found: {arg0}. +/// Fatal: Path not found: {arg0}. /// public static DiagnosticEvent PathNotFound(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.PathNotFound.Event([arg0], exception, location); @@ -731,7 +732,7 @@ readonly partial struct DiagnosticEvent /// The 'InvalidPath' diagnostic. /// /// -/// Invalid path: {arg0}. +/// Fatal: Invalid path: {arg0}. /// public static DiagnosticEvent InvalidPath(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.InvalidPath.Event([arg0], exception, location); @@ -739,7 +740,7 @@ readonly partial struct DiagnosticEvent /// The 'InvalidOptionSyntax' diagnostic. /// /// -/// Invalid option: {arg0}. +/// Fatal: Invalid option: {arg0}. /// public static DiagnosticEvent InvalidOptionSyntax(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.InvalidOptionSyntax.Event([arg0], exception, location); @@ -747,7 +748,7 @@ readonly partial struct DiagnosticEvent /// The 'ExternalResourceNotFound' diagnostic. /// /// -/// External resource file does not exist: {arg0}. +/// Fatal: External resource file does not exist: {arg0}. /// public static DiagnosticEvent ExternalResourceNotFound(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.ExternalResourceNotFound.Event([arg0], exception, location); @@ -755,7 +756,7 @@ readonly partial struct DiagnosticEvent /// The 'ExternalResourceNameInvalid' diagnostic. /// /// -/// External resource file may not include path specification: {arg0}. +/// Fatal: External resource file may not include path specification: {arg0}. /// public static DiagnosticEvent ExternalResourceNameInvalid(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.ExternalResourceNameInvalid.Event([arg0], exception, location); @@ -763,7 +764,7 @@ readonly partial struct DiagnosticEvent /// The 'InvalidVersionFormat' diagnostic. /// /// -/// Invalid version specified: {arg0}. +/// Fatal: Invalid version specified: {arg0}. /// public static DiagnosticEvent InvalidVersionFormat(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.InvalidVersionFormat.Event([arg0], exception, location); @@ -771,7 +772,7 @@ readonly partial struct DiagnosticEvent /// The 'InvalidFileAlignment' diagnostic. /// /// -/// Invalid value '{arg0}' for -filealign option. +/// Fatal: Invalid value '{arg0}' for -filealign option. /// public static DiagnosticEvent InvalidFileAlignment(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.InvalidFileAlignment.Event([arg0], exception, location); @@ -779,7 +780,7 @@ readonly partial struct DiagnosticEvent /// The 'ErrorWritingFile' diagnostic. /// /// -/// Unable to write file: {arg0}. ({arg1}) +/// Fatal: Unable to write file: {arg0}. ({arg1}) /// public static DiagnosticEvent ErrorWritingFile(string arg0, string arg1, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.ErrorWritingFile.Event([arg0, arg1], exception, location); @@ -787,7 +788,7 @@ readonly partial struct DiagnosticEvent /// The 'UnrecognizedOption' diagnostic. /// /// -/// Unrecognized option: {arg0}. +/// Fatal: Unrecognized option: {arg0}. /// public static DiagnosticEvent UnrecognizedOption(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.UnrecognizedOption.Event([arg0], exception, location); @@ -795,7 +796,7 @@ readonly partial struct DiagnosticEvent /// The 'NoOutputFileSpecified' diagnostic. /// /// -/// No output file specified. +/// Fatal: No output file specified. /// public static DiagnosticEvent NoOutputFileSpecified(Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.NoOutputFileSpecified.Event([], exception, location); @@ -803,7 +804,7 @@ readonly partial struct DiagnosticEvent /// The 'SharedClassLoaderCannotBeUsedOnModuleTarget' diagnostic. /// /// -/// Incompatible options: -target:module and -sharedclassloader cannot be combined. +/// Fatal: Incompatible options: -target:module and -sharedclassloader cannot be combined. /// public static DiagnosticEvent SharedClassLoaderCannotBeUsedOnModuleTarget(Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.SharedClassLoaderCannotBeUsedOnModuleTarget.Event([], exception, location); @@ -811,7 +812,7 @@ readonly partial struct DiagnosticEvent /// The 'RuntimeNotFound' diagnostic. /// /// -/// Unable to load runtime assembly. +/// Fatal: Unable to load runtime assembly. /// public static DiagnosticEvent RuntimeNotFound(Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.RuntimeNotFound.Event([], exception, location); @@ -819,7 +820,7 @@ readonly partial struct DiagnosticEvent /// The 'MainClassRequiresExe' diagnostic. /// /// -/// Main class cannot be specified for library or module. +/// Fatal: Main class cannot be specified for library or module. /// public static DiagnosticEvent MainClassRequiresExe(Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.MainClassRequiresExe.Event([], exception, location); @@ -827,7 +828,7 @@ readonly partial struct DiagnosticEvent /// The 'ExeRequiresMainClass' diagnostic. /// /// -/// No main method found. +/// Fatal: No main method found. /// public static DiagnosticEvent ExeRequiresMainClass(Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.ExeRequiresMainClass.Event([], exception, location); @@ -835,7 +836,7 @@ readonly partial struct DiagnosticEvent /// The 'PropertiesRequireExe' diagnostic. /// /// -/// Properties cannot be specified for library or module. +/// Fatal: Properties cannot be specified for library or module. /// public static DiagnosticEvent PropertiesRequireExe(Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.PropertiesRequireExe.Event([], exception, location); @@ -843,7 +844,7 @@ readonly partial struct DiagnosticEvent /// The 'ModuleCannotHaveClassLoader' diagnostic. /// /// -/// Cannot specify assembly class loader for modules. +/// Fatal: Cannot specify assembly class loader for modules. /// public static DiagnosticEvent ModuleCannotHaveClassLoader(Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.ModuleCannotHaveClassLoader.Event([], exception, location); @@ -851,7 +852,7 @@ readonly partial struct DiagnosticEvent /// The 'ErrorParsingMapFile' diagnostic. /// /// -/// Unable to parse remap file: {arg0}. ({arg1}) +/// Fatal: Unable to parse remap file: {arg0}. ({arg1}) /// public static DiagnosticEvent ErrorParsingMapFile(string arg0, string arg1, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.ErrorParsingMapFile.Event([arg0, arg1], exception, location); @@ -859,7 +860,7 @@ readonly partial struct DiagnosticEvent /// The 'BootstrapClassesMissing' diagnostic. /// /// -/// Bootstrap classes missing and core assembly not found. +/// Fatal: Bootstrap classes missing and core assembly not found. /// public static DiagnosticEvent BootstrapClassesMissing(Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.BootstrapClassesMissing.Event([], exception, location); @@ -867,7 +868,7 @@ readonly partial struct DiagnosticEvent /// The 'StrongNameRequiresStrongNamedRefs' diagnostic. /// /// -/// All referenced assemblies must be strong named, to be able to sign the output assembly. +/// Fatal: All referenced assemblies must be strong named, to be able to sign the output assembly. /// public static DiagnosticEvent StrongNameRequiresStrongNamedRefs(Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.StrongNameRequiresStrongNamedRefs.Event([], exception, location); @@ -875,7 +876,7 @@ readonly partial struct DiagnosticEvent /// The 'MainClassNotFound' diagnostic. /// /// -/// Main class not found. +/// Fatal: Main class not found. /// public static DiagnosticEvent MainClassNotFound(Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.MainClassNotFound.Event([], exception, location); @@ -883,7 +884,7 @@ readonly partial struct DiagnosticEvent /// The 'MainMethodNotFound' diagnostic. /// /// -/// Main method not found. +/// Fatal: Main method not found. /// public static DiagnosticEvent MainMethodNotFound(Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.MainMethodNotFound.Event([], exception, location); @@ -891,7 +892,7 @@ readonly partial struct DiagnosticEvent /// The 'UnsupportedMainMethod' diagnostic. /// /// -/// Redirected main method not supported. +/// Fatal: Redirected main method not supported. /// public static DiagnosticEvent UnsupportedMainMethod(Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.UnsupportedMainMethod.Event([], exception, location); @@ -899,7 +900,7 @@ readonly partial struct DiagnosticEvent /// The 'ExternalMainNotAccessible' diagnostic. /// /// -/// External main method must be public and in a public class. +/// Fatal: External main method must be public and in a public class. /// public static DiagnosticEvent ExternalMainNotAccessible(Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.ExternalMainNotAccessible.Event([], exception, location); @@ -907,7 +908,7 @@ readonly partial struct DiagnosticEvent /// The 'ClassLoaderNotFound' diagnostic. /// /// -/// Custom assembly class loader class not found. +/// Fatal: Custom assembly class loader class not found. /// public static DiagnosticEvent ClassLoaderNotFound(Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.ClassLoaderNotFound.Event([], exception, location); @@ -915,7 +916,7 @@ readonly partial struct DiagnosticEvent /// The 'ClassLoaderNotAccessible' diagnostic. /// /// -/// Custom assembly class loader class is not accessible. +/// Fatal: Custom assembly class loader class is not accessible. /// public static DiagnosticEvent ClassLoaderNotAccessible(Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.ClassLoaderNotAccessible.Event([], exception, location); @@ -923,7 +924,7 @@ readonly partial struct DiagnosticEvent /// The 'ClassLoaderIsAbstract' diagnostic. /// /// -/// Custom assembly class loader class is abstract. +/// Fatal: Custom assembly class loader class is abstract. /// public static DiagnosticEvent ClassLoaderIsAbstract(Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.ClassLoaderIsAbstract.Event([], exception, location); @@ -931,7 +932,7 @@ readonly partial struct DiagnosticEvent /// The 'ClassLoaderNotClassLoader' diagnostic. /// /// -/// Custom assembly class loader class does not extend java.lang.ClassLoader. +/// Fatal: Custom assembly class loader class does not extend java.lang.ClassLoader. /// public static DiagnosticEvent ClassLoaderNotClassLoader(Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.ClassLoaderNotClassLoader.Event([], exception, location); @@ -939,7 +940,7 @@ readonly partial struct DiagnosticEvent /// The 'ClassLoaderConstructorMissing' diagnostic. /// /// -/// Custom assembly class loader constructor is missing. +/// Fatal: Custom assembly class loader constructor is missing. /// public static DiagnosticEvent ClassLoaderConstructorMissing(Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.ClassLoaderConstructorMissing.Event([], exception, location); @@ -947,7 +948,7 @@ readonly partial struct DiagnosticEvent /// The 'MapFileTypeNotFound' diagnostic. /// /// -/// Type '{arg0}' referenced in remap file was not found. +/// Fatal: Type '{arg0}' referenced in remap file was not found. /// public static DiagnosticEvent MapFileTypeNotFound(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.MapFileTypeNotFound.Event([arg0], exception, location); @@ -955,7 +956,7 @@ readonly partial struct DiagnosticEvent /// The 'MapFileClassNotFound' diagnostic. /// /// -/// Class '{arg0}' referenced in remap file was not found. +/// Fatal: Class '{arg0}' referenced in remap file was not found. /// public static DiagnosticEvent MapFileClassNotFound(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.MapFileClassNotFound.Event([arg0], exception, location); @@ -963,7 +964,7 @@ readonly partial struct DiagnosticEvent /// The 'MaximumErrorCountReached' diagnostic. /// /// -/// Maximum error count reached. +/// Fatal: Maximum error count reached. /// public static DiagnosticEvent MaximumErrorCountReached(Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.MaximumErrorCountReached.Event([], exception, location); @@ -971,7 +972,7 @@ readonly partial struct DiagnosticEvent /// The 'LinkageError' diagnostic. /// /// -/// Link error: {arg0} +/// Fatal: Link error: {arg0} /// public static DiagnosticEvent LinkageError(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.LinkageError.Event([arg0], exception, location); @@ -979,7 +980,7 @@ readonly partial struct DiagnosticEvent /// The 'RuntimeMismatch' diagnostic. /// /// -/// Referenced assembly {referencedAssemblyPath} was compiled with an incompatible IKVM.Runtime version. Current runtime: {runtimeAssemblyName}. Referenced assembly runtime: {referencedAssemblyName} +/// Fatal: Referenced assembly {referencedAssemblyPath} was compiled with an incompatible IKVM.Runtime version. Current runtime: {runtimeAssemblyName}. Referenced assembly runtime: {referencedAssemblyName} /// public static DiagnosticEvent RuntimeMismatch(string referencedAssemblyPath, string runtimeAssemblyName, string referencedAssemblyName, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.RuntimeMismatch.Event([referencedAssemblyPath, runtimeAssemblyName, referencedAssemblyName], exception, location); @@ -987,7 +988,7 @@ readonly partial struct DiagnosticEvent /// The 'RuntimeMismatchStrongName' diagnostic. /// /// -/// +/// Fatal: /// public static DiagnosticEvent RuntimeMismatchStrongName(Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.RuntimeMismatchStrongName.Event([], exception, location); @@ -995,7 +996,7 @@ readonly partial struct DiagnosticEvent /// The 'CoreClassesMissing' diagnostic. /// /// -/// Failed to find core classes in core library. +/// Fatal: Failed to find core classes in core library. /// public static DiagnosticEvent CoreClassesMissing(Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.CoreClassesMissing.Event([], exception, location); @@ -1003,7 +1004,7 @@ readonly partial struct DiagnosticEvent /// The 'CriticalClassNotFound' diagnostic. /// /// -/// Unable to load critical class '{arg0}'. +/// Fatal: Unable to load critical class '{arg0}'. /// public static DiagnosticEvent CriticalClassNotFound(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.CriticalClassNotFound.Event([arg0], exception, location); @@ -1011,7 +1012,7 @@ readonly partial struct DiagnosticEvent /// The 'AssemblyContainsDuplicateClassNames' diagnostic. /// /// -/// Type '{arg0}' and '{arg1}' both map to the same name '{arg2}'. ({arg3}) +/// Fatal: Type '{arg0}' and '{arg1}' both map to the same name '{arg2}'. ({arg3}) /// public static DiagnosticEvent AssemblyContainsDuplicateClassNames(string arg0, string arg1, string arg2, string arg3, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.AssemblyContainsDuplicateClassNames.Event([arg0, arg1, arg2, arg3], exception, location); @@ -1019,7 +1020,7 @@ readonly partial struct DiagnosticEvent /// The 'CallerIDRequiresHasCallerIDAnnotation' diagnostic. /// /// -/// CallerID.getCallerID() requires a HasCallerID annotation. +/// Fatal: CallerID.getCallerID() requires a HasCallerID annotation. /// public static DiagnosticEvent CallerIDRequiresHasCallerIDAnnotation(Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.CallerIDRequiresHasCallerIDAnnotation.Event([], exception, location); @@ -1027,7 +1028,7 @@ readonly partial struct DiagnosticEvent /// The 'UnableToResolveInterface' diagnostic. /// /// -/// Unable to resolve interface '{arg0}' on type '{arg1}'. +/// Fatal: Unable to resolve interface '{arg0}' on type '{arg1}'. /// public static DiagnosticEvent UnableToResolveInterface(string arg0, string arg1, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.UnableToResolveInterface.Event([arg0, arg1], exception, location); @@ -1035,7 +1036,7 @@ readonly partial struct DiagnosticEvent /// The 'MissingBaseType' diagnostic. /// /// -/// The base class or interface '{arg0}' in assembly '{arg1}' referenced by type '{arg2}' in '{arg3}' could not be resolved. +/// Fatal: The base class or interface '{arg0}' in assembly '{arg1}' referenced by type '{arg2}' in '{arg3}' could not be resolved. /// public static DiagnosticEvent MissingBaseType(string arg0, string arg1, string arg2, string arg3, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.MissingBaseType.Event([arg0, arg1, arg2, arg3], exception, location); @@ -1043,7 +1044,7 @@ readonly partial struct DiagnosticEvent /// The 'MissingBaseTypeReference' diagnostic. /// /// -/// The type '{arg0}' is defined in an assembly that is not referenced. You must add a reference to assembly '{arg1}'. +/// Fatal: The type '{arg0}' is defined in an assembly that is not referenced. You must add a reference to assembly '{arg1}'. /// public static DiagnosticEvent MissingBaseTypeReference(string arg0, string arg1, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.MissingBaseTypeReference.Event([arg0, arg1], exception, location); @@ -1051,7 +1052,7 @@ readonly partial struct DiagnosticEvent /// The 'FileNotFound' diagnostic. /// /// -/// File not found: {arg0}. +/// Fatal: File not found: {arg0}. /// public static DiagnosticEvent FileNotFound(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.FileNotFound.Event([arg0], exception, location); @@ -1059,7 +1060,7 @@ readonly partial struct DiagnosticEvent /// The 'RuntimeMethodMissing' diagnostic. /// /// -/// Runtime method '{arg0}' not found. +/// Fatal: Runtime method '{arg0}' not found. /// public static DiagnosticEvent RuntimeMethodMissing(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.RuntimeMethodMissing.Event([arg0], exception, location); @@ -1067,7 +1068,7 @@ readonly partial struct DiagnosticEvent /// The 'MapFileFieldNotFound' diagnostic. /// /// -/// Field '{arg0}' referenced in remap file was not found in class '{arg1}'. +/// Fatal: Field '{arg0}' referenced in remap file was not found in class '{arg1}'. /// public static DiagnosticEvent MapFileFieldNotFound(string arg0, string arg1, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.MapFileFieldNotFound.Event([arg0, arg1], exception, location); @@ -1075,7 +1076,7 @@ readonly partial struct DiagnosticEvent /// The 'GhostInterfaceMethodMissing' diagnostic. /// /// -/// Remapped class '{arg0}' does not implement ghost interface method. ({arg1}.{arg2}{arg3}) +/// Fatal: Remapped class '{arg0}' does not implement ghost interface method. ({arg1}.{arg2}{arg3}) /// public static DiagnosticEvent GhostInterfaceMethodMissing(string arg0, string arg1, string arg2, string arg3, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.GhostInterfaceMethodMissing.Event([arg0, arg1, arg2, arg3], exception, location); @@ -1083,7 +1084,7 @@ readonly partial struct DiagnosticEvent /// The 'ModuleInitializerMethodRequirements' diagnostic. /// /// -/// Method '{arg1}.{arg2}{arg3}' does not meet the requirements of a module initializer. +/// Fatal: Method '{arg1}.{arg2}{arg3}' does not meet the requirements of a module initializer. /// public static DiagnosticEvent ModuleInitializerMethodRequirements(string arg1, string arg2, string arg3, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.ModuleInitializerMethodRequirements.Event([arg1, arg2, arg3], exception, location); @@ -1091,7 +1092,7 @@ readonly partial struct DiagnosticEvent /// The 'InvalidZip' diagnostic. /// /// -/// Invalid zip: {name}. +/// Fatal: Invalid zip: {name}. /// public static DiagnosticEvent InvalidZip(string name, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.InvalidZip.Event([name], exception, location); @@ -1099,7 +1100,7 @@ readonly partial struct DiagnosticEvent /// The 'CoreAssemblyVersionMismatch' diagnostic. /// /// -/// Unable to load assembly '{0}' as it depends on a higher version of {1} than the one currently loaded. +/// Fatal: Unable to load assembly '{0}' as it depends on a higher version of {1} than the one currently loaded. /// public static DiagnosticEvent CoreAssemblyVersionMismatch(string arg0, string arg1, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.CoreAssemblyVersionMismatch.Event([arg0, arg1], exception, location); @@ -1107,7 +1108,7 @@ readonly partial struct DiagnosticEvent /// The 'GenericRuntimeTrace' diagnostic. /// /// -/// {arg0} +/// Trace: {arg0} /// public static DiagnosticEvent GenericRuntimeTrace(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.GenericRuntimeTrace.Event([arg0], exception, location); @@ -1115,7 +1116,7 @@ readonly partial struct DiagnosticEvent /// The 'GenericJniTrace' diagnostic. /// /// -/// {arg0} +/// Trace: {arg0} /// public static DiagnosticEvent GenericJniTrace(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.GenericJniTrace.Event([arg0], exception, location); @@ -1123,7 +1124,7 @@ readonly partial struct DiagnosticEvent /// The 'GenericCompilerTrace' diagnostic. /// /// -/// {arg0} +/// Trace: {arg0} /// public static DiagnosticEvent GenericCompilerTrace(string arg0, Exception? exception = null, DiagnosticLocation location = default) => Diagnostic.GenericCompilerTrace.Event([arg0], exception, location); diff --git a/src/IKVM.CoreLib/Diagnostics/DiagnosticEvent.g.tt b/src/IKVM.CoreLib/Diagnostics/DiagnosticEvent.g.tt index a7cdf4ab6..9b3b95ecb 100644 --- a/src/IKVM.CoreLib/Diagnostics/DiagnosticEvent.g.tt +++ b/src/IKVM.CoreLib/Diagnostics/DiagnosticEvent.g.tt @@ -50,7 +50,7 @@ foreach (var kvp in DiagnosticFile.Read(Host.ResolvePath(Path.Combine("Diagnosti /// <#= desc #> /// /// -<#= Util.ToCommentString(kvp.Value.Message ?? "") #> +<#= Util.ToCommentString(kvp.Value) #> /// public static DiagnosticEvent <#= kvp.Key #>(<#= string.Join(", ", argDecl) #>) => Diagnostic.<#= kvp.Key #>.Event([<#= string.Join(", ", argList) #>], exception, location); diff --git a/src/IKVM.Tools.Importer/FatalCompilerErrorException.cs b/src/IKVM.CoreLib/Diagnostics/DiagnosticEventException.cs similarity index 88% rename from src/IKVM.Tools.Importer/FatalCompilerErrorException.cs rename to src/IKVM.CoreLib/Diagnostics/DiagnosticEventException.cs index 8296518f4..bf64df0b3 100644 --- a/src/IKVM.Tools.Importer/FatalCompilerErrorException.cs +++ b/src/IKVM.CoreLib/Diagnostics/DiagnosticEventException.cs @@ -1,11 +1,9 @@ using System; -using IKVM.CoreLib.Diagnostics; - -namespace IKVM.Tools.Importer +namespace IKVM.CoreLib.Diagnostics { - sealed class FatalCompilerErrorException : Exception + sealed class DiagnosticEventException : Exception { /// @@ -33,7 +31,7 @@ static string FormatDiagnosticLevel(DiagnosticLevel level) /// Initializes a new instance. /// /// - internal FatalCompilerErrorException(in DiagnosticEvent evt) : + internal DiagnosticEventException(in DiagnosticEvent evt) : #if NET8_0_OR_GREATER base($"{FormatDiagnosticLevel(evt.Diagnostic.Level)} IKVM{evt.Diagnostic.Id:D4}: {string.Format(null, evt.Diagnostic.Message, evt.Args)}") #else diff --git a/src/IKVM.CoreLib/Diagnostics/DiagnosticEventHandler.g.cs b/src/IKVM.CoreLib/Diagnostics/DiagnosticEventHandler.g.cs index 53fc27600..782a3309c 100644 --- a/src/IKVM.CoreLib/Diagnostics/DiagnosticEventHandler.g.cs +++ b/src/IKVM.CoreLib/Diagnostics/DiagnosticEventHandler.g.cs @@ -10,7 +10,7 @@ internal abstract partial class DiagnosticEventHandler /// The 'MainMethodFound' diagnostic. /// /// -/// Found main method in class "{arg0}". +/// Info: Found main method in class "{arg0}". /// public void MainMethodFound(string arg0) { @@ -22,7 +22,7 @@ public void MainMethodFound(string arg0) /// The 'OutputFileIs' diagnostic. /// /// -/// Output file is "{arg0}". +/// Info: Output file is "{arg0}". /// public void OutputFileIs(string arg0) { @@ -34,7 +34,7 @@ public void OutputFileIs(string arg0) /// The 'AutoAddRef' diagnostic. /// /// -/// Automatically adding reference to "{arg0}". +/// Info: Automatically adding reference to "{arg0}". /// public void AutoAddRef(string arg0) { @@ -46,7 +46,7 @@ public void AutoAddRef(string arg0) /// The 'MainMethodFromManifest' diagnostic. /// /// -/// Using main class "{arg0}" based on jar manifest. +/// Info: Using main class "{arg0}" based on jar manifest. /// public void MainMethodFromManifest(string arg0) { @@ -58,7 +58,7 @@ public void MainMethodFromManifest(string arg0) /// The 'GenericCompilerInfo' diagnostic. /// /// -/// {arg0} +/// Info: {arg0} /// public void GenericCompilerInfo(string arg0) { @@ -70,7 +70,7 @@ public void GenericCompilerInfo(string arg0) /// The 'GenericClassLoadingInfo' diagnostic. /// /// -/// {arg0} +/// Info: {arg0} /// public void GenericClassLoadingInfo(string arg0) { @@ -82,7 +82,7 @@ public void GenericClassLoadingInfo(string arg0) /// The 'GenericVerifierInfo' diagnostic. /// /// -/// {arg0} +/// Info: {arg0} /// public void GenericVerifierInfo(string arg0) { @@ -94,7 +94,7 @@ public void GenericVerifierInfo(string arg0) /// The 'GenericRuntimeInfo' diagnostic. /// /// -/// {arg0} +/// Info: {arg0} /// public void GenericRuntimeInfo(string arg0) { @@ -106,7 +106,7 @@ public void GenericRuntimeInfo(string arg0) /// The 'GenericJniInfo' diagnostic. /// /// -/// {arg0} +/// Info: {arg0} /// public void GenericJniInfo(string arg0) { @@ -118,7 +118,7 @@ public void GenericJniInfo(string arg0) /// The 'ClassNotFound' diagnostic. /// /// -/// Class "{arg0}" not found. +/// Warning: Class "{arg0}" not found. /// public void ClassNotFound(string arg0) { @@ -130,7 +130,7 @@ public void ClassNotFound(string arg0) /// The 'ClassFormatError' diagnostic. /// /// -/// Unable to compile class "{arg0}". (class format error "{arg1}") +/// Warning: Unable to compile class "{arg0}". (class format error "{arg1}") /// public void ClassFormatError(string arg0, string arg1) { @@ -142,7 +142,7 @@ public void ClassFormatError(string arg0, string arg1) /// The 'DuplicateClassName' diagnostic. /// /// -/// Duplicate class name: "{arg0}". +/// Warning: Duplicate class name: "{arg0}". /// public void DuplicateClassName(string arg0) { @@ -154,7 +154,7 @@ public void DuplicateClassName(string arg0) /// The 'IllegalAccessError' diagnostic. /// /// -/// Unable to compile class "{arg0}". (illegal access error "{arg1}") +/// Warning: Unable to compile class "{arg0}". (illegal access error "{arg1}") /// public void IllegalAccessError(string arg0, string arg1) { @@ -166,7 +166,7 @@ public void IllegalAccessError(string arg0, string arg1) /// The 'VerificationError' diagnostic. /// /// -/// Unable to compile class "{arg0}". (verification error "{arg1}") +/// Warning: Unable to compile class "{arg0}". (verification error "{arg1}") /// public void VerificationError(string arg0, string arg1) { @@ -178,7 +178,7 @@ public void VerificationError(string arg0, string arg1) /// The 'NoClassDefFoundError' diagnostic. /// /// -/// Unable to compile class "{arg0}". (missing class "{arg1}") +/// Warning: Unable to compile class "{arg0}". (missing class "{arg1}") /// public void NoClassDefFoundError(string arg0, string arg1) { @@ -190,7 +190,7 @@ public void NoClassDefFoundError(string arg0, string arg1) /// The 'GenericUnableToCompileError' diagnostic. /// /// -/// Unable to compile class "{arg0}". ("{arg1}": "{arg2}") +/// Warning: Unable to compile class "{arg0}". ("{arg1}": "{arg2}") /// public void GenericUnableToCompileError(string arg0, string arg1, string arg2) { @@ -202,7 +202,7 @@ public void GenericUnableToCompileError(string arg0, string arg1, string arg2) /// The 'DuplicateResourceName' diagnostic. /// /// -/// Skipping resource (name clash): "{arg0}" +/// Warning: Skipping resource (name clash): "{arg0}" /// public void DuplicateResourceName(string arg0) { @@ -214,7 +214,7 @@ public void DuplicateResourceName(string arg0) /// The 'SkippingReferencedClass' diagnostic. /// /// -/// Skipping class: "{arg0}". (class is already available in referenced assembly "{arg1}") +/// Warning: Skipping class: "{arg0}". (class is already available in referenced assembly "{arg1}") /// public void SkippingReferencedClass(string arg0, string arg1) { @@ -226,7 +226,7 @@ public void SkippingReferencedClass(string arg0, string arg1) /// The 'NoJniRuntime' diagnostic. /// /// -/// Unable to load runtime JNI assembly. +/// Warning: Unable to load runtime JNI assembly. /// public void NoJniRuntime() { @@ -238,7 +238,7 @@ public void NoJniRuntime() /// The 'EmittedNoClassDefFoundError' diagnostic. /// /// -/// Emitted java.lang.NoClassDefFoundError in "{arg0}". ("{arg1}"). +/// Warning: Emitted java.lang.NoClassDefFoundError in "{arg0}". ("{arg1}"). /// public void EmittedNoClassDefFoundError(string arg0, string arg1) { @@ -250,7 +250,7 @@ public void EmittedNoClassDefFoundError(string arg0, string arg1) /// The 'EmittedIllegalAccessError' diagnostic. /// /// -/// Emitted java.lang.IllegalAccessError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.IllegalAccessError in "{arg0}". ("{arg1}") /// public void EmittedIllegalAccessError(string arg0, string arg1) { @@ -262,7 +262,7 @@ public void EmittedIllegalAccessError(string arg0, string arg1) /// The 'EmittedInstantiationError' diagnostic. /// /// -/// Emitted java.lang.InstantiationError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.InstantiationError in "{arg0}". ("{arg1}") /// public void EmittedInstantiationError(string arg0, string arg1) { @@ -274,7 +274,7 @@ public void EmittedInstantiationError(string arg0, string arg1) /// The 'EmittedIncompatibleClassChangeError' diagnostic. /// /// -/// Emitted java.lang.IncompatibleClassChangeError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.IncompatibleClassChangeError in "{arg0}". ("{arg1}") /// public void EmittedIncompatibleClassChangeError(string arg0, string arg1) { @@ -286,7 +286,7 @@ public void EmittedIncompatibleClassChangeError(string arg0, string arg1) /// The 'EmittedNoSuchFieldError' diagnostic. /// /// -/// Emitted java.lang.NoSuchFieldError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.NoSuchFieldError in "{arg0}". ("{arg1}") /// public void EmittedNoSuchFieldError(string arg0, string arg1) { @@ -298,7 +298,7 @@ public void EmittedNoSuchFieldError(string arg0, string arg1) /// The 'EmittedAbstractMethodError' diagnostic. /// /// -/// Emitted java.lang.AbstractMethodError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.AbstractMethodError in "{arg0}". ("{arg1}") /// public void EmittedAbstractMethodError(string arg0, string arg1) { @@ -310,7 +310,7 @@ public void EmittedAbstractMethodError(string arg0, string arg1) /// The 'EmittedNoSuchMethodError' diagnostic. /// /// -/// Emitted java.lang.NoSuchMethodError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.NoSuchMethodError in "{arg0}". ("{arg1}") /// public void EmittedNoSuchMethodError(string arg0, string arg1) { @@ -322,7 +322,7 @@ public void EmittedNoSuchMethodError(string arg0, string arg1) /// The 'EmittedLinkageError' diagnostic. /// /// -/// Emitted java.lang.LinkageError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.LinkageError in "{arg0}". ("{arg1}") /// public void EmittedLinkageError(string arg0, string arg1) { @@ -334,7 +334,7 @@ public void EmittedLinkageError(string arg0, string arg1) /// The 'EmittedVerificationError' diagnostic. /// /// -/// Emitted java.lang.VerificationError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.VerificationError in "{arg0}". ("{arg1}") /// public void EmittedVerificationError(string arg0, string arg1) { @@ -346,7 +346,7 @@ public void EmittedVerificationError(string arg0, string arg1) /// The 'EmittedClassFormatError' diagnostic. /// /// -/// Emitted java.lang.ClassFormatError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.ClassFormatError in "{arg0}". ("{arg1}") /// public void EmittedClassFormatError(string arg0, string arg1) { @@ -358,7 +358,7 @@ public void EmittedClassFormatError(string arg0, string arg1) /// The 'InvalidCustomAttribute' diagnostic. /// /// -/// Error emitting "{arg0}" custom attribute. ("{arg1}") +/// Warning: Error emitting "{arg0}" custom attribute. ("{arg1}") /// public void InvalidCustomAttribute(string arg0, string arg1) { @@ -370,7 +370,7 @@ public void InvalidCustomAttribute(string arg0, string arg1) /// The 'IgnoredCustomAttribute' diagnostic. /// /// -/// Custom attribute "{arg0}" was ignored. ("{arg1}") +/// Warning: Custom attribute "{arg0}" was ignored. ("{arg1}") /// public void IgnoredCustomAttribute(string arg0, string arg1) { @@ -382,7 +382,7 @@ public void IgnoredCustomAttribute(string arg0, string arg1) /// The 'AssumeAssemblyVersionMatch' diagnostic. /// /// -/// Assuming assembly reference "{arg0}" matches "{arg1}", you may need to supply runtime policy +/// Warning: Assuming assembly reference "{arg0}" matches "{arg1}", you may need to supply runtime policy /// public void AssumeAssemblyVersionMatch(string arg0, string arg1) { @@ -394,7 +394,7 @@ public void AssumeAssemblyVersionMatch(string arg0, string arg1) /// The 'InvalidDirectoryInLibOptionPath' diagnostic. /// /// -/// Directory "{arg0}" specified in -lib option is not valid. +/// Warning: Directory "{arg0}" specified in -lib option is not valid. /// public void InvalidDirectoryInLibOptionPath(string arg0) { @@ -406,7 +406,7 @@ public void InvalidDirectoryInLibOptionPath(string arg0) /// The 'InvalidDirectoryInLibEnvironmentPath' diagnostic. /// /// -/// Directory "{arg0}" specified in LIB environment is not valid. +/// Warning: Directory "{arg0}" specified in LIB environment is not valid. /// public void InvalidDirectoryInLibEnvironmentPath(string arg0) { @@ -418,7 +418,7 @@ public void InvalidDirectoryInLibEnvironmentPath(string arg0) /// The 'LegacySearchRule' diagnostic. /// /// -/// Found assembly "{arg0}" using legacy search rule, please append '.dll' to the reference. +/// Warning: Found assembly "{arg0}" using legacy search rule, please append '.dll' to the reference. /// public void LegacySearchRule(string arg0) { @@ -430,7 +430,7 @@ public void LegacySearchRule(string arg0) /// The 'AssemblyLocationIgnored' diagnostic. /// /// -/// Assembly "{arg0}" is ignored as previously loaded assembly "{arg1}" has the same identity "{arg2}". +/// Warning: Assembly "{arg0}" is ignored as previously loaded assembly "{arg1}" has the same identity "{arg2}". /// public void AssemblyLocationIgnored(string arg0, string arg1, string arg2) { @@ -442,7 +442,7 @@ public void AssemblyLocationIgnored(string arg0, string arg1, string arg2) /// The 'InterfaceMethodCantBeInternal' diagnostic. /// /// -/// Ignoring @ikvm.lang.Internal annotation on interface method. ("{arg0}.{arg1}{arg2}") +/// Warning: Ignoring @ikvm.lang.Internal annotation on interface method. ("{arg0}.{arg1}{arg2}") /// public void InterfaceMethodCantBeInternal(string arg0, string arg1, string arg2) { @@ -454,7 +454,7 @@ public void InterfaceMethodCantBeInternal(string arg0, string arg1, string arg2) /// The 'DuplicateAssemblyReference' diagnostic. /// /// -/// Duplicate assembly reference "{arg0}" +/// Warning: Duplicate assembly reference "{arg0}" /// public void DuplicateAssemblyReference(string arg0) { @@ -466,7 +466,7 @@ public void DuplicateAssemblyReference(string arg0) /// The 'UnableToResolveType' diagnostic. /// /// -/// Reference in "{arg0}" to type "{arg1}" claims it is defined in "{arg2}", but it could not be found. +/// Warning: Reference in "{arg0}" to type "{arg1}" claims it is defined in "{arg2}", but it could not be found. /// public void UnableToResolveType(string arg0, string arg1, string arg2) { @@ -478,7 +478,7 @@ public void UnableToResolveType(string arg0, string arg1, string arg2) /// The 'StubsAreDeprecated' diagnostic. /// /// -/// Compiling stubs is deprecated. Please add a reference to assembly "{arg0}" instead. +/// Warning: Compiling stubs is deprecated. Please add a reference to assembly "{arg0}" instead. /// public void StubsAreDeprecated(string arg0) { @@ -490,7 +490,7 @@ public void StubsAreDeprecated(string arg0) /// The 'WrongClassName' diagnostic. /// /// -/// Unable to compile "{arg0}" (wrong name: "{arg1}") +/// Warning: Unable to compile "{arg0}" (wrong name: "{arg1}") /// public void WrongClassName(string arg0, string arg1) { @@ -502,7 +502,7 @@ public void WrongClassName(string arg0, string arg1) /// The 'ReflectionCallerClassRequiresCallerID' diagnostic. /// /// -/// Reflection.getCallerClass() called from non-CallerID method. ("{arg0}.{arg1}{arg2}") +/// Warning: Reflection.getCallerClass() called from non-CallerID method. ("{arg0}.{arg1}{arg2}") /// public void ReflectionCallerClassRequiresCallerID(string arg0, string arg1, string arg2) { @@ -514,7 +514,7 @@ public void ReflectionCallerClassRequiresCallerID(string arg0, string arg1, stri /// The 'LegacyAssemblyAttributesFound' diagnostic. /// /// -/// Legacy assembly attributes container found. Please use the -assemblyattributes: option. +/// Warning: Legacy assembly attributes container found. Please use the -assemblyattributes: option. /// public void LegacyAssemblyAttributesFound() { @@ -526,7 +526,7 @@ public void LegacyAssemblyAttributesFound() /// The 'UnableToCreateLambdaFactory' diagnostic. /// /// -/// Unable to create static lambda factory. +/// Warning: Unable to create static lambda factory. /// public void UnableToCreateLambdaFactory() { @@ -538,7 +538,7 @@ public void UnableToCreateLambdaFactory() /// The 'UnknownWarning' diagnostic. /// /// -/// {arg0} +/// Warning: {arg0} /// public void UnknownWarning(string arg0) { @@ -550,7 +550,7 @@ public void UnknownWarning(string arg0) /// The 'DuplicateIkvmLangProperty' diagnostic. /// /// -/// Ignoring duplicate ikvm.lang.Property annotation on {arg0}.{arg1}. +/// Warning: Ignoring duplicate ikvm.lang.Property annotation on {arg0}.{arg1}. /// public void DuplicateIkvmLangProperty(string arg0, string arg1) { @@ -562,7 +562,7 @@ public void DuplicateIkvmLangProperty(string arg0, string arg1) /// The 'MalformedIkvmLangProperty' diagnostic. /// /// -/// Ignoring duplicate ikvm.lang.Property annotation on {arg0}.{arg1}. +/// Warning: Ignoring duplicate ikvm.lang.Property annotation on {arg0}.{arg1}. /// public void MalformedIkvmLangProperty(string arg0, string arg1) { @@ -574,7 +574,7 @@ public void MalformedIkvmLangProperty(string arg0, string arg1) /// The 'GenericCompilerWarning' diagnostic. /// /// -/// {arg0} +/// Warning: {arg0} /// public void GenericCompilerWarning(string arg0) { @@ -586,7 +586,7 @@ public void GenericCompilerWarning(string arg0) /// The 'GenericClassLoadingWarning' diagnostic. /// /// -/// {arg0} +/// Warning: {arg0} /// public void GenericClassLoadingWarning(string arg0) { @@ -598,7 +598,7 @@ public void GenericClassLoadingWarning(string arg0) /// The 'GenericVerifierWarning' diagnostic. /// /// -/// {arg0} +/// Warning: {arg0} /// public void GenericVerifierWarning(string arg0) { @@ -610,7 +610,7 @@ public void GenericVerifierWarning(string arg0) /// The 'GenericRuntimeWarning' diagnostic. /// /// -/// {arg0} +/// Warning: {arg0} /// public void GenericRuntimeWarning(string arg0) { @@ -622,7 +622,7 @@ public void GenericRuntimeWarning(string arg0) /// The 'GenericJniWarning' diagnostic. /// /// -/// {arg0} +/// Warning: {arg0} /// public void GenericJniWarning(string arg0) { @@ -634,7 +634,7 @@ public void GenericJniWarning(string arg0) /// The 'UnableToCreateProxy' diagnostic. /// /// -/// Unable to create proxy "{arg0}". ("{arg1}") +/// Error: Unable to create proxy "{arg0}". ("{arg1}") /// public void UnableToCreateProxy(string arg0, string arg1) { @@ -646,7 +646,7 @@ public void UnableToCreateProxy(string arg0, string arg1) /// The 'DuplicateProxy' diagnostic. /// /// -/// Duplicate proxy "{arg0}". +/// Error: Duplicate proxy "{arg0}". /// public void DuplicateProxy(string arg0) { @@ -658,7 +658,7 @@ public void DuplicateProxy(string arg0) /// The 'MapXmlUnableToResolveOpCode' diagnostic. /// /// -/// Unable to resolve opcode in remap file: {arg0}. +/// Error: Unable to resolve opcode in remap file: {arg0}. /// public void MapXmlUnableToResolveOpCode(string arg0) { @@ -670,7 +670,7 @@ public void MapXmlUnableToResolveOpCode(string arg0) /// The 'MapXmlError' diagnostic. /// /// -/// Error in remap file: {arg0}. +/// Error: Error in remap file: {arg0}. /// public void MapXmlError(string arg0) { @@ -682,7 +682,7 @@ public void MapXmlError(string arg0) /// The 'InputFileNotFound' diagnostic. /// /// -/// Source file '{arg0}' not found. +/// Error: Source file '{arg0}' not found. /// public void InputFileNotFound(string arg0) { @@ -694,7 +694,7 @@ public void InputFileNotFound(string arg0) /// The 'UnknownFileType' diagnostic. /// /// -/// Unknown file type: {arg0}. +/// Error: Unknown file type: {arg0}. /// public void UnknownFileType(string arg0) { @@ -706,7 +706,7 @@ public void UnknownFileType(string arg0) /// The 'UnknownElementInMapFile' diagnostic. /// /// -/// Unknown element {arg0} in remap file, line {arg1}, column {arg2}. +/// Error: Unknown element {arg0} in remap file, line {arg1}, column {arg2}. /// public void UnknownElementInMapFile(string arg0, string arg1, string arg2) { @@ -718,7 +718,7 @@ public void UnknownElementInMapFile(string arg0, string arg1, string arg2) /// The 'UnknownAttributeInMapFile' diagnostic. /// /// -/// Unknown attribute {arg0} in remap file, line {arg1}, column {arg2}. +/// Error: Unknown attribute {arg0} in remap file, line {arg1}, column {arg2}. /// public void UnknownAttributeInMapFile(string arg0, string arg1, string arg2) { @@ -730,7 +730,7 @@ public void UnknownAttributeInMapFile(string arg0, string arg1, string arg2) /// The 'InvalidMemberNameInMapFile' diagnostic. /// /// -/// Invalid {arg0} name '{arg1}' in remap file in class {arg2}. +/// Error: Invalid {arg0} name '{arg1}' in remap file in class {arg2}. /// public void InvalidMemberNameInMapFile(string arg0, string arg1, string arg2) { @@ -742,7 +742,7 @@ public void InvalidMemberNameInMapFile(string arg0, string arg1, string arg2) /// The 'InvalidMemberSignatureInMapFile' diagnostic. /// /// -/// Invalid {arg0} signature '{arg3}' in remap file for {arg0} {arg1}.{arg2}. +/// Error: Invalid {arg0} signature '{arg3}' in remap file for {arg0} {arg1}.{arg2}. /// public void InvalidMemberSignatureInMapFile(string arg0, string arg1, string arg2, string arg3) { @@ -754,7 +754,7 @@ public void InvalidMemberSignatureInMapFile(string arg0, string arg1, string arg /// The 'InvalidPropertyNameInMapFile' diagnostic. /// /// -/// Invalid property {arg0} name '{arg3}' in remap file for property {arg1}.{arg2}. +/// Error: Invalid property {arg0} name '{arg3}' in remap file for property {arg1}.{arg2}. /// public void InvalidPropertyNameInMapFile(string arg0, string arg1, string arg2, string arg3) { @@ -766,7 +766,7 @@ public void InvalidPropertyNameInMapFile(string arg0, string arg1, string arg2, /// The 'InvalidPropertySignatureInMapFile' diagnostic. /// /// -/// Invalid property {arg0} signature '{arg3}' in remap file for property {arg1}.{arg2}. +/// Error: Invalid property {arg0} signature '{arg3}' in remap file for property {arg1}.{arg2}. /// public void InvalidPropertySignatureInMapFile(string arg0, string arg1, string arg2, string arg3) { @@ -778,7 +778,7 @@ public void InvalidPropertySignatureInMapFile(string arg0, string arg1, string a /// The 'NonPrimaryAssemblyReference' diagnostic. /// /// -/// Referenced assembly "{arg0}" is not the primary assembly of a shared class loader group, please reference primary assembly "{arg1}" instead. +/// Error: Referenced assembly "{arg0}" is not the primary assembly of a shared class loader group, please reference primary assembly "{arg1}" instead. /// public void NonPrimaryAssemblyReference(string arg0, string arg1) { @@ -790,7 +790,7 @@ public void NonPrimaryAssemblyReference(string arg0, string arg1) /// The 'MissingType' diagnostic. /// /// -/// Reference to type "{arg0}" claims it is defined in "{arg1}", but it could not be found. +/// Error: Reference to type "{arg0}" claims it is defined in "{arg1}", but it could not be found. /// public void MissingType(string arg0, string arg1) { @@ -802,7 +802,7 @@ public void MissingType(string arg0, string arg1) /// The 'MissingReference' diagnostic. /// /// -/// The type '{arg0}' is defined in an assembly that is notResponseFileDepthExceeded referenced. You must add a reference to assembly '{arg1}'. +/// Error: The type '{arg0}' is defined in an assembly that is notResponseFileDepthExceeded referenced. You must add a reference to assembly '{arg1}'. /// public void MissingReference(string arg0, string arg1) { @@ -814,7 +814,7 @@ public void MissingReference(string arg0, string arg1) /// The 'CallerSensitiveOnUnsupportedMethod' diagnostic. /// /// -/// CallerSensitive annotation on unsupported method. ("{arg0}.{arg1}{arg2}") +/// Error: CallerSensitive annotation on unsupported method. ("{arg0}.{arg1}{arg2}") /// public void CallerSensitiveOnUnsupportedMethod(string arg0, string arg1, string arg2) { @@ -826,7 +826,7 @@ public void CallerSensitiveOnUnsupportedMethod(string arg0, string arg1, string /// The 'RemappedTypeMissingDefaultInterfaceMethod' diagnostic. /// /// -/// {arg0} does not implement default interface method {arg1}. +/// Error: {arg0} does not implement default interface method {arg1}. /// public void RemappedTypeMissingDefaultInterfaceMethod(string arg0, string arg1) { @@ -838,7 +838,7 @@ public void RemappedTypeMissingDefaultInterfaceMethod(string arg0, string arg1) /// The 'GenericCompilerError' diagnostic. /// /// -/// {arg0} +/// Error: {arg0} /// public void GenericCompilerError(string arg0) { @@ -850,7 +850,7 @@ public void GenericCompilerError(string arg0) /// The 'GenericClassLoadingError' diagnostic. /// /// -/// {arg0} +/// Error: {arg0} /// public void GenericClassLoadingError(string arg0) { @@ -862,7 +862,7 @@ public void GenericClassLoadingError(string arg0) /// The 'GenericVerifierError' diagnostic. /// /// -/// {arg0} +/// Error: {arg0} /// public void GenericVerifierError(string arg0) { @@ -874,7 +874,7 @@ public void GenericVerifierError(string arg0) /// The 'GenericRuntimeError' diagnostic. /// /// -/// {arg0} +/// Error: {arg0} /// public void GenericRuntimeError(string arg0) { @@ -886,7 +886,7 @@ public void GenericRuntimeError(string arg0) /// The 'GenericJniError' diagnostic. /// /// -/// {arg0} +/// Error: {arg0} /// public void GenericJniError(string arg0) { @@ -898,7 +898,7 @@ public void GenericJniError(string arg0) /// The 'ExportingImportsNotSupported' diagnostic. /// /// -/// Exporting previously imported assemblies is not supported. +/// Error: Exporting previously imported assemblies is not supported. /// public void ExportingImportsNotSupported() { @@ -910,7 +910,7 @@ public void ExportingImportsNotSupported() /// The 'ResponseFileDepthExceeded' diagnostic. /// /// -/// Response file nesting depth exceeded. +/// Fatal: Response file nesting depth exceeded. /// public void ResponseFileDepthExceeded() { @@ -922,7 +922,7 @@ public void ResponseFileDepthExceeded() /// The 'ErrorReadingFile' diagnostic. /// /// -/// Unable to read file: {arg0}. ({arg1}) +/// Fatal: Unable to read file: {arg0}. ({arg1}) /// public void ErrorReadingFile(string arg0, string arg1) { @@ -934,7 +934,7 @@ public void ErrorReadingFile(string arg0, string arg1) /// The 'NoTargetsFound' diagnostic. /// /// -/// No targets found +/// Fatal: No targets found /// public void NoTargetsFound() { @@ -946,7 +946,7 @@ public void NoTargetsFound() /// The 'FileFormatLimitationExceeded' diagnostic. /// /// -/// File format limitation exceeded: {arg0}. +/// Fatal: File format limitation exceeded: {arg0}. /// public void FileFormatLimitationExceeded(string arg0) { @@ -958,7 +958,7 @@ public void FileFormatLimitationExceeded(string arg0) /// The 'CannotSpecifyBothKeyFileAndContainer' diagnostic. /// /// -/// You cannot specify both a key file and container. +/// Fatal: You cannot specify both a key file and container. /// public void CannotSpecifyBothKeyFileAndContainer() { @@ -970,7 +970,7 @@ public void CannotSpecifyBothKeyFileAndContainer() /// The 'DelaySignRequiresKey' diagnostic. /// /// -/// You cannot delay sign without a key file or container. +/// Fatal: You cannot delay sign without a key file or container. /// public void DelaySignRequiresKey() { @@ -982,7 +982,7 @@ public void DelaySignRequiresKey() /// The 'InvalidStrongNameKeyPair' diagnostic. /// /// -/// Invalid key {arg0} specified. ("{arg1}") +/// Fatal: Invalid key {arg0} specified. ("{arg1}") /// public void InvalidStrongNameKeyPair(string arg0, string arg1) { @@ -994,7 +994,7 @@ public void InvalidStrongNameKeyPair(string arg0, string arg1) /// The 'ReferenceNotFound' diagnostic. /// /// -/// Reference not found: {arg0} +/// Fatal: Reference not found: {arg0} /// public void ReferenceNotFound(string arg0) { @@ -1006,7 +1006,7 @@ public void ReferenceNotFound(string arg0) /// The 'OptionsMustPreceedChildLevels' diagnostic. /// /// -/// You can only specify options before any child levels. +/// Fatal: You can only specify options before any child levels. /// public void OptionsMustPreceedChildLevels() { @@ -1018,7 +1018,7 @@ public void OptionsMustPreceedChildLevels() /// The 'UnrecognizedTargetType' diagnostic. /// /// -/// Invalid value '{arg0}' for -target option. +/// Fatal: Invalid value '{arg0}' for -target option. /// public void UnrecognizedTargetType(string arg0) { @@ -1030,7 +1030,7 @@ public void UnrecognizedTargetType(string arg0) /// The 'UnrecognizedPlatform' diagnostic. /// /// -/// Invalid value '{arg0}' for -platform option. +/// Fatal: Invalid value '{arg0}' for -platform option. /// public void UnrecognizedPlatform(string arg0) { @@ -1042,7 +1042,7 @@ public void UnrecognizedPlatform(string arg0) /// The 'UnrecognizedApartment' diagnostic. /// /// -/// Invalid value '{arg0}' for -apartment option. +/// Fatal: Invalid value '{arg0}' for -apartment option. /// public void UnrecognizedApartment(string arg0) { @@ -1054,7 +1054,7 @@ public void UnrecognizedApartment(string arg0) /// The 'MissingFileSpecification' diagnostic. /// /// -/// Missing file specification for '{arg0}' option. +/// Fatal: Missing file specification for '{arg0}' option. /// public void MissingFileSpecification(string arg0) { @@ -1066,7 +1066,7 @@ public void MissingFileSpecification(string arg0) /// The 'PathTooLong' diagnostic. /// /// -/// Path too long: {arg0}. +/// Fatal: Path too long: {arg0}. /// public void PathTooLong(string arg0) { @@ -1078,7 +1078,7 @@ public void PathTooLong(string arg0) /// The 'PathNotFound' diagnostic. /// /// -/// Path not found: {arg0}. +/// Fatal: Path not found: {arg0}. /// public void PathNotFound(string arg0) { @@ -1090,7 +1090,7 @@ public void PathNotFound(string arg0) /// The 'InvalidPath' diagnostic. /// /// -/// Invalid path: {arg0}. +/// Fatal: Invalid path: {arg0}. /// public void InvalidPath(string arg0) { @@ -1102,7 +1102,7 @@ public void InvalidPath(string arg0) /// The 'InvalidOptionSyntax' diagnostic. /// /// -/// Invalid option: {arg0}. +/// Fatal: Invalid option: {arg0}. /// public void InvalidOptionSyntax(string arg0) { @@ -1114,7 +1114,7 @@ public void InvalidOptionSyntax(string arg0) /// The 'ExternalResourceNotFound' diagnostic. /// /// -/// External resource file does not exist: {arg0}. +/// Fatal: External resource file does not exist: {arg0}. /// public void ExternalResourceNotFound(string arg0) { @@ -1126,7 +1126,7 @@ public void ExternalResourceNotFound(string arg0) /// The 'ExternalResourceNameInvalid' diagnostic. /// /// -/// External resource file may not include path specification: {arg0}. +/// Fatal: External resource file may not include path specification: {arg0}. /// public void ExternalResourceNameInvalid(string arg0) { @@ -1138,7 +1138,7 @@ public void ExternalResourceNameInvalid(string arg0) /// The 'InvalidVersionFormat' diagnostic. /// /// -/// Invalid version specified: {arg0}. +/// Fatal: Invalid version specified: {arg0}. /// public void InvalidVersionFormat(string arg0) { @@ -1150,7 +1150,7 @@ public void InvalidVersionFormat(string arg0) /// The 'InvalidFileAlignment' diagnostic. /// /// -/// Invalid value '{arg0}' for -filealign option. +/// Fatal: Invalid value '{arg0}' for -filealign option. /// public void InvalidFileAlignment(string arg0) { @@ -1162,7 +1162,7 @@ public void InvalidFileAlignment(string arg0) /// The 'ErrorWritingFile' diagnostic. /// /// -/// Unable to write file: {arg0}. ({arg1}) +/// Fatal: Unable to write file: {arg0}. ({arg1}) /// public void ErrorWritingFile(string arg0, string arg1) { @@ -1174,7 +1174,7 @@ public void ErrorWritingFile(string arg0, string arg1) /// The 'UnrecognizedOption' diagnostic. /// /// -/// Unrecognized option: {arg0}. +/// Fatal: Unrecognized option: {arg0}. /// public void UnrecognizedOption(string arg0) { @@ -1186,7 +1186,7 @@ public void UnrecognizedOption(string arg0) /// The 'NoOutputFileSpecified' diagnostic. /// /// -/// No output file specified. +/// Fatal: No output file specified. /// public void NoOutputFileSpecified() { @@ -1198,7 +1198,7 @@ public void NoOutputFileSpecified() /// The 'SharedClassLoaderCannotBeUsedOnModuleTarget' diagnostic. /// /// -/// Incompatible options: -target:module and -sharedclassloader cannot be combined. +/// Fatal: Incompatible options: -target:module and -sharedclassloader cannot be combined. /// public void SharedClassLoaderCannotBeUsedOnModuleTarget() { @@ -1210,7 +1210,7 @@ public void SharedClassLoaderCannotBeUsedOnModuleTarget() /// The 'RuntimeNotFound' diagnostic. /// /// -/// Unable to load runtime assembly. +/// Fatal: Unable to load runtime assembly. /// public void RuntimeNotFound() { @@ -1222,7 +1222,7 @@ public void RuntimeNotFound() /// The 'MainClassRequiresExe' diagnostic. /// /// -/// Main class cannot be specified for library or module. +/// Fatal: Main class cannot be specified for library or module. /// public void MainClassRequiresExe() { @@ -1234,7 +1234,7 @@ public void MainClassRequiresExe() /// The 'ExeRequiresMainClass' diagnostic. /// /// -/// No main method found. +/// Fatal: No main method found. /// public void ExeRequiresMainClass() { @@ -1246,7 +1246,7 @@ public void ExeRequiresMainClass() /// The 'PropertiesRequireExe' diagnostic. /// /// -/// Properties cannot be specified for library or module. +/// Fatal: Properties cannot be specified for library or module. /// public void PropertiesRequireExe() { @@ -1258,7 +1258,7 @@ public void PropertiesRequireExe() /// The 'ModuleCannotHaveClassLoader' diagnostic. /// /// -/// Cannot specify assembly class loader for modules. +/// Fatal: Cannot specify assembly class loader for modules. /// public void ModuleCannotHaveClassLoader() { @@ -1270,7 +1270,7 @@ public void ModuleCannotHaveClassLoader() /// The 'ErrorParsingMapFile' diagnostic. /// /// -/// Unable to parse remap file: {arg0}. ({arg1}) +/// Fatal: Unable to parse remap file: {arg0}. ({arg1}) /// public void ErrorParsingMapFile(string arg0, string arg1) { @@ -1282,7 +1282,7 @@ public void ErrorParsingMapFile(string arg0, string arg1) /// The 'BootstrapClassesMissing' diagnostic. /// /// -/// Bootstrap classes missing and core assembly not found. +/// Fatal: Bootstrap classes missing and core assembly not found. /// public void BootstrapClassesMissing() { @@ -1294,7 +1294,7 @@ public void BootstrapClassesMissing() /// The 'StrongNameRequiresStrongNamedRefs' diagnostic. /// /// -/// All referenced assemblies must be strong named, to be able to sign the output assembly. +/// Fatal: All referenced assemblies must be strong named, to be able to sign the output assembly. /// public void StrongNameRequiresStrongNamedRefs() { @@ -1306,7 +1306,7 @@ public void StrongNameRequiresStrongNamedRefs() /// The 'MainClassNotFound' diagnostic. /// /// -/// Main class not found. +/// Fatal: Main class not found. /// public void MainClassNotFound() { @@ -1318,7 +1318,7 @@ public void MainClassNotFound() /// The 'MainMethodNotFound' diagnostic. /// /// -/// Main method not found. +/// Fatal: Main method not found. /// public void MainMethodNotFound() { @@ -1330,7 +1330,7 @@ public void MainMethodNotFound() /// The 'UnsupportedMainMethod' diagnostic. /// /// -/// Redirected main method not supported. +/// Fatal: Redirected main method not supported. /// public void UnsupportedMainMethod() { @@ -1342,7 +1342,7 @@ public void UnsupportedMainMethod() /// The 'ExternalMainNotAccessible' diagnostic. /// /// -/// External main method must be public and in a public class. +/// Fatal: External main method must be public and in a public class. /// public void ExternalMainNotAccessible() { @@ -1354,7 +1354,7 @@ public void ExternalMainNotAccessible() /// The 'ClassLoaderNotFound' diagnostic. /// /// -/// Custom assembly class loader class not found. +/// Fatal: Custom assembly class loader class not found. /// public void ClassLoaderNotFound() { @@ -1366,7 +1366,7 @@ public void ClassLoaderNotFound() /// The 'ClassLoaderNotAccessible' diagnostic. /// /// -/// Custom assembly class loader class is not accessible. +/// Fatal: Custom assembly class loader class is not accessible. /// public void ClassLoaderNotAccessible() { @@ -1378,7 +1378,7 @@ public void ClassLoaderNotAccessible() /// The 'ClassLoaderIsAbstract' diagnostic. /// /// -/// Custom assembly class loader class is abstract. +/// Fatal: Custom assembly class loader class is abstract. /// public void ClassLoaderIsAbstract() { @@ -1390,7 +1390,7 @@ public void ClassLoaderIsAbstract() /// The 'ClassLoaderNotClassLoader' diagnostic. /// /// -/// Custom assembly class loader class does not extend java.lang.ClassLoader. +/// Fatal: Custom assembly class loader class does not extend java.lang.ClassLoader. /// public void ClassLoaderNotClassLoader() { @@ -1402,7 +1402,7 @@ public void ClassLoaderNotClassLoader() /// The 'ClassLoaderConstructorMissing' diagnostic. /// /// -/// Custom assembly class loader constructor is missing. +/// Fatal: Custom assembly class loader constructor is missing. /// public void ClassLoaderConstructorMissing() { @@ -1414,7 +1414,7 @@ public void ClassLoaderConstructorMissing() /// The 'MapFileTypeNotFound' diagnostic. /// /// -/// Type '{arg0}' referenced in remap file was not found. +/// Fatal: Type '{arg0}' referenced in remap file was not found. /// public void MapFileTypeNotFound(string arg0) { @@ -1426,7 +1426,7 @@ public void MapFileTypeNotFound(string arg0) /// The 'MapFileClassNotFound' diagnostic. /// /// -/// Class '{arg0}' referenced in remap file was not found. +/// Fatal: Class '{arg0}' referenced in remap file was not found. /// public void MapFileClassNotFound(string arg0) { @@ -1438,7 +1438,7 @@ public void MapFileClassNotFound(string arg0) /// The 'MaximumErrorCountReached' diagnostic. /// /// -/// Maximum error count reached. +/// Fatal: Maximum error count reached. /// public void MaximumErrorCountReached() { @@ -1450,7 +1450,7 @@ public void MaximumErrorCountReached() /// The 'LinkageError' diagnostic. /// /// -/// Link error: {arg0} +/// Fatal: Link error: {arg0} /// public void LinkageError(string arg0) { @@ -1462,7 +1462,7 @@ public void LinkageError(string arg0) /// The 'RuntimeMismatch' diagnostic. /// /// -/// Referenced assembly {referencedAssemblyPath} was compiled with an incompatible IKVM.Runtime version. Current runtime: {runtimeAssemblyName}. Referenced assembly runtime: {referencedAssemblyName} +/// Fatal: Referenced assembly {referencedAssemblyPath} was compiled with an incompatible IKVM.Runtime version. Current runtime: {runtimeAssemblyName}. Referenced assembly runtime: {referencedAssemblyName} /// public void RuntimeMismatch(string referencedAssemblyPath, string runtimeAssemblyName, string referencedAssemblyName) { @@ -1474,7 +1474,7 @@ public void RuntimeMismatch(string referencedAssemblyPath, string runtimeAssembl /// The 'RuntimeMismatchStrongName' diagnostic. /// /// -/// +/// Fatal: /// public void RuntimeMismatchStrongName() { @@ -1486,7 +1486,7 @@ public void RuntimeMismatchStrongName() /// The 'CoreClassesMissing' diagnostic. /// /// -/// Failed to find core classes in core library. +/// Fatal: Failed to find core classes in core library. /// public void CoreClassesMissing() { @@ -1498,7 +1498,7 @@ public void CoreClassesMissing() /// The 'CriticalClassNotFound' diagnostic. /// /// -/// Unable to load critical class '{arg0}'. +/// Fatal: Unable to load critical class '{arg0}'. /// public void CriticalClassNotFound(string arg0) { @@ -1510,7 +1510,7 @@ public void CriticalClassNotFound(string arg0) /// The 'AssemblyContainsDuplicateClassNames' diagnostic. /// /// -/// Type '{arg0}' and '{arg1}' both map to the same name '{arg2}'. ({arg3}) +/// Fatal: Type '{arg0}' and '{arg1}' both map to the same name '{arg2}'. ({arg3}) /// public void AssemblyContainsDuplicateClassNames(string arg0, string arg1, string arg2, string arg3) { @@ -1522,7 +1522,7 @@ public void AssemblyContainsDuplicateClassNames(string arg0, string arg1, string /// The 'CallerIDRequiresHasCallerIDAnnotation' diagnostic. /// /// -/// CallerID.getCallerID() requires a HasCallerID annotation. +/// Fatal: CallerID.getCallerID() requires a HasCallerID annotation. /// public void CallerIDRequiresHasCallerIDAnnotation() { @@ -1534,7 +1534,7 @@ public void CallerIDRequiresHasCallerIDAnnotation() /// The 'UnableToResolveInterface' diagnostic. /// /// -/// Unable to resolve interface '{arg0}' on type '{arg1}'. +/// Fatal: Unable to resolve interface '{arg0}' on type '{arg1}'. /// public void UnableToResolveInterface(string arg0, string arg1) { @@ -1546,7 +1546,7 @@ public void UnableToResolveInterface(string arg0, string arg1) /// The 'MissingBaseType' diagnostic. /// /// -/// The base class or interface '{arg0}' in assembly '{arg1}' referenced by type '{arg2}' in '{arg3}' could not be resolved. +/// Fatal: The base class or interface '{arg0}' in assembly '{arg1}' referenced by type '{arg2}' in '{arg3}' could not be resolved. /// public void MissingBaseType(string arg0, string arg1, string arg2, string arg3) { @@ -1558,7 +1558,7 @@ public void MissingBaseType(string arg0, string arg1, string arg2, string arg3) /// The 'MissingBaseTypeReference' diagnostic. /// /// -/// The type '{arg0}' is defined in an assembly that is not referenced. You must add a reference to assembly '{arg1}'. +/// Fatal: The type '{arg0}' is defined in an assembly that is not referenced. You must add a reference to assembly '{arg1}'. /// public void MissingBaseTypeReference(string arg0, string arg1) { @@ -1570,7 +1570,7 @@ public void MissingBaseTypeReference(string arg0, string arg1) /// The 'FileNotFound' diagnostic. /// /// -/// File not found: {arg0}. +/// Fatal: File not found: {arg0}. /// public void FileNotFound(string arg0) { @@ -1582,7 +1582,7 @@ public void FileNotFound(string arg0) /// The 'RuntimeMethodMissing' diagnostic. /// /// -/// Runtime method '{arg0}' not found. +/// Fatal: Runtime method '{arg0}' not found. /// public void RuntimeMethodMissing(string arg0) { @@ -1594,7 +1594,7 @@ public void RuntimeMethodMissing(string arg0) /// The 'MapFileFieldNotFound' diagnostic. /// /// -/// Field '{arg0}' referenced in remap file was not found in class '{arg1}'. +/// Fatal: Field '{arg0}' referenced in remap file was not found in class '{arg1}'. /// public void MapFileFieldNotFound(string arg0, string arg1) { @@ -1606,7 +1606,7 @@ public void MapFileFieldNotFound(string arg0, string arg1) /// The 'GhostInterfaceMethodMissing' diagnostic. /// /// -/// Remapped class '{arg0}' does not implement ghost interface method. ({arg1}.{arg2}{arg3}) +/// Fatal: Remapped class '{arg0}' does not implement ghost interface method. ({arg1}.{arg2}{arg3}) /// public void GhostInterfaceMethodMissing(string arg0, string arg1, string arg2, string arg3) { @@ -1618,7 +1618,7 @@ public void GhostInterfaceMethodMissing(string arg0, string arg1, string arg2, s /// The 'ModuleInitializerMethodRequirements' diagnostic. /// /// -/// Method '{arg1}.{arg2}{arg3}' does not meet the requirements of a module initializer. +/// Fatal: Method '{arg1}.{arg2}{arg3}' does not meet the requirements of a module initializer. /// public void ModuleInitializerMethodRequirements(string arg1, string arg2, string arg3) { @@ -1630,7 +1630,7 @@ public void ModuleInitializerMethodRequirements(string arg1, string arg2, string /// The 'InvalidZip' diagnostic. /// /// -/// Invalid zip: {name}. +/// Fatal: Invalid zip: {name}. /// public void InvalidZip(string name) { @@ -1642,7 +1642,7 @@ public void InvalidZip(string name) /// The 'CoreAssemblyVersionMismatch' diagnostic. /// /// -/// Unable to load assembly '{0}' as it depends on a higher version of {1} than the one currently loaded. +/// Fatal: Unable to load assembly '{0}' as it depends on a higher version of {1} than the one currently loaded. /// public void CoreAssemblyVersionMismatch(string arg0, string arg1) { @@ -1654,7 +1654,7 @@ public void CoreAssemblyVersionMismatch(string arg0, string arg1) /// The 'GenericRuntimeTrace' diagnostic. /// /// -/// {arg0} +/// Trace: {arg0} /// public void GenericRuntimeTrace(string arg0) { @@ -1666,7 +1666,7 @@ public void GenericRuntimeTrace(string arg0) /// The 'GenericJniTrace' diagnostic. /// /// -/// {arg0} +/// Trace: {arg0} /// public void GenericJniTrace(string arg0) { @@ -1678,7 +1678,7 @@ public void GenericJniTrace(string arg0) /// The 'GenericCompilerTrace' diagnostic. /// /// -/// {arg0} +/// Trace: {arg0} /// public void GenericCompilerTrace(string arg0) { diff --git a/src/IKVM.CoreLib/Diagnostics/DiagnosticEventHandler.g.tt b/src/IKVM.CoreLib/Diagnostics/DiagnosticEventHandler.g.tt index 415e1deed..328b47bcc 100644 --- a/src/IKVM.CoreLib/Diagnostics/DiagnosticEventHandler.g.tt +++ b/src/IKVM.CoreLib/Diagnostics/DiagnosticEventHandler.g.tt @@ -45,7 +45,7 @@ foreach (var kvp in DiagnosticFile.Read(Host.ResolvePath(Path.Combine("Diagnosti /// <#= desc #> /// /// -<#= Util.ToCommentString(kvp.Value.Message ?? "") #> +<#= Util.ToCommentString(kvp.Value) #> /// public void <#= kvp.Key #>(<#= string.Join(", ", argDecl) #>) { diff --git a/src/IKVM.CoreLib/Diagnostics/IDiagnosticHandler.g.cs b/src/IKVM.CoreLib/Diagnostics/IDiagnosticHandler.g.cs index 1bac0acbc..cbd53a727 100644 --- a/src/IKVM.CoreLib/Diagnostics/IDiagnosticHandler.g.cs +++ b/src/IKVM.CoreLib/Diagnostics/IDiagnosticHandler.g.cs @@ -10,7 +10,7 @@ partial interface IDiagnosticHandler /// The 'MainMethodFound' diagnostic. /// /// -/// Found main method in class "{arg0}". +/// Info: Found main method in class "{arg0}". /// void MainMethodFound(string arg0); @@ -18,7 +18,7 @@ partial interface IDiagnosticHandler /// The 'OutputFileIs' diagnostic. /// /// -/// Output file is "{arg0}". +/// Info: Output file is "{arg0}". /// void OutputFileIs(string arg0); @@ -26,7 +26,7 @@ partial interface IDiagnosticHandler /// The 'AutoAddRef' diagnostic. /// /// -/// Automatically adding reference to "{arg0}". +/// Info: Automatically adding reference to "{arg0}". /// void AutoAddRef(string arg0); @@ -34,7 +34,7 @@ partial interface IDiagnosticHandler /// The 'MainMethodFromManifest' diagnostic. /// /// -/// Using main class "{arg0}" based on jar manifest. +/// Info: Using main class "{arg0}" based on jar manifest. /// void MainMethodFromManifest(string arg0); @@ -42,7 +42,7 @@ partial interface IDiagnosticHandler /// The 'GenericCompilerInfo' diagnostic. /// /// -/// {arg0} +/// Info: {arg0} /// void GenericCompilerInfo(string arg0); @@ -50,7 +50,7 @@ partial interface IDiagnosticHandler /// The 'GenericClassLoadingInfo' diagnostic. /// /// -/// {arg0} +/// Info: {arg0} /// void GenericClassLoadingInfo(string arg0); @@ -58,7 +58,7 @@ partial interface IDiagnosticHandler /// The 'GenericVerifierInfo' diagnostic. /// /// -/// {arg0} +/// Info: {arg0} /// void GenericVerifierInfo(string arg0); @@ -66,7 +66,7 @@ partial interface IDiagnosticHandler /// The 'GenericRuntimeInfo' diagnostic. /// /// -/// {arg0} +/// Info: {arg0} /// void GenericRuntimeInfo(string arg0); @@ -74,7 +74,7 @@ partial interface IDiagnosticHandler /// The 'GenericJniInfo' diagnostic. /// /// -/// {arg0} +/// Info: {arg0} /// void GenericJniInfo(string arg0); @@ -82,7 +82,7 @@ partial interface IDiagnosticHandler /// The 'ClassNotFound' diagnostic. /// /// -/// Class "{arg0}" not found. +/// Warning: Class "{arg0}" not found. /// void ClassNotFound(string arg0); @@ -90,7 +90,7 @@ partial interface IDiagnosticHandler /// The 'ClassFormatError' diagnostic. /// /// -/// Unable to compile class "{arg0}". (class format error "{arg1}") +/// Warning: Unable to compile class "{arg0}". (class format error "{arg1}") /// void ClassFormatError(string arg0, string arg1); @@ -98,7 +98,7 @@ partial interface IDiagnosticHandler /// The 'DuplicateClassName' diagnostic. /// /// -/// Duplicate class name: "{arg0}". +/// Warning: Duplicate class name: "{arg0}". /// void DuplicateClassName(string arg0); @@ -106,7 +106,7 @@ partial interface IDiagnosticHandler /// The 'IllegalAccessError' diagnostic. /// /// -/// Unable to compile class "{arg0}". (illegal access error "{arg1}") +/// Warning: Unable to compile class "{arg0}". (illegal access error "{arg1}") /// void IllegalAccessError(string arg0, string arg1); @@ -114,7 +114,7 @@ partial interface IDiagnosticHandler /// The 'VerificationError' diagnostic. /// /// -/// Unable to compile class "{arg0}". (verification error "{arg1}") +/// Warning: Unable to compile class "{arg0}". (verification error "{arg1}") /// void VerificationError(string arg0, string arg1); @@ -122,7 +122,7 @@ partial interface IDiagnosticHandler /// The 'NoClassDefFoundError' diagnostic. /// /// -/// Unable to compile class "{arg0}". (missing class "{arg1}") +/// Warning: Unable to compile class "{arg0}". (missing class "{arg1}") /// void NoClassDefFoundError(string arg0, string arg1); @@ -130,7 +130,7 @@ partial interface IDiagnosticHandler /// The 'GenericUnableToCompileError' diagnostic. /// /// -/// Unable to compile class "{arg0}". ("{arg1}": "{arg2}") +/// Warning: Unable to compile class "{arg0}". ("{arg1}": "{arg2}") /// void GenericUnableToCompileError(string arg0, string arg1, string arg2); @@ -138,7 +138,7 @@ partial interface IDiagnosticHandler /// The 'DuplicateResourceName' diagnostic. /// /// -/// Skipping resource (name clash): "{arg0}" +/// Warning: Skipping resource (name clash): "{arg0}" /// void DuplicateResourceName(string arg0); @@ -146,7 +146,7 @@ partial interface IDiagnosticHandler /// The 'SkippingReferencedClass' diagnostic. /// /// -/// Skipping class: "{arg0}". (class is already available in referenced assembly "{arg1}") +/// Warning: Skipping class: "{arg0}". (class is already available in referenced assembly "{arg1}") /// void SkippingReferencedClass(string arg0, string arg1); @@ -154,7 +154,7 @@ partial interface IDiagnosticHandler /// The 'NoJniRuntime' diagnostic. /// /// -/// Unable to load runtime JNI assembly. +/// Warning: Unable to load runtime JNI assembly. /// void NoJniRuntime(); @@ -162,7 +162,7 @@ partial interface IDiagnosticHandler /// The 'EmittedNoClassDefFoundError' diagnostic. /// /// -/// Emitted java.lang.NoClassDefFoundError in "{arg0}". ("{arg1}"). +/// Warning: Emitted java.lang.NoClassDefFoundError in "{arg0}". ("{arg1}"). /// void EmittedNoClassDefFoundError(string arg0, string arg1); @@ -170,7 +170,7 @@ partial interface IDiagnosticHandler /// The 'EmittedIllegalAccessError' diagnostic. /// /// -/// Emitted java.lang.IllegalAccessError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.IllegalAccessError in "{arg0}". ("{arg1}") /// void EmittedIllegalAccessError(string arg0, string arg1); @@ -178,7 +178,7 @@ partial interface IDiagnosticHandler /// The 'EmittedInstantiationError' diagnostic. /// /// -/// Emitted java.lang.InstantiationError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.InstantiationError in "{arg0}". ("{arg1}") /// void EmittedInstantiationError(string arg0, string arg1); @@ -186,7 +186,7 @@ partial interface IDiagnosticHandler /// The 'EmittedIncompatibleClassChangeError' diagnostic. /// /// -/// Emitted java.lang.IncompatibleClassChangeError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.IncompatibleClassChangeError in "{arg0}". ("{arg1}") /// void EmittedIncompatibleClassChangeError(string arg0, string arg1); @@ -194,7 +194,7 @@ partial interface IDiagnosticHandler /// The 'EmittedNoSuchFieldError' diagnostic. /// /// -/// Emitted java.lang.NoSuchFieldError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.NoSuchFieldError in "{arg0}". ("{arg1}") /// void EmittedNoSuchFieldError(string arg0, string arg1); @@ -202,7 +202,7 @@ partial interface IDiagnosticHandler /// The 'EmittedAbstractMethodError' diagnostic. /// /// -/// Emitted java.lang.AbstractMethodError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.AbstractMethodError in "{arg0}". ("{arg1}") /// void EmittedAbstractMethodError(string arg0, string arg1); @@ -210,7 +210,7 @@ partial interface IDiagnosticHandler /// The 'EmittedNoSuchMethodError' diagnostic. /// /// -/// Emitted java.lang.NoSuchMethodError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.NoSuchMethodError in "{arg0}". ("{arg1}") /// void EmittedNoSuchMethodError(string arg0, string arg1); @@ -218,7 +218,7 @@ partial interface IDiagnosticHandler /// The 'EmittedLinkageError' diagnostic. /// /// -/// Emitted java.lang.LinkageError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.LinkageError in "{arg0}". ("{arg1}") /// void EmittedLinkageError(string arg0, string arg1); @@ -226,7 +226,7 @@ partial interface IDiagnosticHandler /// The 'EmittedVerificationError' diagnostic. /// /// -/// Emitted java.lang.VerificationError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.VerificationError in "{arg0}". ("{arg1}") /// void EmittedVerificationError(string arg0, string arg1); @@ -234,7 +234,7 @@ partial interface IDiagnosticHandler /// The 'EmittedClassFormatError' diagnostic. /// /// -/// Emitted java.lang.ClassFormatError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.ClassFormatError in "{arg0}". ("{arg1}") /// void EmittedClassFormatError(string arg0, string arg1); @@ -242,7 +242,7 @@ partial interface IDiagnosticHandler /// The 'InvalidCustomAttribute' diagnostic. /// /// -/// Error emitting "{arg0}" custom attribute. ("{arg1}") +/// Warning: Error emitting "{arg0}" custom attribute. ("{arg1}") /// void InvalidCustomAttribute(string arg0, string arg1); @@ -250,7 +250,7 @@ partial interface IDiagnosticHandler /// The 'IgnoredCustomAttribute' diagnostic. /// /// -/// Custom attribute "{arg0}" was ignored. ("{arg1}") +/// Warning: Custom attribute "{arg0}" was ignored. ("{arg1}") /// void IgnoredCustomAttribute(string arg0, string arg1); @@ -258,7 +258,7 @@ partial interface IDiagnosticHandler /// The 'AssumeAssemblyVersionMatch' diagnostic. /// /// -/// Assuming assembly reference "{arg0}" matches "{arg1}", you may need to supply runtime policy +/// Warning: Assuming assembly reference "{arg0}" matches "{arg1}", you may need to supply runtime policy /// void AssumeAssemblyVersionMatch(string arg0, string arg1); @@ -266,7 +266,7 @@ partial interface IDiagnosticHandler /// The 'InvalidDirectoryInLibOptionPath' diagnostic. /// /// -/// Directory "{arg0}" specified in -lib option is not valid. +/// Warning: Directory "{arg0}" specified in -lib option is not valid. /// void InvalidDirectoryInLibOptionPath(string arg0); @@ -274,7 +274,7 @@ partial interface IDiagnosticHandler /// The 'InvalidDirectoryInLibEnvironmentPath' diagnostic. /// /// -/// Directory "{arg0}" specified in LIB environment is not valid. +/// Warning: Directory "{arg0}" specified in LIB environment is not valid. /// void InvalidDirectoryInLibEnvironmentPath(string arg0); @@ -282,7 +282,7 @@ partial interface IDiagnosticHandler /// The 'LegacySearchRule' diagnostic. /// /// -/// Found assembly "{arg0}" using legacy search rule, please append '.dll' to the reference. +/// Warning: Found assembly "{arg0}" using legacy search rule, please append '.dll' to the reference. /// void LegacySearchRule(string arg0); @@ -290,7 +290,7 @@ partial interface IDiagnosticHandler /// The 'AssemblyLocationIgnored' diagnostic. /// /// -/// Assembly "{arg0}" is ignored as previously loaded assembly "{arg1}" has the same identity "{arg2}". +/// Warning: Assembly "{arg0}" is ignored as previously loaded assembly "{arg1}" has the same identity "{arg2}". /// void AssemblyLocationIgnored(string arg0, string arg1, string arg2); @@ -298,7 +298,7 @@ partial interface IDiagnosticHandler /// The 'InterfaceMethodCantBeInternal' diagnostic. /// /// -/// Ignoring @ikvm.lang.Internal annotation on interface method. ("{arg0}.{arg1}{arg2}") +/// Warning: Ignoring @ikvm.lang.Internal annotation on interface method. ("{arg0}.{arg1}{arg2}") /// void InterfaceMethodCantBeInternal(string arg0, string arg1, string arg2); @@ -306,7 +306,7 @@ partial interface IDiagnosticHandler /// The 'DuplicateAssemblyReference' diagnostic. /// /// -/// Duplicate assembly reference "{arg0}" +/// Warning: Duplicate assembly reference "{arg0}" /// void DuplicateAssemblyReference(string arg0); @@ -314,7 +314,7 @@ partial interface IDiagnosticHandler /// The 'UnableToResolveType' diagnostic. /// /// -/// Reference in "{arg0}" to type "{arg1}" claims it is defined in "{arg2}", but it could not be found. +/// Warning: Reference in "{arg0}" to type "{arg1}" claims it is defined in "{arg2}", but it could not be found. /// void UnableToResolveType(string arg0, string arg1, string arg2); @@ -322,7 +322,7 @@ partial interface IDiagnosticHandler /// The 'StubsAreDeprecated' diagnostic. /// /// -/// Compiling stubs is deprecated. Please add a reference to assembly "{arg0}" instead. +/// Warning: Compiling stubs is deprecated. Please add a reference to assembly "{arg0}" instead. /// void StubsAreDeprecated(string arg0); @@ -330,7 +330,7 @@ partial interface IDiagnosticHandler /// The 'WrongClassName' diagnostic. /// /// -/// Unable to compile "{arg0}" (wrong name: "{arg1}") +/// Warning: Unable to compile "{arg0}" (wrong name: "{arg1}") /// void WrongClassName(string arg0, string arg1); @@ -338,7 +338,7 @@ partial interface IDiagnosticHandler /// The 'ReflectionCallerClassRequiresCallerID' diagnostic. /// /// -/// Reflection.getCallerClass() called from non-CallerID method. ("{arg0}.{arg1}{arg2}") +/// Warning: Reflection.getCallerClass() called from non-CallerID method. ("{arg0}.{arg1}{arg2}") /// void ReflectionCallerClassRequiresCallerID(string arg0, string arg1, string arg2); @@ -346,7 +346,7 @@ partial interface IDiagnosticHandler /// The 'LegacyAssemblyAttributesFound' diagnostic. /// /// -/// Legacy assembly attributes container found. Please use the -assemblyattributes: option. +/// Warning: Legacy assembly attributes container found. Please use the -assemblyattributes: option. /// void LegacyAssemblyAttributesFound(); @@ -354,7 +354,7 @@ partial interface IDiagnosticHandler /// The 'UnableToCreateLambdaFactory' diagnostic. /// /// -/// Unable to create static lambda factory. +/// Warning: Unable to create static lambda factory. /// void UnableToCreateLambdaFactory(); @@ -362,7 +362,7 @@ partial interface IDiagnosticHandler /// The 'UnknownWarning' diagnostic. /// /// -/// {arg0} +/// Warning: {arg0} /// void UnknownWarning(string arg0); @@ -370,7 +370,7 @@ partial interface IDiagnosticHandler /// The 'DuplicateIkvmLangProperty' diagnostic. /// /// -/// Ignoring duplicate ikvm.lang.Property annotation on {arg0}.{arg1}. +/// Warning: Ignoring duplicate ikvm.lang.Property annotation on {arg0}.{arg1}. /// void DuplicateIkvmLangProperty(string arg0, string arg1); @@ -378,7 +378,7 @@ partial interface IDiagnosticHandler /// The 'MalformedIkvmLangProperty' diagnostic. /// /// -/// Ignoring duplicate ikvm.lang.Property annotation on {arg0}.{arg1}. +/// Warning: Ignoring duplicate ikvm.lang.Property annotation on {arg0}.{arg1}. /// void MalformedIkvmLangProperty(string arg0, string arg1); @@ -386,7 +386,7 @@ partial interface IDiagnosticHandler /// The 'GenericCompilerWarning' diagnostic. /// /// -/// {arg0} +/// Warning: {arg0} /// void GenericCompilerWarning(string arg0); @@ -394,7 +394,7 @@ partial interface IDiagnosticHandler /// The 'GenericClassLoadingWarning' diagnostic. /// /// -/// {arg0} +/// Warning: {arg0} /// void GenericClassLoadingWarning(string arg0); @@ -402,7 +402,7 @@ partial interface IDiagnosticHandler /// The 'GenericVerifierWarning' diagnostic. /// /// -/// {arg0} +/// Warning: {arg0} /// void GenericVerifierWarning(string arg0); @@ -410,7 +410,7 @@ partial interface IDiagnosticHandler /// The 'GenericRuntimeWarning' diagnostic. /// /// -/// {arg0} +/// Warning: {arg0} /// void GenericRuntimeWarning(string arg0); @@ -418,7 +418,7 @@ partial interface IDiagnosticHandler /// The 'GenericJniWarning' diagnostic. /// /// -/// {arg0} +/// Warning: {arg0} /// void GenericJniWarning(string arg0); @@ -426,7 +426,7 @@ partial interface IDiagnosticHandler /// The 'UnableToCreateProxy' diagnostic. /// /// -/// Unable to create proxy "{arg0}". ("{arg1}") +/// Error: Unable to create proxy "{arg0}". ("{arg1}") /// void UnableToCreateProxy(string arg0, string arg1); @@ -434,7 +434,7 @@ partial interface IDiagnosticHandler /// The 'DuplicateProxy' diagnostic. /// /// -/// Duplicate proxy "{arg0}". +/// Error: Duplicate proxy "{arg0}". /// void DuplicateProxy(string arg0); @@ -442,7 +442,7 @@ partial interface IDiagnosticHandler /// The 'MapXmlUnableToResolveOpCode' diagnostic. /// /// -/// Unable to resolve opcode in remap file: {arg0}. +/// Error: Unable to resolve opcode in remap file: {arg0}. /// void MapXmlUnableToResolveOpCode(string arg0); @@ -450,7 +450,7 @@ partial interface IDiagnosticHandler /// The 'MapXmlError' diagnostic. /// /// -/// Error in remap file: {arg0}. +/// Error: Error in remap file: {arg0}. /// void MapXmlError(string arg0); @@ -458,7 +458,7 @@ partial interface IDiagnosticHandler /// The 'InputFileNotFound' diagnostic. /// /// -/// Source file '{arg0}' not found. +/// Error: Source file '{arg0}' not found. /// void InputFileNotFound(string arg0); @@ -466,7 +466,7 @@ partial interface IDiagnosticHandler /// The 'UnknownFileType' diagnostic. /// /// -/// Unknown file type: {arg0}. +/// Error: Unknown file type: {arg0}. /// void UnknownFileType(string arg0); @@ -474,7 +474,7 @@ partial interface IDiagnosticHandler /// The 'UnknownElementInMapFile' diagnostic. /// /// -/// Unknown element {arg0} in remap file, line {arg1}, column {arg2}. +/// Error: Unknown element {arg0} in remap file, line {arg1}, column {arg2}. /// void UnknownElementInMapFile(string arg0, string arg1, string arg2); @@ -482,7 +482,7 @@ partial interface IDiagnosticHandler /// The 'UnknownAttributeInMapFile' diagnostic. /// /// -/// Unknown attribute {arg0} in remap file, line {arg1}, column {arg2}. +/// Error: Unknown attribute {arg0} in remap file, line {arg1}, column {arg2}. /// void UnknownAttributeInMapFile(string arg0, string arg1, string arg2); @@ -490,7 +490,7 @@ partial interface IDiagnosticHandler /// The 'InvalidMemberNameInMapFile' diagnostic. /// /// -/// Invalid {arg0} name '{arg1}' in remap file in class {arg2}. +/// Error: Invalid {arg0} name '{arg1}' in remap file in class {arg2}. /// void InvalidMemberNameInMapFile(string arg0, string arg1, string arg2); @@ -498,7 +498,7 @@ partial interface IDiagnosticHandler /// The 'InvalidMemberSignatureInMapFile' diagnostic. /// /// -/// Invalid {arg0} signature '{arg3}' in remap file for {arg0} {arg1}.{arg2}. +/// Error: Invalid {arg0} signature '{arg3}' in remap file for {arg0} {arg1}.{arg2}. /// void InvalidMemberSignatureInMapFile(string arg0, string arg1, string arg2, string arg3); @@ -506,7 +506,7 @@ partial interface IDiagnosticHandler /// The 'InvalidPropertyNameInMapFile' diagnostic. /// /// -/// Invalid property {arg0} name '{arg3}' in remap file for property {arg1}.{arg2}. +/// Error: Invalid property {arg0} name '{arg3}' in remap file for property {arg1}.{arg2}. /// void InvalidPropertyNameInMapFile(string arg0, string arg1, string arg2, string arg3); @@ -514,7 +514,7 @@ partial interface IDiagnosticHandler /// The 'InvalidPropertySignatureInMapFile' diagnostic. /// /// -/// Invalid property {arg0} signature '{arg3}' in remap file for property {arg1}.{arg2}. +/// Error: Invalid property {arg0} signature '{arg3}' in remap file for property {arg1}.{arg2}. /// void InvalidPropertySignatureInMapFile(string arg0, string arg1, string arg2, string arg3); @@ -522,7 +522,7 @@ partial interface IDiagnosticHandler /// The 'NonPrimaryAssemblyReference' diagnostic. /// /// -/// Referenced assembly "{arg0}" is not the primary assembly of a shared class loader group, please reference primary assembly "{arg1}" instead. +/// Error: Referenced assembly "{arg0}" is not the primary assembly of a shared class loader group, please reference primary assembly "{arg1}" instead. /// void NonPrimaryAssemblyReference(string arg0, string arg1); @@ -530,7 +530,7 @@ partial interface IDiagnosticHandler /// The 'MissingType' diagnostic. /// /// -/// Reference to type "{arg0}" claims it is defined in "{arg1}", but it could not be found. +/// Error: Reference to type "{arg0}" claims it is defined in "{arg1}", but it could not be found. /// void MissingType(string arg0, string arg1); @@ -538,7 +538,7 @@ partial interface IDiagnosticHandler /// The 'MissingReference' diagnostic. /// /// -/// The type '{arg0}' is defined in an assembly that is notResponseFileDepthExceeded referenced. You must add a reference to assembly '{arg1}'. +/// Error: The type '{arg0}' is defined in an assembly that is notResponseFileDepthExceeded referenced. You must add a reference to assembly '{arg1}'. /// void MissingReference(string arg0, string arg1); @@ -546,7 +546,7 @@ partial interface IDiagnosticHandler /// The 'CallerSensitiveOnUnsupportedMethod' diagnostic. /// /// -/// CallerSensitive annotation on unsupported method. ("{arg0}.{arg1}{arg2}") +/// Error: CallerSensitive annotation on unsupported method. ("{arg0}.{arg1}{arg2}") /// void CallerSensitiveOnUnsupportedMethod(string arg0, string arg1, string arg2); @@ -554,7 +554,7 @@ partial interface IDiagnosticHandler /// The 'RemappedTypeMissingDefaultInterfaceMethod' diagnostic. /// /// -/// {arg0} does not implement default interface method {arg1}. +/// Error: {arg0} does not implement default interface method {arg1}. /// void RemappedTypeMissingDefaultInterfaceMethod(string arg0, string arg1); @@ -562,7 +562,7 @@ partial interface IDiagnosticHandler /// The 'GenericCompilerError' diagnostic. /// /// -/// {arg0} +/// Error: {arg0} /// void GenericCompilerError(string arg0); @@ -570,7 +570,7 @@ partial interface IDiagnosticHandler /// The 'GenericClassLoadingError' diagnostic. /// /// -/// {arg0} +/// Error: {arg0} /// void GenericClassLoadingError(string arg0); @@ -578,7 +578,7 @@ partial interface IDiagnosticHandler /// The 'GenericVerifierError' diagnostic. /// /// -/// {arg0} +/// Error: {arg0} /// void GenericVerifierError(string arg0); @@ -586,7 +586,7 @@ partial interface IDiagnosticHandler /// The 'GenericRuntimeError' diagnostic. /// /// -/// {arg0} +/// Error: {arg0} /// void GenericRuntimeError(string arg0); @@ -594,7 +594,7 @@ partial interface IDiagnosticHandler /// The 'GenericJniError' diagnostic. /// /// -/// {arg0} +/// Error: {arg0} /// void GenericJniError(string arg0); @@ -602,7 +602,7 @@ partial interface IDiagnosticHandler /// The 'ExportingImportsNotSupported' diagnostic. /// /// -/// Exporting previously imported assemblies is not supported. +/// Error: Exporting previously imported assemblies is not supported. /// void ExportingImportsNotSupported(); @@ -610,7 +610,7 @@ partial interface IDiagnosticHandler /// The 'ResponseFileDepthExceeded' diagnostic. /// /// -/// Response file nesting depth exceeded. +/// Fatal: Response file nesting depth exceeded. /// void ResponseFileDepthExceeded(); @@ -618,7 +618,7 @@ partial interface IDiagnosticHandler /// The 'ErrorReadingFile' diagnostic. /// /// -/// Unable to read file: {arg0}. ({arg1}) +/// Fatal: Unable to read file: {arg0}. ({arg1}) /// void ErrorReadingFile(string arg0, string arg1); @@ -626,7 +626,7 @@ partial interface IDiagnosticHandler /// The 'NoTargetsFound' diagnostic. /// /// -/// No targets found +/// Fatal: No targets found /// void NoTargetsFound(); @@ -634,7 +634,7 @@ partial interface IDiagnosticHandler /// The 'FileFormatLimitationExceeded' diagnostic. /// /// -/// File format limitation exceeded: {arg0}. +/// Fatal: File format limitation exceeded: {arg0}. /// void FileFormatLimitationExceeded(string arg0); @@ -642,7 +642,7 @@ partial interface IDiagnosticHandler /// The 'CannotSpecifyBothKeyFileAndContainer' diagnostic. /// /// -/// You cannot specify both a key file and container. +/// Fatal: You cannot specify both a key file and container. /// void CannotSpecifyBothKeyFileAndContainer(); @@ -650,7 +650,7 @@ partial interface IDiagnosticHandler /// The 'DelaySignRequiresKey' diagnostic. /// /// -/// You cannot delay sign without a key file or container. +/// Fatal: You cannot delay sign without a key file or container. /// void DelaySignRequiresKey(); @@ -658,7 +658,7 @@ partial interface IDiagnosticHandler /// The 'InvalidStrongNameKeyPair' diagnostic. /// /// -/// Invalid key {arg0} specified. ("{arg1}") +/// Fatal: Invalid key {arg0} specified. ("{arg1}") /// void InvalidStrongNameKeyPair(string arg0, string arg1); @@ -666,7 +666,7 @@ partial interface IDiagnosticHandler /// The 'ReferenceNotFound' diagnostic. /// /// -/// Reference not found: {arg0} +/// Fatal: Reference not found: {arg0} /// void ReferenceNotFound(string arg0); @@ -674,7 +674,7 @@ partial interface IDiagnosticHandler /// The 'OptionsMustPreceedChildLevels' diagnostic. /// /// -/// You can only specify options before any child levels. +/// Fatal: You can only specify options before any child levels. /// void OptionsMustPreceedChildLevels(); @@ -682,7 +682,7 @@ partial interface IDiagnosticHandler /// The 'UnrecognizedTargetType' diagnostic. /// /// -/// Invalid value '{arg0}' for -target option. +/// Fatal: Invalid value '{arg0}' for -target option. /// void UnrecognizedTargetType(string arg0); @@ -690,7 +690,7 @@ partial interface IDiagnosticHandler /// The 'UnrecognizedPlatform' diagnostic. /// /// -/// Invalid value '{arg0}' for -platform option. +/// Fatal: Invalid value '{arg0}' for -platform option. /// void UnrecognizedPlatform(string arg0); @@ -698,7 +698,7 @@ partial interface IDiagnosticHandler /// The 'UnrecognizedApartment' diagnostic. /// /// -/// Invalid value '{arg0}' for -apartment option. +/// Fatal: Invalid value '{arg0}' for -apartment option. /// void UnrecognizedApartment(string arg0); @@ -706,7 +706,7 @@ partial interface IDiagnosticHandler /// The 'MissingFileSpecification' diagnostic. /// /// -/// Missing file specification for '{arg0}' option. +/// Fatal: Missing file specification for '{arg0}' option. /// void MissingFileSpecification(string arg0); @@ -714,7 +714,7 @@ partial interface IDiagnosticHandler /// The 'PathTooLong' diagnostic. /// /// -/// Path too long: {arg0}. +/// Fatal: Path too long: {arg0}. /// void PathTooLong(string arg0); @@ -722,7 +722,7 @@ partial interface IDiagnosticHandler /// The 'PathNotFound' diagnostic. /// /// -/// Path not found: {arg0}. +/// Fatal: Path not found: {arg0}. /// void PathNotFound(string arg0); @@ -730,7 +730,7 @@ partial interface IDiagnosticHandler /// The 'InvalidPath' diagnostic. /// /// -/// Invalid path: {arg0}. +/// Fatal: Invalid path: {arg0}. /// void InvalidPath(string arg0); @@ -738,7 +738,7 @@ partial interface IDiagnosticHandler /// The 'InvalidOptionSyntax' diagnostic. /// /// -/// Invalid option: {arg0}. +/// Fatal: Invalid option: {arg0}. /// void InvalidOptionSyntax(string arg0); @@ -746,7 +746,7 @@ partial interface IDiagnosticHandler /// The 'ExternalResourceNotFound' diagnostic. /// /// -/// External resource file does not exist: {arg0}. +/// Fatal: External resource file does not exist: {arg0}. /// void ExternalResourceNotFound(string arg0); @@ -754,7 +754,7 @@ partial interface IDiagnosticHandler /// The 'ExternalResourceNameInvalid' diagnostic. /// /// -/// External resource file may not include path specification: {arg0}. +/// Fatal: External resource file may not include path specification: {arg0}. /// void ExternalResourceNameInvalid(string arg0); @@ -762,7 +762,7 @@ partial interface IDiagnosticHandler /// The 'InvalidVersionFormat' diagnostic. /// /// -/// Invalid version specified: {arg0}. +/// Fatal: Invalid version specified: {arg0}. /// void InvalidVersionFormat(string arg0); @@ -770,7 +770,7 @@ partial interface IDiagnosticHandler /// The 'InvalidFileAlignment' diagnostic. /// /// -/// Invalid value '{arg0}' for -filealign option. +/// Fatal: Invalid value '{arg0}' for -filealign option. /// void InvalidFileAlignment(string arg0); @@ -778,7 +778,7 @@ partial interface IDiagnosticHandler /// The 'ErrorWritingFile' diagnostic. /// /// -/// Unable to write file: {arg0}. ({arg1}) +/// Fatal: Unable to write file: {arg0}. ({arg1}) /// void ErrorWritingFile(string arg0, string arg1); @@ -786,7 +786,7 @@ partial interface IDiagnosticHandler /// The 'UnrecognizedOption' diagnostic. /// /// -/// Unrecognized option: {arg0}. +/// Fatal: Unrecognized option: {arg0}. /// void UnrecognizedOption(string arg0); @@ -794,7 +794,7 @@ partial interface IDiagnosticHandler /// The 'NoOutputFileSpecified' diagnostic. /// /// -/// No output file specified. +/// Fatal: No output file specified. /// void NoOutputFileSpecified(); @@ -802,7 +802,7 @@ partial interface IDiagnosticHandler /// The 'SharedClassLoaderCannotBeUsedOnModuleTarget' diagnostic. /// /// -/// Incompatible options: -target:module and -sharedclassloader cannot be combined. +/// Fatal: Incompatible options: -target:module and -sharedclassloader cannot be combined. /// void SharedClassLoaderCannotBeUsedOnModuleTarget(); @@ -810,7 +810,7 @@ partial interface IDiagnosticHandler /// The 'RuntimeNotFound' diagnostic. /// /// -/// Unable to load runtime assembly. +/// Fatal: Unable to load runtime assembly. /// void RuntimeNotFound(); @@ -818,7 +818,7 @@ partial interface IDiagnosticHandler /// The 'MainClassRequiresExe' diagnostic. /// /// -/// Main class cannot be specified for library or module. +/// Fatal: Main class cannot be specified for library or module. /// void MainClassRequiresExe(); @@ -826,7 +826,7 @@ partial interface IDiagnosticHandler /// The 'ExeRequiresMainClass' diagnostic. /// /// -/// No main method found. +/// Fatal: No main method found. /// void ExeRequiresMainClass(); @@ -834,7 +834,7 @@ partial interface IDiagnosticHandler /// The 'PropertiesRequireExe' diagnostic. /// /// -/// Properties cannot be specified for library or module. +/// Fatal: Properties cannot be specified for library or module. /// void PropertiesRequireExe(); @@ -842,7 +842,7 @@ partial interface IDiagnosticHandler /// The 'ModuleCannotHaveClassLoader' diagnostic. /// /// -/// Cannot specify assembly class loader for modules. +/// Fatal: Cannot specify assembly class loader for modules. /// void ModuleCannotHaveClassLoader(); @@ -850,7 +850,7 @@ partial interface IDiagnosticHandler /// The 'ErrorParsingMapFile' diagnostic. /// /// -/// Unable to parse remap file: {arg0}. ({arg1}) +/// Fatal: Unable to parse remap file: {arg0}. ({arg1}) /// void ErrorParsingMapFile(string arg0, string arg1); @@ -858,7 +858,7 @@ partial interface IDiagnosticHandler /// The 'BootstrapClassesMissing' diagnostic. /// /// -/// Bootstrap classes missing and core assembly not found. +/// Fatal: Bootstrap classes missing and core assembly not found. /// void BootstrapClassesMissing(); @@ -866,7 +866,7 @@ partial interface IDiagnosticHandler /// The 'StrongNameRequiresStrongNamedRefs' diagnostic. /// /// -/// All referenced assemblies must be strong named, to be able to sign the output assembly. +/// Fatal: All referenced assemblies must be strong named, to be able to sign the output assembly. /// void StrongNameRequiresStrongNamedRefs(); @@ -874,7 +874,7 @@ partial interface IDiagnosticHandler /// The 'MainClassNotFound' diagnostic. /// /// -/// Main class not found. +/// Fatal: Main class not found. /// void MainClassNotFound(); @@ -882,7 +882,7 @@ partial interface IDiagnosticHandler /// The 'MainMethodNotFound' diagnostic. /// /// -/// Main method not found. +/// Fatal: Main method not found. /// void MainMethodNotFound(); @@ -890,7 +890,7 @@ partial interface IDiagnosticHandler /// The 'UnsupportedMainMethod' diagnostic. /// /// -/// Redirected main method not supported. +/// Fatal: Redirected main method not supported. /// void UnsupportedMainMethod(); @@ -898,7 +898,7 @@ partial interface IDiagnosticHandler /// The 'ExternalMainNotAccessible' diagnostic. /// /// -/// External main method must be public and in a public class. +/// Fatal: External main method must be public and in a public class. /// void ExternalMainNotAccessible(); @@ -906,7 +906,7 @@ partial interface IDiagnosticHandler /// The 'ClassLoaderNotFound' diagnostic. /// /// -/// Custom assembly class loader class not found. +/// Fatal: Custom assembly class loader class not found. /// void ClassLoaderNotFound(); @@ -914,7 +914,7 @@ partial interface IDiagnosticHandler /// The 'ClassLoaderNotAccessible' diagnostic. /// /// -/// Custom assembly class loader class is not accessible. +/// Fatal: Custom assembly class loader class is not accessible. /// void ClassLoaderNotAccessible(); @@ -922,7 +922,7 @@ partial interface IDiagnosticHandler /// The 'ClassLoaderIsAbstract' diagnostic. /// /// -/// Custom assembly class loader class is abstract. +/// Fatal: Custom assembly class loader class is abstract. /// void ClassLoaderIsAbstract(); @@ -930,7 +930,7 @@ partial interface IDiagnosticHandler /// The 'ClassLoaderNotClassLoader' diagnostic. /// /// -/// Custom assembly class loader class does not extend java.lang.ClassLoader. +/// Fatal: Custom assembly class loader class does not extend java.lang.ClassLoader. /// void ClassLoaderNotClassLoader(); @@ -938,7 +938,7 @@ partial interface IDiagnosticHandler /// The 'ClassLoaderConstructorMissing' diagnostic. /// /// -/// Custom assembly class loader constructor is missing. +/// Fatal: Custom assembly class loader constructor is missing. /// void ClassLoaderConstructorMissing(); @@ -946,7 +946,7 @@ partial interface IDiagnosticHandler /// The 'MapFileTypeNotFound' diagnostic. /// /// -/// Type '{arg0}' referenced in remap file was not found. +/// Fatal: Type '{arg0}' referenced in remap file was not found. /// void MapFileTypeNotFound(string arg0); @@ -954,7 +954,7 @@ partial interface IDiagnosticHandler /// The 'MapFileClassNotFound' diagnostic. /// /// -/// Class '{arg0}' referenced in remap file was not found. +/// Fatal: Class '{arg0}' referenced in remap file was not found. /// void MapFileClassNotFound(string arg0); @@ -962,7 +962,7 @@ partial interface IDiagnosticHandler /// The 'MaximumErrorCountReached' diagnostic. /// /// -/// Maximum error count reached. +/// Fatal: Maximum error count reached. /// void MaximumErrorCountReached(); @@ -970,7 +970,7 @@ partial interface IDiagnosticHandler /// The 'LinkageError' diagnostic. /// /// -/// Link error: {arg0} +/// Fatal: Link error: {arg0} /// void LinkageError(string arg0); @@ -978,7 +978,7 @@ partial interface IDiagnosticHandler /// The 'RuntimeMismatch' diagnostic. /// /// -/// Referenced assembly {referencedAssemblyPath} was compiled with an incompatible IKVM.Runtime version. Current runtime: {runtimeAssemblyName}. Referenced assembly runtime: {referencedAssemblyName} +/// Fatal: Referenced assembly {referencedAssemblyPath} was compiled with an incompatible IKVM.Runtime version. Current runtime: {runtimeAssemblyName}. Referenced assembly runtime: {referencedAssemblyName} /// void RuntimeMismatch(string referencedAssemblyPath, string runtimeAssemblyName, string referencedAssemblyName); @@ -986,7 +986,7 @@ partial interface IDiagnosticHandler /// The 'RuntimeMismatchStrongName' diagnostic. /// /// -/// +/// Fatal: /// void RuntimeMismatchStrongName(); @@ -994,7 +994,7 @@ partial interface IDiagnosticHandler /// The 'CoreClassesMissing' diagnostic. /// /// -/// Failed to find core classes in core library. +/// Fatal: Failed to find core classes in core library. /// void CoreClassesMissing(); @@ -1002,7 +1002,7 @@ partial interface IDiagnosticHandler /// The 'CriticalClassNotFound' diagnostic. /// /// -/// Unable to load critical class '{arg0}'. +/// Fatal: Unable to load critical class '{arg0}'. /// void CriticalClassNotFound(string arg0); @@ -1010,7 +1010,7 @@ partial interface IDiagnosticHandler /// The 'AssemblyContainsDuplicateClassNames' diagnostic. /// /// -/// Type '{arg0}' and '{arg1}' both map to the same name '{arg2}'. ({arg3}) +/// Fatal: Type '{arg0}' and '{arg1}' both map to the same name '{arg2}'. ({arg3}) /// void AssemblyContainsDuplicateClassNames(string arg0, string arg1, string arg2, string arg3); @@ -1018,7 +1018,7 @@ partial interface IDiagnosticHandler /// The 'CallerIDRequiresHasCallerIDAnnotation' diagnostic. /// /// -/// CallerID.getCallerID() requires a HasCallerID annotation. +/// Fatal: CallerID.getCallerID() requires a HasCallerID annotation. /// void CallerIDRequiresHasCallerIDAnnotation(); @@ -1026,7 +1026,7 @@ partial interface IDiagnosticHandler /// The 'UnableToResolveInterface' diagnostic. /// /// -/// Unable to resolve interface '{arg0}' on type '{arg1}'. +/// Fatal: Unable to resolve interface '{arg0}' on type '{arg1}'. /// void UnableToResolveInterface(string arg0, string arg1); @@ -1034,7 +1034,7 @@ partial interface IDiagnosticHandler /// The 'MissingBaseType' diagnostic. /// /// -/// The base class or interface '{arg0}' in assembly '{arg1}' referenced by type '{arg2}' in '{arg3}' could not be resolved. +/// Fatal: The base class or interface '{arg0}' in assembly '{arg1}' referenced by type '{arg2}' in '{arg3}' could not be resolved. /// void MissingBaseType(string arg0, string arg1, string arg2, string arg3); @@ -1042,7 +1042,7 @@ partial interface IDiagnosticHandler /// The 'MissingBaseTypeReference' diagnostic. /// /// -/// The type '{arg0}' is defined in an assembly that is not referenced. You must add a reference to assembly '{arg1}'. +/// Fatal: The type '{arg0}' is defined in an assembly that is not referenced. You must add a reference to assembly '{arg1}'. /// void MissingBaseTypeReference(string arg0, string arg1); @@ -1050,7 +1050,7 @@ partial interface IDiagnosticHandler /// The 'FileNotFound' diagnostic. /// /// -/// File not found: {arg0}. +/// Fatal: File not found: {arg0}. /// void FileNotFound(string arg0); @@ -1058,7 +1058,7 @@ partial interface IDiagnosticHandler /// The 'RuntimeMethodMissing' diagnostic. /// /// -/// Runtime method '{arg0}' not found. +/// Fatal: Runtime method '{arg0}' not found. /// void RuntimeMethodMissing(string arg0); @@ -1066,7 +1066,7 @@ partial interface IDiagnosticHandler /// The 'MapFileFieldNotFound' diagnostic. /// /// -/// Field '{arg0}' referenced in remap file was not found in class '{arg1}'. +/// Fatal: Field '{arg0}' referenced in remap file was not found in class '{arg1}'. /// void MapFileFieldNotFound(string arg0, string arg1); @@ -1074,7 +1074,7 @@ partial interface IDiagnosticHandler /// The 'GhostInterfaceMethodMissing' diagnostic. /// /// -/// Remapped class '{arg0}' does not implement ghost interface method. ({arg1}.{arg2}{arg3}) +/// Fatal: Remapped class '{arg0}' does not implement ghost interface method. ({arg1}.{arg2}{arg3}) /// void GhostInterfaceMethodMissing(string arg0, string arg1, string arg2, string arg3); @@ -1082,7 +1082,7 @@ partial interface IDiagnosticHandler /// The 'ModuleInitializerMethodRequirements' diagnostic. /// /// -/// Method '{arg1}.{arg2}{arg3}' does not meet the requirements of a module initializer. +/// Fatal: Method '{arg1}.{arg2}{arg3}' does not meet the requirements of a module initializer. /// void ModuleInitializerMethodRequirements(string arg1, string arg2, string arg3); @@ -1090,7 +1090,7 @@ partial interface IDiagnosticHandler /// The 'InvalidZip' diagnostic. /// /// -/// Invalid zip: {name}. +/// Fatal: Invalid zip: {name}. /// void InvalidZip(string name); @@ -1098,7 +1098,7 @@ partial interface IDiagnosticHandler /// The 'CoreAssemblyVersionMismatch' diagnostic. /// /// -/// Unable to load assembly '{0}' as it depends on a higher version of {1} than the one currently loaded. +/// Fatal: Unable to load assembly '{0}' as it depends on a higher version of {1} than the one currently loaded. /// void CoreAssemblyVersionMismatch(string arg0, string arg1); @@ -1106,7 +1106,7 @@ partial interface IDiagnosticHandler /// The 'GenericRuntimeTrace' diagnostic. /// /// -/// {arg0} +/// Trace: {arg0} /// void GenericRuntimeTrace(string arg0); @@ -1114,7 +1114,7 @@ partial interface IDiagnosticHandler /// The 'GenericJniTrace' diagnostic. /// /// -/// {arg0} +/// Trace: {arg0} /// void GenericJniTrace(string arg0); @@ -1122,7 +1122,7 @@ partial interface IDiagnosticHandler /// The 'GenericCompilerTrace' diagnostic. /// /// -/// {arg0} +/// Trace: {arg0} /// void GenericCompilerTrace(string arg0); diff --git a/src/IKVM.CoreLib/Diagnostics/IDiagnosticHandler.g.tt b/src/IKVM.CoreLib/Diagnostics/IDiagnosticHandler.g.tt index 947391123..4708f9233 100644 --- a/src/IKVM.CoreLib/Diagnostics/IDiagnosticHandler.g.tt +++ b/src/IKVM.CoreLib/Diagnostics/IDiagnosticHandler.g.tt @@ -41,7 +41,7 @@ foreach (var kvp in DiagnosticFile.Read(Host.ResolvePath(Path.Combine("Diagnosti /// <#= desc #> /// /// -<#= Util.ToCommentString(kvp.Value.Message ?? "") #> +<#= Util.ToCommentString(kvp.Value) #> /// void <#= kvp.Key #>(<#= string.Join(", ", argList) #>); diff --git a/src/IKVM.CoreLib/Diagnostics/NullDiagnosticHandler.g.cs b/src/IKVM.CoreLib/Diagnostics/NullDiagnosticHandler.g.cs index 1283a9557..77f88e4db 100644 --- a/src/IKVM.CoreLib/Diagnostics/NullDiagnosticHandler.g.cs +++ b/src/IKVM.CoreLib/Diagnostics/NullDiagnosticHandler.g.cs @@ -10,7 +10,7 @@ partial class NullDiagnosticHandler /// The 'MainMethodFound' diagnostic. /// /// -/// Found main method in class "{arg0}". +/// Info: Found main method in class "{arg0}". /// public void MainMethodFound(string arg0) { @@ -21,7 +21,7 @@ public void MainMethodFound(string arg0) /// The 'OutputFileIs' diagnostic. /// /// -/// Output file is "{arg0}". +/// Info: Output file is "{arg0}". /// public void OutputFileIs(string arg0) { @@ -32,7 +32,7 @@ public void OutputFileIs(string arg0) /// The 'AutoAddRef' diagnostic. /// /// -/// Automatically adding reference to "{arg0}". +/// Info: Automatically adding reference to "{arg0}". /// public void AutoAddRef(string arg0) { @@ -43,7 +43,7 @@ public void AutoAddRef(string arg0) /// The 'MainMethodFromManifest' diagnostic. /// /// -/// Using main class "{arg0}" based on jar manifest. +/// Info: Using main class "{arg0}" based on jar manifest. /// public void MainMethodFromManifest(string arg0) { @@ -54,7 +54,7 @@ public void MainMethodFromManifest(string arg0) /// The 'GenericCompilerInfo' diagnostic. /// /// -/// {arg0} +/// Info: {arg0} /// public void GenericCompilerInfo(string arg0) { @@ -65,7 +65,7 @@ public void GenericCompilerInfo(string arg0) /// The 'GenericClassLoadingInfo' diagnostic. /// /// -/// {arg0} +/// Info: {arg0} /// public void GenericClassLoadingInfo(string arg0) { @@ -76,7 +76,7 @@ public void GenericClassLoadingInfo(string arg0) /// The 'GenericVerifierInfo' diagnostic. /// /// -/// {arg0} +/// Info: {arg0} /// public void GenericVerifierInfo(string arg0) { @@ -87,7 +87,7 @@ public void GenericVerifierInfo(string arg0) /// The 'GenericRuntimeInfo' diagnostic. /// /// -/// {arg0} +/// Info: {arg0} /// public void GenericRuntimeInfo(string arg0) { @@ -98,7 +98,7 @@ public void GenericRuntimeInfo(string arg0) /// The 'GenericJniInfo' diagnostic. /// /// -/// {arg0} +/// Info: {arg0} /// public void GenericJniInfo(string arg0) { @@ -109,7 +109,7 @@ public void GenericJniInfo(string arg0) /// The 'ClassNotFound' diagnostic. /// /// -/// Class "{arg0}" not found. +/// Warning: Class "{arg0}" not found. /// public void ClassNotFound(string arg0) { @@ -120,7 +120,7 @@ public void ClassNotFound(string arg0) /// The 'ClassFormatError' diagnostic. /// /// -/// Unable to compile class "{arg0}". (class format error "{arg1}") +/// Warning: Unable to compile class "{arg0}". (class format error "{arg1}") /// public void ClassFormatError(string arg0, string arg1) { @@ -131,7 +131,7 @@ public void ClassFormatError(string arg0, string arg1) /// The 'DuplicateClassName' diagnostic. /// /// -/// Duplicate class name: "{arg0}". +/// Warning: Duplicate class name: "{arg0}". /// public void DuplicateClassName(string arg0) { @@ -142,7 +142,7 @@ public void DuplicateClassName(string arg0) /// The 'IllegalAccessError' diagnostic. /// /// -/// Unable to compile class "{arg0}". (illegal access error "{arg1}") +/// Warning: Unable to compile class "{arg0}". (illegal access error "{arg1}") /// public void IllegalAccessError(string arg0, string arg1) { @@ -153,7 +153,7 @@ public void IllegalAccessError(string arg0, string arg1) /// The 'VerificationError' diagnostic. /// /// -/// Unable to compile class "{arg0}". (verification error "{arg1}") +/// Warning: Unable to compile class "{arg0}". (verification error "{arg1}") /// public void VerificationError(string arg0, string arg1) { @@ -164,7 +164,7 @@ public void VerificationError(string arg0, string arg1) /// The 'NoClassDefFoundError' diagnostic. /// /// -/// Unable to compile class "{arg0}". (missing class "{arg1}") +/// Warning: Unable to compile class "{arg0}". (missing class "{arg1}") /// public void NoClassDefFoundError(string arg0, string arg1) { @@ -175,7 +175,7 @@ public void NoClassDefFoundError(string arg0, string arg1) /// The 'GenericUnableToCompileError' diagnostic. /// /// -/// Unable to compile class "{arg0}". ("{arg1}": "{arg2}") +/// Warning: Unable to compile class "{arg0}". ("{arg1}": "{arg2}") /// public void GenericUnableToCompileError(string arg0, string arg1, string arg2) { @@ -186,7 +186,7 @@ public void GenericUnableToCompileError(string arg0, string arg1, string arg2) /// The 'DuplicateResourceName' diagnostic. /// /// -/// Skipping resource (name clash): "{arg0}" +/// Warning: Skipping resource (name clash): "{arg0}" /// public void DuplicateResourceName(string arg0) { @@ -197,7 +197,7 @@ public void DuplicateResourceName(string arg0) /// The 'SkippingReferencedClass' diagnostic. /// /// -/// Skipping class: "{arg0}". (class is already available in referenced assembly "{arg1}") +/// Warning: Skipping class: "{arg0}". (class is already available in referenced assembly "{arg1}") /// public void SkippingReferencedClass(string arg0, string arg1) { @@ -208,7 +208,7 @@ public void SkippingReferencedClass(string arg0, string arg1) /// The 'NoJniRuntime' diagnostic. /// /// -/// Unable to load runtime JNI assembly. +/// Warning: Unable to load runtime JNI assembly. /// public void NoJniRuntime() { @@ -219,7 +219,7 @@ public void NoJniRuntime() /// The 'EmittedNoClassDefFoundError' diagnostic. /// /// -/// Emitted java.lang.NoClassDefFoundError in "{arg0}". ("{arg1}"). +/// Warning: Emitted java.lang.NoClassDefFoundError in "{arg0}". ("{arg1}"). /// public void EmittedNoClassDefFoundError(string arg0, string arg1) { @@ -230,7 +230,7 @@ public void EmittedNoClassDefFoundError(string arg0, string arg1) /// The 'EmittedIllegalAccessError' diagnostic. /// /// -/// Emitted java.lang.IllegalAccessError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.IllegalAccessError in "{arg0}". ("{arg1}") /// public void EmittedIllegalAccessError(string arg0, string arg1) { @@ -241,7 +241,7 @@ public void EmittedIllegalAccessError(string arg0, string arg1) /// The 'EmittedInstantiationError' diagnostic. /// /// -/// Emitted java.lang.InstantiationError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.InstantiationError in "{arg0}". ("{arg1}") /// public void EmittedInstantiationError(string arg0, string arg1) { @@ -252,7 +252,7 @@ public void EmittedInstantiationError(string arg0, string arg1) /// The 'EmittedIncompatibleClassChangeError' diagnostic. /// /// -/// Emitted java.lang.IncompatibleClassChangeError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.IncompatibleClassChangeError in "{arg0}". ("{arg1}") /// public void EmittedIncompatibleClassChangeError(string arg0, string arg1) { @@ -263,7 +263,7 @@ public void EmittedIncompatibleClassChangeError(string arg0, string arg1) /// The 'EmittedNoSuchFieldError' diagnostic. /// /// -/// Emitted java.lang.NoSuchFieldError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.NoSuchFieldError in "{arg0}". ("{arg1}") /// public void EmittedNoSuchFieldError(string arg0, string arg1) { @@ -274,7 +274,7 @@ public void EmittedNoSuchFieldError(string arg0, string arg1) /// The 'EmittedAbstractMethodError' diagnostic. /// /// -/// Emitted java.lang.AbstractMethodError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.AbstractMethodError in "{arg0}". ("{arg1}") /// public void EmittedAbstractMethodError(string arg0, string arg1) { @@ -285,7 +285,7 @@ public void EmittedAbstractMethodError(string arg0, string arg1) /// The 'EmittedNoSuchMethodError' diagnostic. /// /// -/// Emitted java.lang.NoSuchMethodError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.NoSuchMethodError in "{arg0}". ("{arg1}") /// public void EmittedNoSuchMethodError(string arg0, string arg1) { @@ -296,7 +296,7 @@ public void EmittedNoSuchMethodError(string arg0, string arg1) /// The 'EmittedLinkageError' diagnostic. /// /// -/// Emitted java.lang.LinkageError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.LinkageError in "{arg0}". ("{arg1}") /// public void EmittedLinkageError(string arg0, string arg1) { @@ -307,7 +307,7 @@ public void EmittedLinkageError(string arg0, string arg1) /// The 'EmittedVerificationError' diagnostic. /// /// -/// Emitted java.lang.VerificationError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.VerificationError in "{arg0}". ("{arg1}") /// public void EmittedVerificationError(string arg0, string arg1) { @@ -318,7 +318,7 @@ public void EmittedVerificationError(string arg0, string arg1) /// The 'EmittedClassFormatError' diagnostic. /// /// -/// Emitted java.lang.ClassFormatError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.ClassFormatError in "{arg0}". ("{arg1}") /// public void EmittedClassFormatError(string arg0, string arg1) { @@ -329,7 +329,7 @@ public void EmittedClassFormatError(string arg0, string arg1) /// The 'InvalidCustomAttribute' diagnostic. /// /// -/// Error emitting "{arg0}" custom attribute. ("{arg1}") +/// Warning: Error emitting "{arg0}" custom attribute. ("{arg1}") /// public void InvalidCustomAttribute(string arg0, string arg1) { @@ -340,7 +340,7 @@ public void InvalidCustomAttribute(string arg0, string arg1) /// The 'IgnoredCustomAttribute' diagnostic. /// /// -/// Custom attribute "{arg0}" was ignored. ("{arg1}") +/// Warning: Custom attribute "{arg0}" was ignored. ("{arg1}") /// public void IgnoredCustomAttribute(string arg0, string arg1) { @@ -351,7 +351,7 @@ public void IgnoredCustomAttribute(string arg0, string arg1) /// The 'AssumeAssemblyVersionMatch' diagnostic. /// /// -/// Assuming assembly reference "{arg0}" matches "{arg1}", you may need to supply runtime policy +/// Warning: Assuming assembly reference "{arg0}" matches "{arg1}", you may need to supply runtime policy /// public void AssumeAssemblyVersionMatch(string arg0, string arg1) { @@ -362,7 +362,7 @@ public void AssumeAssemblyVersionMatch(string arg0, string arg1) /// The 'InvalidDirectoryInLibOptionPath' diagnostic. /// /// -/// Directory "{arg0}" specified in -lib option is not valid. +/// Warning: Directory "{arg0}" specified in -lib option is not valid. /// public void InvalidDirectoryInLibOptionPath(string arg0) { @@ -373,7 +373,7 @@ public void InvalidDirectoryInLibOptionPath(string arg0) /// The 'InvalidDirectoryInLibEnvironmentPath' diagnostic. /// /// -/// Directory "{arg0}" specified in LIB environment is not valid. +/// Warning: Directory "{arg0}" specified in LIB environment is not valid. /// public void InvalidDirectoryInLibEnvironmentPath(string arg0) { @@ -384,7 +384,7 @@ public void InvalidDirectoryInLibEnvironmentPath(string arg0) /// The 'LegacySearchRule' diagnostic. /// /// -/// Found assembly "{arg0}" using legacy search rule, please append '.dll' to the reference. +/// Warning: Found assembly "{arg0}" using legacy search rule, please append '.dll' to the reference. /// public void LegacySearchRule(string arg0) { @@ -395,7 +395,7 @@ public void LegacySearchRule(string arg0) /// The 'AssemblyLocationIgnored' diagnostic. /// /// -/// Assembly "{arg0}" is ignored as previously loaded assembly "{arg1}" has the same identity "{arg2}". +/// Warning: Assembly "{arg0}" is ignored as previously loaded assembly "{arg1}" has the same identity "{arg2}". /// public void AssemblyLocationIgnored(string arg0, string arg1, string arg2) { @@ -406,7 +406,7 @@ public void AssemblyLocationIgnored(string arg0, string arg1, string arg2) /// The 'InterfaceMethodCantBeInternal' diagnostic. /// /// -/// Ignoring @ikvm.lang.Internal annotation on interface method. ("{arg0}.{arg1}{arg2}") +/// Warning: Ignoring @ikvm.lang.Internal annotation on interface method. ("{arg0}.{arg1}{arg2}") /// public void InterfaceMethodCantBeInternal(string arg0, string arg1, string arg2) { @@ -417,7 +417,7 @@ public void InterfaceMethodCantBeInternal(string arg0, string arg1, string arg2) /// The 'DuplicateAssemblyReference' diagnostic. /// /// -/// Duplicate assembly reference "{arg0}" +/// Warning: Duplicate assembly reference "{arg0}" /// public void DuplicateAssemblyReference(string arg0) { @@ -428,7 +428,7 @@ public void DuplicateAssemblyReference(string arg0) /// The 'UnableToResolveType' diagnostic. /// /// -/// Reference in "{arg0}" to type "{arg1}" claims it is defined in "{arg2}", but it could not be found. +/// Warning: Reference in "{arg0}" to type "{arg1}" claims it is defined in "{arg2}", but it could not be found. /// public void UnableToResolveType(string arg0, string arg1, string arg2) { @@ -439,7 +439,7 @@ public void UnableToResolveType(string arg0, string arg1, string arg2) /// The 'StubsAreDeprecated' diagnostic. /// /// -/// Compiling stubs is deprecated. Please add a reference to assembly "{arg0}" instead. +/// Warning: Compiling stubs is deprecated. Please add a reference to assembly "{arg0}" instead. /// public void StubsAreDeprecated(string arg0) { @@ -450,7 +450,7 @@ public void StubsAreDeprecated(string arg0) /// The 'WrongClassName' diagnostic. /// /// -/// Unable to compile "{arg0}" (wrong name: "{arg1}") +/// Warning: Unable to compile "{arg0}" (wrong name: "{arg1}") /// public void WrongClassName(string arg0, string arg1) { @@ -461,7 +461,7 @@ public void WrongClassName(string arg0, string arg1) /// The 'ReflectionCallerClassRequiresCallerID' diagnostic. /// /// -/// Reflection.getCallerClass() called from non-CallerID method. ("{arg0}.{arg1}{arg2}") +/// Warning: Reflection.getCallerClass() called from non-CallerID method. ("{arg0}.{arg1}{arg2}") /// public void ReflectionCallerClassRequiresCallerID(string arg0, string arg1, string arg2) { @@ -472,7 +472,7 @@ public void ReflectionCallerClassRequiresCallerID(string arg0, string arg1, stri /// The 'LegacyAssemblyAttributesFound' diagnostic. /// /// -/// Legacy assembly attributes container found. Please use the -assemblyattributes: option. +/// Warning: Legacy assembly attributes container found. Please use the -assemblyattributes: option. /// public void LegacyAssemblyAttributesFound() { @@ -483,7 +483,7 @@ public void LegacyAssemblyAttributesFound() /// The 'UnableToCreateLambdaFactory' diagnostic. /// /// -/// Unable to create static lambda factory. +/// Warning: Unable to create static lambda factory. /// public void UnableToCreateLambdaFactory() { @@ -494,7 +494,7 @@ public void UnableToCreateLambdaFactory() /// The 'UnknownWarning' diagnostic. /// /// -/// {arg0} +/// Warning: {arg0} /// public void UnknownWarning(string arg0) { @@ -505,7 +505,7 @@ public void UnknownWarning(string arg0) /// The 'DuplicateIkvmLangProperty' diagnostic. /// /// -/// Ignoring duplicate ikvm.lang.Property annotation on {arg0}.{arg1}. +/// Warning: Ignoring duplicate ikvm.lang.Property annotation on {arg0}.{arg1}. /// public void DuplicateIkvmLangProperty(string arg0, string arg1) { @@ -516,7 +516,7 @@ public void DuplicateIkvmLangProperty(string arg0, string arg1) /// The 'MalformedIkvmLangProperty' diagnostic. /// /// -/// Ignoring duplicate ikvm.lang.Property annotation on {arg0}.{arg1}. +/// Warning: Ignoring duplicate ikvm.lang.Property annotation on {arg0}.{arg1}. /// public void MalformedIkvmLangProperty(string arg0, string arg1) { @@ -527,7 +527,7 @@ public void MalformedIkvmLangProperty(string arg0, string arg1) /// The 'GenericCompilerWarning' diagnostic. /// /// -/// {arg0} +/// Warning: {arg0} /// public void GenericCompilerWarning(string arg0) { @@ -538,7 +538,7 @@ public void GenericCompilerWarning(string arg0) /// The 'GenericClassLoadingWarning' diagnostic. /// /// -/// {arg0} +/// Warning: {arg0} /// public void GenericClassLoadingWarning(string arg0) { @@ -549,7 +549,7 @@ public void GenericClassLoadingWarning(string arg0) /// The 'GenericVerifierWarning' diagnostic. /// /// -/// {arg0} +/// Warning: {arg0} /// public void GenericVerifierWarning(string arg0) { @@ -560,7 +560,7 @@ public void GenericVerifierWarning(string arg0) /// The 'GenericRuntimeWarning' diagnostic. /// /// -/// {arg0} +/// Warning: {arg0} /// public void GenericRuntimeWarning(string arg0) { @@ -571,7 +571,7 @@ public void GenericRuntimeWarning(string arg0) /// The 'GenericJniWarning' diagnostic. /// /// -/// {arg0} +/// Warning: {arg0} /// public void GenericJniWarning(string arg0) { @@ -582,7 +582,7 @@ public void GenericJniWarning(string arg0) /// The 'UnableToCreateProxy' diagnostic. /// /// -/// Unable to create proxy "{arg0}". ("{arg1}") +/// Error: Unable to create proxy "{arg0}". ("{arg1}") /// public void UnableToCreateProxy(string arg0, string arg1) { @@ -593,7 +593,7 @@ public void UnableToCreateProxy(string arg0, string arg1) /// The 'DuplicateProxy' diagnostic. /// /// -/// Duplicate proxy "{arg0}". +/// Error: Duplicate proxy "{arg0}". /// public void DuplicateProxy(string arg0) { @@ -604,7 +604,7 @@ public void DuplicateProxy(string arg0) /// The 'MapXmlUnableToResolveOpCode' diagnostic. /// /// -/// Unable to resolve opcode in remap file: {arg0}. +/// Error: Unable to resolve opcode in remap file: {arg0}. /// public void MapXmlUnableToResolveOpCode(string arg0) { @@ -615,7 +615,7 @@ public void MapXmlUnableToResolveOpCode(string arg0) /// The 'MapXmlError' diagnostic. /// /// -/// Error in remap file: {arg0}. +/// Error: Error in remap file: {arg0}. /// public void MapXmlError(string arg0) { @@ -626,7 +626,7 @@ public void MapXmlError(string arg0) /// The 'InputFileNotFound' diagnostic. /// /// -/// Source file '{arg0}' not found. +/// Error: Source file '{arg0}' not found. /// public void InputFileNotFound(string arg0) { @@ -637,7 +637,7 @@ public void InputFileNotFound(string arg0) /// The 'UnknownFileType' diagnostic. /// /// -/// Unknown file type: {arg0}. +/// Error: Unknown file type: {arg0}. /// public void UnknownFileType(string arg0) { @@ -648,7 +648,7 @@ public void UnknownFileType(string arg0) /// The 'UnknownElementInMapFile' diagnostic. /// /// -/// Unknown element {arg0} in remap file, line {arg1}, column {arg2}. +/// Error: Unknown element {arg0} in remap file, line {arg1}, column {arg2}. /// public void UnknownElementInMapFile(string arg0, string arg1, string arg2) { @@ -659,7 +659,7 @@ public void UnknownElementInMapFile(string arg0, string arg1, string arg2) /// The 'UnknownAttributeInMapFile' diagnostic. /// /// -/// Unknown attribute {arg0} in remap file, line {arg1}, column {arg2}. +/// Error: Unknown attribute {arg0} in remap file, line {arg1}, column {arg2}. /// public void UnknownAttributeInMapFile(string arg0, string arg1, string arg2) { @@ -670,7 +670,7 @@ public void UnknownAttributeInMapFile(string arg0, string arg1, string arg2) /// The 'InvalidMemberNameInMapFile' diagnostic. /// /// -/// Invalid {arg0} name '{arg1}' in remap file in class {arg2}. +/// Error: Invalid {arg0} name '{arg1}' in remap file in class {arg2}. /// public void InvalidMemberNameInMapFile(string arg0, string arg1, string arg2) { @@ -681,7 +681,7 @@ public void InvalidMemberNameInMapFile(string arg0, string arg1, string arg2) /// The 'InvalidMemberSignatureInMapFile' diagnostic. /// /// -/// Invalid {arg0} signature '{arg3}' in remap file for {arg0} {arg1}.{arg2}. +/// Error: Invalid {arg0} signature '{arg3}' in remap file for {arg0} {arg1}.{arg2}. /// public void InvalidMemberSignatureInMapFile(string arg0, string arg1, string arg2, string arg3) { @@ -692,7 +692,7 @@ public void InvalidMemberSignatureInMapFile(string arg0, string arg1, string arg /// The 'InvalidPropertyNameInMapFile' diagnostic. /// /// -/// Invalid property {arg0} name '{arg3}' in remap file for property {arg1}.{arg2}. +/// Error: Invalid property {arg0} name '{arg3}' in remap file for property {arg1}.{arg2}. /// public void InvalidPropertyNameInMapFile(string arg0, string arg1, string arg2, string arg3) { @@ -703,7 +703,7 @@ public void InvalidPropertyNameInMapFile(string arg0, string arg1, string arg2, /// The 'InvalidPropertySignatureInMapFile' diagnostic. /// /// -/// Invalid property {arg0} signature '{arg3}' in remap file for property {arg1}.{arg2}. +/// Error: Invalid property {arg0} signature '{arg3}' in remap file for property {arg1}.{arg2}. /// public void InvalidPropertySignatureInMapFile(string arg0, string arg1, string arg2, string arg3) { @@ -714,7 +714,7 @@ public void InvalidPropertySignatureInMapFile(string arg0, string arg1, string a /// The 'NonPrimaryAssemblyReference' diagnostic. /// /// -/// Referenced assembly "{arg0}" is not the primary assembly of a shared class loader group, please reference primary assembly "{arg1}" instead. +/// Error: Referenced assembly "{arg0}" is not the primary assembly of a shared class loader group, please reference primary assembly "{arg1}" instead. /// public void NonPrimaryAssemblyReference(string arg0, string arg1) { @@ -725,7 +725,7 @@ public void NonPrimaryAssemblyReference(string arg0, string arg1) /// The 'MissingType' diagnostic. /// /// -/// Reference to type "{arg0}" claims it is defined in "{arg1}", but it could not be found. +/// Error: Reference to type "{arg0}" claims it is defined in "{arg1}", but it could not be found. /// public void MissingType(string arg0, string arg1) { @@ -736,7 +736,7 @@ public void MissingType(string arg0, string arg1) /// The 'MissingReference' diagnostic. /// /// -/// The type '{arg0}' is defined in an assembly that is notResponseFileDepthExceeded referenced. You must add a reference to assembly '{arg1}'. +/// Error: The type '{arg0}' is defined in an assembly that is notResponseFileDepthExceeded referenced. You must add a reference to assembly '{arg1}'. /// public void MissingReference(string arg0, string arg1) { @@ -747,7 +747,7 @@ public void MissingReference(string arg0, string arg1) /// The 'CallerSensitiveOnUnsupportedMethod' diagnostic. /// /// -/// CallerSensitive annotation on unsupported method. ("{arg0}.{arg1}{arg2}") +/// Error: CallerSensitive annotation on unsupported method. ("{arg0}.{arg1}{arg2}") /// public void CallerSensitiveOnUnsupportedMethod(string arg0, string arg1, string arg2) { @@ -758,7 +758,7 @@ public void CallerSensitiveOnUnsupportedMethod(string arg0, string arg1, string /// The 'RemappedTypeMissingDefaultInterfaceMethod' diagnostic. /// /// -/// {arg0} does not implement default interface method {arg1}. +/// Error: {arg0} does not implement default interface method {arg1}. /// public void RemappedTypeMissingDefaultInterfaceMethod(string arg0, string arg1) { @@ -769,7 +769,7 @@ public void RemappedTypeMissingDefaultInterfaceMethod(string arg0, string arg1) /// The 'GenericCompilerError' diagnostic. /// /// -/// {arg0} +/// Error: {arg0} /// public void GenericCompilerError(string arg0) { @@ -780,7 +780,7 @@ public void GenericCompilerError(string arg0) /// The 'GenericClassLoadingError' diagnostic. /// /// -/// {arg0} +/// Error: {arg0} /// public void GenericClassLoadingError(string arg0) { @@ -791,7 +791,7 @@ public void GenericClassLoadingError(string arg0) /// The 'GenericVerifierError' diagnostic. /// /// -/// {arg0} +/// Error: {arg0} /// public void GenericVerifierError(string arg0) { @@ -802,7 +802,7 @@ public void GenericVerifierError(string arg0) /// The 'GenericRuntimeError' diagnostic. /// /// -/// {arg0} +/// Error: {arg0} /// public void GenericRuntimeError(string arg0) { @@ -813,7 +813,7 @@ public void GenericRuntimeError(string arg0) /// The 'GenericJniError' diagnostic. /// /// -/// {arg0} +/// Error: {arg0} /// public void GenericJniError(string arg0) { @@ -824,7 +824,7 @@ public void GenericJniError(string arg0) /// The 'ExportingImportsNotSupported' diagnostic. /// /// -/// Exporting previously imported assemblies is not supported. +/// Error: Exporting previously imported assemblies is not supported. /// public void ExportingImportsNotSupported() { @@ -835,7 +835,7 @@ public void ExportingImportsNotSupported() /// The 'ResponseFileDepthExceeded' diagnostic. /// /// -/// Response file nesting depth exceeded. +/// Fatal: Response file nesting depth exceeded. /// public void ResponseFileDepthExceeded() { @@ -846,7 +846,7 @@ public void ResponseFileDepthExceeded() /// The 'ErrorReadingFile' diagnostic. /// /// -/// Unable to read file: {arg0}. ({arg1}) +/// Fatal: Unable to read file: {arg0}. ({arg1}) /// public void ErrorReadingFile(string arg0, string arg1) { @@ -857,7 +857,7 @@ public void ErrorReadingFile(string arg0, string arg1) /// The 'NoTargetsFound' diagnostic. /// /// -/// No targets found +/// Fatal: No targets found /// public void NoTargetsFound() { @@ -868,7 +868,7 @@ public void NoTargetsFound() /// The 'FileFormatLimitationExceeded' diagnostic. /// /// -/// File format limitation exceeded: {arg0}. +/// Fatal: File format limitation exceeded: {arg0}. /// public void FileFormatLimitationExceeded(string arg0) { @@ -879,7 +879,7 @@ public void FileFormatLimitationExceeded(string arg0) /// The 'CannotSpecifyBothKeyFileAndContainer' diagnostic. /// /// -/// You cannot specify both a key file and container. +/// Fatal: You cannot specify both a key file and container. /// public void CannotSpecifyBothKeyFileAndContainer() { @@ -890,7 +890,7 @@ public void CannotSpecifyBothKeyFileAndContainer() /// The 'DelaySignRequiresKey' diagnostic. /// /// -/// You cannot delay sign without a key file or container. +/// Fatal: You cannot delay sign without a key file or container. /// public void DelaySignRequiresKey() { @@ -901,7 +901,7 @@ public void DelaySignRequiresKey() /// The 'InvalidStrongNameKeyPair' diagnostic. /// /// -/// Invalid key {arg0} specified. ("{arg1}") +/// Fatal: Invalid key {arg0} specified. ("{arg1}") /// public void InvalidStrongNameKeyPair(string arg0, string arg1) { @@ -912,7 +912,7 @@ public void InvalidStrongNameKeyPair(string arg0, string arg1) /// The 'ReferenceNotFound' diagnostic. /// /// -/// Reference not found: {arg0} +/// Fatal: Reference not found: {arg0} /// public void ReferenceNotFound(string arg0) { @@ -923,7 +923,7 @@ public void ReferenceNotFound(string arg0) /// The 'OptionsMustPreceedChildLevels' diagnostic. /// /// -/// You can only specify options before any child levels. +/// Fatal: You can only specify options before any child levels. /// public void OptionsMustPreceedChildLevels() { @@ -934,7 +934,7 @@ public void OptionsMustPreceedChildLevels() /// The 'UnrecognizedTargetType' diagnostic. /// /// -/// Invalid value '{arg0}' for -target option. +/// Fatal: Invalid value '{arg0}' for -target option. /// public void UnrecognizedTargetType(string arg0) { @@ -945,7 +945,7 @@ public void UnrecognizedTargetType(string arg0) /// The 'UnrecognizedPlatform' diagnostic. /// /// -/// Invalid value '{arg0}' for -platform option. +/// Fatal: Invalid value '{arg0}' for -platform option. /// public void UnrecognizedPlatform(string arg0) { @@ -956,7 +956,7 @@ public void UnrecognizedPlatform(string arg0) /// The 'UnrecognizedApartment' diagnostic. /// /// -/// Invalid value '{arg0}' for -apartment option. +/// Fatal: Invalid value '{arg0}' for -apartment option. /// public void UnrecognizedApartment(string arg0) { @@ -967,7 +967,7 @@ public void UnrecognizedApartment(string arg0) /// The 'MissingFileSpecification' diagnostic. /// /// -/// Missing file specification for '{arg0}' option. +/// Fatal: Missing file specification for '{arg0}' option. /// public void MissingFileSpecification(string arg0) { @@ -978,7 +978,7 @@ public void MissingFileSpecification(string arg0) /// The 'PathTooLong' diagnostic. /// /// -/// Path too long: {arg0}. +/// Fatal: Path too long: {arg0}. /// public void PathTooLong(string arg0) { @@ -989,7 +989,7 @@ public void PathTooLong(string arg0) /// The 'PathNotFound' diagnostic. /// /// -/// Path not found: {arg0}. +/// Fatal: Path not found: {arg0}. /// public void PathNotFound(string arg0) { @@ -1000,7 +1000,7 @@ public void PathNotFound(string arg0) /// The 'InvalidPath' diagnostic. /// /// -/// Invalid path: {arg0}. +/// Fatal: Invalid path: {arg0}. /// public void InvalidPath(string arg0) { @@ -1011,7 +1011,7 @@ public void InvalidPath(string arg0) /// The 'InvalidOptionSyntax' diagnostic. /// /// -/// Invalid option: {arg0}. +/// Fatal: Invalid option: {arg0}. /// public void InvalidOptionSyntax(string arg0) { @@ -1022,7 +1022,7 @@ public void InvalidOptionSyntax(string arg0) /// The 'ExternalResourceNotFound' diagnostic. /// /// -/// External resource file does not exist: {arg0}. +/// Fatal: External resource file does not exist: {arg0}. /// public void ExternalResourceNotFound(string arg0) { @@ -1033,7 +1033,7 @@ public void ExternalResourceNotFound(string arg0) /// The 'ExternalResourceNameInvalid' diagnostic. /// /// -/// External resource file may not include path specification: {arg0}. +/// Fatal: External resource file may not include path specification: {arg0}. /// public void ExternalResourceNameInvalid(string arg0) { @@ -1044,7 +1044,7 @@ public void ExternalResourceNameInvalid(string arg0) /// The 'InvalidVersionFormat' diagnostic. /// /// -/// Invalid version specified: {arg0}. +/// Fatal: Invalid version specified: {arg0}. /// public void InvalidVersionFormat(string arg0) { @@ -1055,7 +1055,7 @@ public void InvalidVersionFormat(string arg0) /// The 'InvalidFileAlignment' diagnostic. /// /// -/// Invalid value '{arg0}' for -filealign option. +/// Fatal: Invalid value '{arg0}' for -filealign option. /// public void InvalidFileAlignment(string arg0) { @@ -1066,7 +1066,7 @@ public void InvalidFileAlignment(string arg0) /// The 'ErrorWritingFile' diagnostic. /// /// -/// Unable to write file: {arg0}. ({arg1}) +/// Fatal: Unable to write file: {arg0}. ({arg1}) /// public void ErrorWritingFile(string arg0, string arg1) { @@ -1077,7 +1077,7 @@ public void ErrorWritingFile(string arg0, string arg1) /// The 'UnrecognizedOption' diagnostic. /// /// -/// Unrecognized option: {arg0}. +/// Fatal: Unrecognized option: {arg0}. /// public void UnrecognizedOption(string arg0) { @@ -1088,7 +1088,7 @@ public void UnrecognizedOption(string arg0) /// The 'NoOutputFileSpecified' diagnostic. /// /// -/// No output file specified. +/// Fatal: No output file specified. /// public void NoOutputFileSpecified() { @@ -1099,7 +1099,7 @@ public void NoOutputFileSpecified() /// The 'SharedClassLoaderCannotBeUsedOnModuleTarget' diagnostic. /// /// -/// Incompatible options: -target:module and -sharedclassloader cannot be combined. +/// Fatal: Incompatible options: -target:module and -sharedclassloader cannot be combined. /// public void SharedClassLoaderCannotBeUsedOnModuleTarget() { @@ -1110,7 +1110,7 @@ public void SharedClassLoaderCannotBeUsedOnModuleTarget() /// The 'RuntimeNotFound' diagnostic. /// /// -/// Unable to load runtime assembly. +/// Fatal: Unable to load runtime assembly. /// public void RuntimeNotFound() { @@ -1121,7 +1121,7 @@ public void RuntimeNotFound() /// The 'MainClassRequiresExe' diagnostic. /// /// -/// Main class cannot be specified for library or module. +/// Fatal: Main class cannot be specified for library or module. /// public void MainClassRequiresExe() { @@ -1132,7 +1132,7 @@ public void MainClassRequiresExe() /// The 'ExeRequiresMainClass' diagnostic. /// /// -/// No main method found. +/// Fatal: No main method found. /// public void ExeRequiresMainClass() { @@ -1143,7 +1143,7 @@ public void ExeRequiresMainClass() /// The 'PropertiesRequireExe' diagnostic. /// /// -/// Properties cannot be specified for library or module. +/// Fatal: Properties cannot be specified for library or module. /// public void PropertiesRequireExe() { @@ -1154,7 +1154,7 @@ public void PropertiesRequireExe() /// The 'ModuleCannotHaveClassLoader' diagnostic. /// /// -/// Cannot specify assembly class loader for modules. +/// Fatal: Cannot specify assembly class loader for modules. /// public void ModuleCannotHaveClassLoader() { @@ -1165,7 +1165,7 @@ public void ModuleCannotHaveClassLoader() /// The 'ErrorParsingMapFile' diagnostic. /// /// -/// Unable to parse remap file: {arg0}. ({arg1}) +/// Fatal: Unable to parse remap file: {arg0}. ({arg1}) /// public void ErrorParsingMapFile(string arg0, string arg1) { @@ -1176,7 +1176,7 @@ public void ErrorParsingMapFile(string arg0, string arg1) /// The 'BootstrapClassesMissing' diagnostic. /// /// -/// Bootstrap classes missing and core assembly not found. +/// Fatal: Bootstrap classes missing and core assembly not found. /// public void BootstrapClassesMissing() { @@ -1187,7 +1187,7 @@ public void BootstrapClassesMissing() /// The 'StrongNameRequiresStrongNamedRefs' diagnostic. /// /// -/// All referenced assemblies must be strong named, to be able to sign the output assembly. +/// Fatal: All referenced assemblies must be strong named, to be able to sign the output assembly. /// public void StrongNameRequiresStrongNamedRefs() { @@ -1198,7 +1198,7 @@ public void StrongNameRequiresStrongNamedRefs() /// The 'MainClassNotFound' diagnostic. /// /// -/// Main class not found. +/// Fatal: Main class not found. /// public void MainClassNotFound() { @@ -1209,7 +1209,7 @@ public void MainClassNotFound() /// The 'MainMethodNotFound' diagnostic. /// /// -/// Main method not found. +/// Fatal: Main method not found. /// public void MainMethodNotFound() { @@ -1220,7 +1220,7 @@ public void MainMethodNotFound() /// The 'UnsupportedMainMethod' diagnostic. /// /// -/// Redirected main method not supported. +/// Fatal: Redirected main method not supported. /// public void UnsupportedMainMethod() { @@ -1231,7 +1231,7 @@ public void UnsupportedMainMethod() /// The 'ExternalMainNotAccessible' diagnostic. /// /// -/// External main method must be public and in a public class. +/// Fatal: External main method must be public and in a public class. /// public void ExternalMainNotAccessible() { @@ -1242,7 +1242,7 @@ public void ExternalMainNotAccessible() /// The 'ClassLoaderNotFound' diagnostic. /// /// -/// Custom assembly class loader class not found. +/// Fatal: Custom assembly class loader class not found. /// public void ClassLoaderNotFound() { @@ -1253,7 +1253,7 @@ public void ClassLoaderNotFound() /// The 'ClassLoaderNotAccessible' diagnostic. /// /// -/// Custom assembly class loader class is not accessible. +/// Fatal: Custom assembly class loader class is not accessible. /// public void ClassLoaderNotAccessible() { @@ -1264,7 +1264,7 @@ public void ClassLoaderNotAccessible() /// The 'ClassLoaderIsAbstract' diagnostic. /// /// -/// Custom assembly class loader class is abstract. +/// Fatal: Custom assembly class loader class is abstract. /// public void ClassLoaderIsAbstract() { @@ -1275,7 +1275,7 @@ public void ClassLoaderIsAbstract() /// The 'ClassLoaderNotClassLoader' diagnostic. /// /// -/// Custom assembly class loader class does not extend java.lang.ClassLoader. +/// Fatal: Custom assembly class loader class does not extend java.lang.ClassLoader. /// public void ClassLoaderNotClassLoader() { @@ -1286,7 +1286,7 @@ public void ClassLoaderNotClassLoader() /// The 'ClassLoaderConstructorMissing' diagnostic. /// /// -/// Custom assembly class loader constructor is missing. +/// Fatal: Custom assembly class loader constructor is missing. /// public void ClassLoaderConstructorMissing() { @@ -1297,7 +1297,7 @@ public void ClassLoaderConstructorMissing() /// The 'MapFileTypeNotFound' diagnostic. /// /// -/// Type '{arg0}' referenced in remap file was not found. +/// Fatal: Type '{arg0}' referenced in remap file was not found. /// public void MapFileTypeNotFound(string arg0) { @@ -1308,7 +1308,7 @@ public void MapFileTypeNotFound(string arg0) /// The 'MapFileClassNotFound' diagnostic. /// /// -/// Class '{arg0}' referenced in remap file was not found. +/// Fatal: Class '{arg0}' referenced in remap file was not found. /// public void MapFileClassNotFound(string arg0) { @@ -1319,7 +1319,7 @@ public void MapFileClassNotFound(string arg0) /// The 'MaximumErrorCountReached' diagnostic. /// /// -/// Maximum error count reached. +/// Fatal: Maximum error count reached. /// public void MaximumErrorCountReached() { @@ -1330,7 +1330,7 @@ public void MaximumErrorCountReached() /// The 'LinkageError' diagnostic. /// /// -/// Link error: {arg0} +/// Fatal: Link error: {arg0} /// public void LinkageError(string arg0) { @@ -1341,7 +1341,7 @@ public void LinkageError(string arg0) /// The 'RuntimeMismatch' diagnostic. /// /// -/// Referenced assembly {referencedAssemblyPath} was compiled with an incompatible IKVM.Runtime version. Current runtime: {runtimeAssemblyName}. Referenced assembly runtime: {referencedAssemblyName} +/// Fatal: Referenced assembly {referencedAssemblyPath} was compiled with an incompatible IKVM.Runtime version. Current runtime: {runtimeAssemblyName}. Referenced assembly runtime: {referencedAssemblyName} /// public void RuntimeMismatch(string referencedAssemblyPath, string runtimeAssemblyName, string referencedAssemblyName) { @@ -1352,7 +1352,7 @@ public void RuntimeMismatch(string referencedAssemblyPath, string runtimeAssembl /// The 'RuntimeMismatchStrongName' diagnostic. /// /// -/// +/// Fatal: /// public void RuntimeMismatchStrongName() { @@ -1363,7 +1363,7 @@ public void RuntimeMismatchStrongName() /// The 'CoreClassesMissing' diagnostic. /// /// -/// Failed to find core classes in core library. +/// Fatal: Failed to find core classes in core library. /// public void CoreClassesMissing() { @@ -1374,7 +1374,7 @@ public void CoreClassesMissing() /// The 'CriticalClassNotFound' diagnostic. /// /// -/// Unable to load critical class '{arg0}'. +/// Fatal: Unable to load critical class '{arg0}'. /// public void CriticalClassNotFound(string arg0) { @@ -1385,7 +1385,7 @@ public void CriticalClassNotFound(string arg0) /// The 'AssemblyContainsDuplicateClassNames' diagnostic. /// /// -/// Type '{arg0}' and '{arg1}' both map to the same name '{arg2}'. ({arg3}) +/// Fatal: Type '{arg0}' and '{arg1}' both map to the same name '{arg2}'. ({arg3}) /// public void AssemblyContainsDuplicateClassNames(string arg0, string arg1, string arg2, string arg3) { @@ -1396,7 +1396,7 @@ public void AssemblyContainsDuplicateClassNames(string arg0, string arg1, string /// The 'CallerIDRequiresHasCallerIDAnnotation' diagnostic. /// /// -/// CallerID.getCallerID() requires a HasCallerID annotation. +/// Fatal: CallerID.getCallerID() requires a HasCallerID annotation. /// public void CallerIDRequiresHasCallerIDAnnotation() { @@ -1407,7 +1407,7 @@ public void CallerIDRequiresHasCallerIDAnnotation() /// The 'UnableToResolveInterface' diagnostic. /// /// -/// Unable to resolve interface '{arg0}' on type '{arg1}'. +/// Fatal: Unable to resolve interface '{arg0}' on type '{arg1}'. /// public void UnableToResolveInterface(string arg0, string arg1) { @@ -1418,7 +1418,7 @@ public void UnableToResolveInterface(string arg0, string arg1) /// The 'MissingBaseType' diagnostic. /// /// -/// The base class or interface '{arg0}' in assembly '{arg1}' referenced by type '{arg2}' in '{arg3}' could not be resolved. +/// Fatal: The base class or interface '{arg0}' in assembly '{arg1}' referenced by type '{arg2}' in '{arg3}' could not be resolved. /// public void MissingBaseType(string arg0, string arg1, string arg2, string arg3) { @@ -1429,7 +1429,7 @@ public void MissingBaseType(string arg0, string arg1, string arg2, string arg3) /// The 'MissingBaseTypeReference' diagnostic. /// /// -/// The type '{arg0}' is defined in an assembly that is not referenced. You must add a reference to assembly '{arg1}'. +/// Fatal: The type '{arg0}' is defined in an assembly that is not referenced. You must add a reference to assembly '{arg1}'. /// public void MissingBaseTypeReference(string arg0, string arg1) { @@ -1440,7 +1440,7 @@ public void MissingBaseTypeReference(string arg0, string arg1) /// The 'FileNotFound' diagnostic. /// /// -/// File not found: {arg0}. +/// Fatal: File not found: {arg0}. /// public void FileNotFound(string arg0) { @@ -1451,7 +1451,7 @@ public void FileNotFound(string arg0) /// The 'RuntimeMethodMissing' diagnostic. /// /// -/// Runtime method '{arg0}' not found. +/// Fatal: Runtime method '{arg0}' not found. /// public void RuntimeMethodMissing(string arg0) { @@ -1462,7 +1462,7 @@ public void RuntimeMethodMissing(string arg0) /// The 'MapFileFieldNotFound' diagnostic. /// /// -/// Field '{arg0}' referenced in remap file was not found in class '{arg1}'. +/// Fatal: Field '{arg0}' referenced in remap file was not found in class '{arg1}'. /// public void MapFileFieldNotFound(string arg0, string arg1) { @@ -1473,7 +1473,7 @@ public void MapFileFieldNotFound(string arg0, string arg1) /// The 'GhostInterfaceMethodMissing' diagnostic. /// /// -/// Remapped class '{arg0}' does not implement ghost interface method. ({arg1}.{arg2}{arg3}) +/// Fatal: Remapped class '{arg0}' does not implement ghost interface method. ({arg1}.{arg2}{arg3}) /// public void GhostInterfaceMethodMissing(string arg0, string arg1, string arg2, string arg3) { @@ -1484,7 +1484,7 @@ public void GhostInterfaceMethodMissing(string arg0, string arg1, string arg2, s /// The 'ModuleInitializerMethodRequirements' diagnostic. /// /// -/// Method '{arg1}.{arg2}{arg3}' does not meet the requirements of a module initializer. +/// Fatal: Method '{arg1}.{arg2}{arg3}' does not meet the requirements of a module initializer. /// public void ModuleInitializerMethodRequirements(string arg1, string arg2, string arg3) { @@ -1495,7 +1495,7 @@ public void ModuleInitializerMethodRequirements(string arg1, string arg2, string /// The 'InvalidZip' diagnostic. /// /// -/// Invalid zip: {name}. +/// Fatal: Invalid zip: {name}. /// public void InvalidZip(string name) { @@ -1506,7 +1506,7 @@ public void InvalidZip(string name) /// The 'CoreAssemblyVersionMismatch' diagnostic. /// /// -/// Unable to load assembly '{0}' as it depends on a higher version of {1} than the one currently loaded. +/// Fatal: Unable to load assembly '{0}' as it depends on a higher version of {1} than the one currently loaded. /// public void CoreAssemblyVersionMismatch(string arg0, string arg1) { @@ -1517,7 +1517,7 @@ public void CoreAssemblyVersionMismatch(string arg0, string arg1) /// The 'GenericRuntimeTrace' diagnostic. /// /// -/// {arg0} +/// Trace: {arg0} /// public void GenericRuntimeTrace(string arg0) { @@ -1528,7 +1528,7 @@ public void GenericRuntimeTrace(string arg0) /// The 'GenericJniTrace' diagnostic. /// /// -/// {arg0} +/// Trace: {arg0} /// public void GenericJniTrace(string arg0) { @@ -1539,7 +1539,7 @@ public void GenericJniTrace(string arg0) /// The 'GenericCompilerTrace' diagnostic. /// /// -/// {arg0} +/// Trace: {arg0} /// public void GenericCompilerTrace(string arg0) { diff --git a/src/IKVM.CoreLib/Diagnostics/NullDiagnosticHandler.g.tt b/src/IKVM.CoreLib/Diagnostics/NullDiagnosticHandler.g.tt index 10badb18b..9d652e807 100644 --- a/src/IKVM.CoreLib/Diagnostics/NullDiagnosticHandler.g.tt +++ b/src/IKVM.CoreLib/Diagnostics/NullDiagnosticHandler.g.tt @@ -45,7 +45,7 @@ foreach (var kvp in DiagnosticFile.Read(Host.ResolvePath(Path.Combine("Diagnosti /// <#= desc #> /// /// -<#= Util.ToCommentString(kvp.Value.Message ?? "") #> +<#= Util.ToCommentString(kvp.Value) #> /// public void <#= kvp.Key #>(<#= string.Join(", ", argDecl) #>) { diff --git a/src/IKVM.CoreLib/Diagnostics/Tracing/DiagnosticEventSource.g.cs b/src/IKVM.CoreLib/Diagnostics/Tracing/DiagnosticEventSource.g.cs index 8d447587b..123b06795 100644 --- a/src/IKVM.CoreLib/Diagnostics/Tracing/DiagnosticEventSource.g.cs +++ b/src/IKVM.CoreLib/Diagnostics/Tracing/DiagnosticEventSource.g.cs @@ -12,7 +12,7 @@ partial class DiagnosticEventSource /// The 'MainMethodFound' diagnostic. /// /// -/// Found main method in class "{arg0}". +/// Info: Found main method in class "{arg0}". /// [Event(1, Message = "Found main method in class \"{0}\".", Level = EventLevel.Informational)] public void MainMethodFound(string arg0) => WriteEvent(1, arg0); @@ -21,7 +21,7 @@ partial class DiagnosticEventSource /// The 'OutputFileIs' diagnostic. /// /// -/// Output file is "{arg0}". +/// Info: Output file is "{arg0}". /// [Event(2, Message = "Output file is \"{0}\".", Level = EventLevel.Informational)] public void OutputFileIs(string arg0) => WriteEvent(2, arg0); @@ -30,7 +30,7 @@ partial class DiagnosticEventSource /// The 'AutoAddRef' diagnostic. /// /// -/// Automatically adding reference to "{arg0}". +/// Info: Automatically adding reference to "{arg0}". /// [Event(3, Message = "Automatically adding reference to \"{0}\".", Level = EventLevel.Informational)] public void AutoAddRef(string arg0) => WriteEvent(3, arg0); @@ -39,7 +39,7 @@ partial class DiagnosticEventSource /// The 'MainMethodFromManifest' diagnostic. /// /// -/// Using main class "{arg0}" based on jar manifest. +/// Info: Using main class "{arg0}" based on jar manifest. /// [Event(4, Message = "Using main class \"{0}\" based on jar manifest.", Level = EventLevel.Informational)] public void MainMethodFromManifest(string arg0) => WriteEvent(4, arg0); @@ -48,7 +48,7 @@ partial class DiagnosticEventSource /// The 'GenericCompilerInfo' diagnostic. /// /// -/// {arg0} +/// Info: {arg0} /// [Event(5, Message = "{0}", Level = EventLevel.Informational)] public void GenericCompilerInfo(string arg0) => WriteEvent(5, arg0); @@ -57,7 +57,7 @@ partial class DiagnosticEventSource /// The 'GenericClassLoadingInfo' diagnostic. /// /// -/// {arg0} +/// Info: {arg0} /// [Event(6, Message = "{0}", Level = EventLevel.Informational)] public void GenericClassLoadingInfo(string arg0) => WriteEvent(6, arg0); @@ -66,7 +66,7 @@ partial class DiagnosticEventSource /// The 'GenericVerifierInfo' diagnostic. /// /// -/// {arg0} +/// Info: {arg0} /// [Event(7, Message = "{0}", Level = EventLevel.Informational)] public void GenericVerifierInfo(string arg0) => WriteEvent(7, arg0); @@ -75,7 +75,7 @@ partial class DiagnosticEventSource /// The 'GenericRuntimeInfo' diagnostic. /// /// -/// {arg0} +/// Info: {arg0} /// [Event(8, Message = "{0}", Level = EventLevel.Informational)] public void GenericRuntimeInfo(string arg0) => WriteEvent(8, arg0); @@ -84,7 +84,7 @@ partial class DiagnosticEventSource /// The 'GenericJniInfo' diagnostic. /// /// -/// {arg0} +/// Info: {arg0} /// [Event(9, Message = "{0}", Level = EventLevel.Informational)] public void GenericJniInfo(string arg0) => WriteEvent(9, arg0); @@ -93,7 +93,7 @@ partial class DiagnosticEventSource /// The 'ClassNotFound' diagnostic. /// /// -/// Class "{arg0}" not found. +/// Warning: Class "{arg0}" not found. /// [Event(100, Message = "Class \"{0}\" not found.", Level = EventLevel.Warning)] public void ClassNotFound(string arg0) => WriteEvent(100, arg0); @@ -102,7 +102,7 @@ partial class DiagnosticEventSource /// The 'ClassFormatError' diagnostic. /// /// -/// Unable to compile class "{arg0}". (class format error "{arg1}") +/// Warning: Unable to compile class "{arg0}". (class format error "{arg1}") /// [Event(101, Message = "Unable to compile class \"{0}\". (class format error \"{1}\")", Level = EventLevel.Warning)] public void ClassFormatError(string arg0, string arg1) => WriteEvent(101, arg0, arg1); @@ -111,7 +111,7 @@ partial class DiagnosticEventSource /// The 'DuplicateClassName' diagnostic. /// /// -/// Duplicate class name: "{arg0}". +/// Warning: Duplicate class name: "{arg0}". /// [Event(102, Message = "Duplicate class name: \"{0}\".", Level = EventLevel.Warning)] public void DuplicateClassName(string arg0) => WriteEvent(102, arg0); @@ -120,7 +120,7 @@ partial class DiagnosticEventSource /// The 'IllegalAccessError' diagnostic. /// /// -/// Unable to compile class "{arg0}". (illegal access error "{arg1}") +/// Warning: Unable to compile class "{arg0}". (illegal access error "{arg1}") /// [Event(103, Message = "Unable to compile class \"{0}\". (illegal access error \"{1}\")", Level = EventLevel.Warning)] public void IllegalAccessError(string arg0, string arg1) => WriteEvent(103, arg0, arg1); @@ -129,7 +129,7 @@ partial class DiagnosticEventSource /// The 'VerificationError' diagnostic. /// /// -/// Unable to compile class "{arg0}". (verification error "{arg1}") +/// Warning: Unable to compile class "{arg0}". (verification error "{arg1}") /// [Event(104, Message = "Unable to compile class \"{0}\". (verification error \"{1}\")", Level = EventLevel.Warning)] public void VerificationError(string arg0, string arg1) => WriteEvent(104, arg0, arg1); @@ -138,7 +138,7 @@ partial class DiagnosticEventSource /// The 'NoClassDefFoundError' diagnostic. /// /// -/// Unable to compile class "{arg0}". (missing class "{arg1}") +/// Warning: Unable to compile class "{arg0}". (missing class "{arg1}") /// [Event(105, Message = "Unable to compile class \"{0}\". (missing class \"{1}\")", Level = EventLevel.Warning)] public void NoClassDefFoundError(string arg0, string arg1) => WriteEvent(105, arg0, arg1); @@ -147,7 +147,7 @@ partial class DiagnosticEventSource /// The 'GenericUnableToCompileError' diagnostic. /// /// -/// Unable to compile class "{arg0}". ("{arg1}": "{arg2}") +/// Warning: Unable to compile class "{arg0}". ("{arg1}": "{arg2}") /// [Event(106, Message = "Unable to compile class \"{0}\". (\"{1}\": \"{2}\")", Level = EventLevel.Warning)] public void GenericUnableToCompileError(string arg0, string arg1, string arg2) => WriteEvent(106, arg0, arg1, arg2); @@ -156,7 +156,7 @@ partial class DiagnosticEventSource /// The 'DuplicateResourceName' diagnostic. /// /// -/// Skipping resource (name clash): "{arg0}" +/// Warning: Skipping resource (name clash): "{arg0}" /// [Event(107, Message = "Skipping resource (name clash): \"{0}\"", Level = EventLevel.Warning)] public void DuplicateResourceName(string arg0) => WriteEvent(107, arg0); @@ -165,7 +165,7 @@ partial class DiagnosticEventSource /// The 'SkippingReferencedClass' diagnostic. /// /// -/// Skipping class: "{arg0}". (class is already available in referenced assembly "{arg1}") +/// Warning: Skipping class: "{arg0}". (class is already available in referenced assembly "{arg1}") /// [Event(109, Message = "Skipping class: \"{0}\". (class is already available in referenced assembly \"{1}\")", Level = EventLevel.Warning)] public void SkippingReferencedClass(string arg0, string arg1) => WriteEvent(109, arg0, arg1); @@ -174,7 +174,7 @@ partial class DiagnosticEventSource /// The 'NoJniRuntime' diagnostic. /// /// -/// Unable to load runtime JNI assembly. +/// Warning: Unable to load runtime JNI assembly. /// [Event(110, Message = "Unable to load runtime JNI assembly.", Level = EventLevel.Warning)] public void NoJniRuntime() => WriteEvent(110); @@ -183,7 +183,7 @@ partial class DiagnosticEventSource /// The 'EmittedNoClassDefFoundError' diagnostic. /// /// -/// Emitted java.lang.NoClassDefFoundError in "{arg0}". ("{arg1}"). +/// Warning: Emitted java.lang.NoClassDefFoundError in "{arg0}". ("{arg1}"). /// [Event(111, Message = "Emitted java.lang.NoClassDefFoundError in \"{0}\". (\"{1}\").", Level = EventLevel.Warning)] public void EmittedNoClassDefFoundError(string arg0, string arg1) => WriteEvent(111, arg0, arg1); @@ -192,7 +192,7 @@ partial class DiagnosticEventSource /// The 'EmittedIllegalAccessError' diagnostic. /// /// -/// Emitted java.lang.IllegalAccessError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.IllegalAccessError in "{arg0}". ("{arg1}") /// [Event(112, Message = "Emitted java.lang.IllegalAccessError in \"{0}\". (\"{1}\")", Level = EventLevel.Warning)] public void EmittedIllegalAccessError(string arg0, string arg1) => WriteEvent(112, arg0, arg1); @@ -201,7 +201,7 @@ partial class DiagnosticEventSource /// The 'EmittedInstantiationError' diagnostic. /// /// -/// Emitted java.lang.InstantiationError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.InstantiationError in "{arg0}". ("{arg1}") /// [Event(113, Message = "Emitted java.lang.InstantiationError in \"{0}\". (\"{1}\")", Level = EventLevel.Warning)] public void EmittedInstantiationError(string arg0, string arg1) => WriteEvent(113, arg0, arg1); @@ -210,7 +210,7 @@ partial class DiagnosticEventSource /// The 'EmittedIncompatibleClassChangeError' diagnostic. /// /// -/// Emitted java.lang.IncompatibleClassChangeError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.IncompatibleClassChangeError in "{arg0}". ("{arg1}") /// [Event(114, Message = "Emitted java.lang.IncompatibleClassChangeError in \"{0}\". (\"{1}\")", Level = EventLevel.Warning)] public void EmittedIncompatibleClassChangeError(string arg0, string arg1) => WriteEvent(114, arg0, arg1); @@ -219,7 +219,7 @@ partial class DiagnosticEventSource /// The 'EmittedNoSuchFieldError' diagnostic. /// /// -/// Emitted java.lang.NoSuchFieldError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.NoSuchFieldError in "{arg0}". ("{arg1}") /// [Event(115, Message = "Emitted java.lang.NoSuchFieldError in \"{0}\". (\"{1}\")", Level = EventLevel.Warning)] public void EmittedNoSuchFieldError(string arg0, string arg1) => WriteEvent(115, arg0, arg1); @@ -228,7 +228,7 @@ partial class DiagnosticEventSource /// The 'EmittedAbstractMethodError' diagnostic. /// /// -/// Emitted java.lang.AbstractMethodError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.AbstractMethodError in "{arg0}". ("{arg1}") /// [Event(116, Message = "Emitted java.lang.AbstractMethodError in \"{0}\". (\"{1}\")", Level = EventLevel.Warning)] public void EmittedAbstractMethodError(string arg0, string arg1) => WriteEvent(116, arg0, arg1); @@ -237,7 +237,7 @@ partial class DiagnosticEventSource /// The 'EmittedNoSuchMethodError' diagnostic. /// /// -/// Emitted java.lang.NoSuchMethodError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.NoSuchMethodError in "{arg0}". ("{arg1}") /// [Event(117, Message = "Emitted java.lang.NoSuchMethodError in \"{0}\". (\"{1}\")", Level = EventLevel.Warning)] public void EmittedNoSuchMethodError(string arg0, string arg1) => WriteEvent(117, arg0, arg1); @@ -246,7 +246,7 @@ partial class DiagnosticEventSource /// The 'EmittedLinkageError' diagnostic. /// /// -/// Emitted java.lang.LinkageError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.LinkageError in "{arg0}". ("{arg1}") /// [Event(118, Message = "Emitted java.lang.LinkageError in \"{0}\". (\"{1}\")", Level = EventLevel.Warning)] public void EmittedLinkageError(string arg0, string arg1) => WriteEvent(118, arg0, arg1); @@ -255,7 +255,7 @@ partial class DiagnosticEventSource /// The 'EmittedVerificationError' diagnostic. /// /// -/// Emitted java.lang.VerificationError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.VerificationError in "{arg0}". ("{arg1}") /// [Event(119, Message = "Emitted java.lang.VerificationError in \"{0}\". (\"{1}\")", Level = EventLevel.Warning)] public void EmittedVerificationError(string arg0, string arg1) => WriteEvent(119, arg0, arg1); @@ -264,7 +264,7 @@ partial class DiagnosticEventSource /// The 'EmittedClassFormatError' diagnostic. /// /// -/// Emitted java.lang.ClassFormatError in "{arg0}". ("{arg1}") +/// Warning: Emitted java.lang.ClassFormatError in "{arg0}". ("{arg1}") /// [Event(120, Message = "Emitted java.lang.ClassFormatError in \"{0}\". (\"{1}\")", Level = EventLevel.Warning)] public void EmittedClassFormatError(string arg0, string arg1) => WriteEvent(120, arg0, arg1); @@ -273,7 +273,7 @@ partial class DiagnosticEventSource /// The 'InvalidCustomAttribute' diagnostic. /// /// -/// Error emitting "{arg0}" custom attribute. ("{arg1}") +/// Warning: Error emitting "{arg0}" custom attribute. ("{arg1}") /// [Event(121, Message = "Error emitting \"{0}\" custom attribute. (\"{1}\")", Level = EventLevel.Warning)] public void InvalidCustomAttribute(string arg0, string arg1) => WriteEvent(121, arg0, arg1); @@ -282,7 +282,7 @@ partial class DiagnosticEventSource /// The 'IgnoredCustomAttribute' diagnostic. /// /// -/// Custom attribute "{arg0}" was ignored. ("{arg1}") +/// Warning: Custom attribute "{arg0}" was ignored. ("{arg1}") /// [Event(122, Message = "Custom attribute \"{0}\" was ignored. (\"{1}\")", Level = EventLevel.Warning)] public void IgnoredCustomAttribute(string arg0, string arg1) => WriteEvent(122, arg0, arg1); @@ -291,7 +291,7 @@ partial class DiagnosticEventSource /// The 'AssumeAssemblyVersionMatch' diagnostic. /// /// -/// Assuming assembly reference "{arg0}" matches "{arg1}", you may need to supply runtime policy +/// Warning: Assuming assembly reference "{arg0}" matches "{arg1}", you may need to supply runtime policy /// [Event(123, Message = "Assuming assembly reference \"{0}\" matches \"{1}\", you may need to supply runtime p" + "olicy", Level = EventLevel.Warning)] @@ -301,7 +301,7 @@ partial class DiagnosticEventSource /// The 'InvalidDirectoryInLibOptionPath' diagnostic. /// /// -/// Directory "{arg0}" specified in -lib option is not valid. +/// Warning: Directory "{arg0}" specified in -lib option is not valid. /// [Event(124, Message = "Directory \"{0}\" specified in -lib option is not valid.", Level = EventLevel.Warning)] public void InvalidDirectoryInLibOptionPath(string arg0) => WriteEvent(124, arg0); @@ -310,7 +310,7 @@ partial class DiagnosticEventSource /// The 'InvalidDirectoryInLibEnvironmentPath' diagnostic. /// /// -/// Directory "{arg0}" specified in LIB environment is not valid. +/// Warning: Directory "{arg0}" specified in LIB environment is not valid. /// [Event(125, Message = "Directory \"{0}\" specified in LIB environment is not valid.", Level = EventLevel.Warning)] public void InvalidDirectoryInLibEnvironmentPath(string arg0) => WriteEvent(125, arg0); @@ -319,7 +319,7 @@ partial class DiagnosticEventSource /// The 'LegacySearchRule' diagnostic. /// /// -/// Found assembly "{arg0}" using legacy search rule, please append '.dll' to the reference. +/// Warning: Found assembly "{arg0}" using legacy search rule, please append '.dll' to the reference. /// [Event(126, Message = "Found assembly \"{0}\" using legacy search rule, please append \'.dll\' to the refere" + "nce.", Level = EventLevel.Warning)] @@ -329,7 +329,7 @@ partial class DiagnosticEventSource /// The 'AssemblyLocationIgnored' diagnostic. /// /// -/// Assembly "{arg0}" is ignored as previously loaded assembly "{arg1}" has the same identity "{arg2}". +/// Warning: Assembly "{arg0}" is ignored as previously loaded assembly "{arg1}" has the same identity "{arg2}". /// [Event(127, Message = "Assembly \"{0}\" is ignored as previously loaded assembly \"{1}\" has the same identi" + "ty \"{2}\".", Level = EventLevel.Warning)] @@ -339,7 +339,7 @@ partial class DiagnosticEventSource /// The 'InterfaceMethodCantBeInternal' diagnostic. /// /// -/// Ignoring @ikvm.lang.Internal annotation on interface method. ("{arg0}.{arg1}{arg2}") +/// Warning: Ignoring @ikvm.lang.Internal annotation on interface method. ("{arg0}.{arg1}{arg2}") /// [Event(128, Message = "Ignoring @ikvm.lang.Internal annotation on interface method. (\"{0}.{1}{2}\")", Level = EventLevel.Warning)] public void InterfaceMethodCantBeInternal(string arg0, string arg1, string arg2) => WriteEvent(128, arg0, arg1, arg2); @@ -348,7 +348,7 @@ partial class DiagnosticEventSource /// The 'DuplicateAssemblyReference' diagnostic. /// /// -/// Duplicate assembly reference "{arg0}" +/// Warning: Duplicate assembly reference "{arg0}" /// [Event(132, Message = "Duplicate assembly reference \"{0}\"", Level = EventLevel.Warning)] public void DuplicateAssemblyReference(string arg0) => WriteEvent(132, arg0); @@ -357,7 +357,7 @@ partial class DiagnosticEventSource /// The 'UnableToResolveType' diagnostic. /// /// -/// Reference in "{arg0}" to type "{arg1}" claims it is defined in "{arg2}", but it could not be found. +/// Warning: Reference in "{arg0}" to type "{arg1}" claims it is defined in "{arg2}", but it could not be found. /// [Event(133, Message = "Reference in \"{0}\" to type \"{1}\" claims it is defined in \"{2}\", but it could not " + "be found.", Level = EventLevel.Warning)] @@ -367,7 +367,7 @@ partial class DiagnosticEventSource /// The 'StubsAreDeprecated' diagnostic. /// /// -/// Compiling stubs is deprecated. Please add a reference to assembly "{arg0}" instead. +/// Warning: Compiling stubs is deprecated. Please add a reference to assembly "{arg0}" instead. /// [Event(134, Message = "Compiling stubs is deprecated. Please add a reference to assembly \"{0}\" instead.", Level = EventLevel.Warning)] public void StubsAreDeprecated(string arg0) => WriteEvent(134, arg0); @@ -376,7 +376,7 @@ partial class DiagnosticEventSource /// The 'WrongClassName' diagnostic. /// /// -/// Unable to compile "{arg0}" (wrong name: "{arg1}") +/// Warning: Unable to compile "{arg0}" (wrong name: "{arg1}") /// [Event(135, Message = "Unable to compile \"{0}\" (wrong name: \"{1}\")", Level = EventLevel.Warning)] public void WrongClassName(string arg0, string arg1) => WriteEvent(135, arg0, arg1); @@ -385,7 +385,7 @@ partial class DiagnosticEventSource /// The 'ReflectionCallerClassRequiresCallerID' diagnostic. /// /// -/// Reflection.getCallerClass() called from non-CallerID method. ("{arg0}.{arg1}{arg2}") +/// Warning: Reflection.getCallerClass() called from non-CallerID method. ("{arg0}.{arg1}{arg2}") /// [Event(136, Message = "Reflection.getCallerClass() called from non-CallerID method. (\"{0}.{1}{2}\")", Level = EventLevel.Warning)] public void ReflectionCallerClassRequiresCallerID(string arg0, string arg1, string arg2) => WriteEvent(136, arg0, arg1, arg2); @@ -394,7 +394,7 @@ partial class DiagnosticEventSource /// The 'LegacyAssemblyAttributesFound' diagnostic. /// /// -/// Legacy assembly attributes container found. Please use the -assemblyattributes: option. +/// Warning: Legacy assembly attributes container found. Please use the -assemblyattributes: option. /// [Event(137, Message = "Legacy assembly attributes container found. Please use the -assemblyattributes: option.", Level = EventLevel.Warning)] @@ -404,7 +404,7 @@ partial class DiagnosticEventSource /// The 'UnableToCreateLambdaFactory' diagnostic. /// /// -/// Unable to create static lambda factory. +/// Warning: Unable to create static lambda factory. /// [Event(138, Message = "Unable to create static lambda factory.", Level = EventLevel.Warning)] public void UnableToCreateLambdaFactory() => WriteEvent(138); @@ -413,7 +413,7 @@ partial class DiagnosticEventSource /// The 'UnknownWarning' diagnostic. /// /// -/// {arg0} +/// Warning: {arg0} /// [Event(999, Message = "{0}", Level = EventLevel.Warning)] public void UnknownWarning(string arg0) => WriteEvent(999, arg0); @@ -422,7 +422,7 @@ partial class DiagnosticEventSource /// The 'DuplicateIkvmLangProperty' diagnostic. /// /// -/// Ignoring duplicate ikvm.lang.Property annotation on {arg0}.{arg1}. +/// Warning: Ignoring duplicate ikvm.lang.Property annotation on {arg0}.{arg1}. /// [Event(139, Message = "Ignoring duplicate ikvm.lang.Property annotation on {0}.{1}.", Level = EventLevel.Warning)] public void DuplicateIkvmLangProperty(string arg0, string arg1) => WriteEvent(139, arg0, arg1); @@ -431,7 +431,7 @@ partial class DiagnosticEventSource /// The 'MalformedIkvmLangProperty' diagnostic. /// /// -/// Ignoring duplicate ikvm.lang.Property annotation on {arg0}.{arg1}. +/// Warning: Ignoring duplicate ikvm.lang.Property annotation on {arg0}.{arg1}. /// [Event(140, Message = "Ignoring duplicate ikvm.lang.Property annotation on {0}.{1}.", Level = EventLevel.Warning)] public void MalformedIkvmLangProperty(string arg0, string arg1) => WriteEvent(140, arg0, arg1); @@ -440,7 +440,7 @@ partial class DiagnosticEventSource /// The 'GenericCompilerWarning' diagnostic. /// /// -/// {arg0} +/// Warning: {arg0} /// [Event(141, Message = "{0}", Level = EventLevel.Warning)] public void GenericCompilerWarning(string arg0) => WriteEvent(141, arg0); @@ -449,7 +449,7 @@ partial class DiagnosticEventSource /// The 'GenericClassLoadingWarning' diagnostic. /// /// -/// {arg0} +/// Warning: {arg0} /// [Event(142, Message = "{0}", Level = EventLevel.Warning)] public void GenericClassLoadingWarning(string arg0) => WriteEvent(142, arg0); @@ -458,7 +458,7 @@ partial class DiagnosticEventSource /// The 'GenericVerifierWarning' diagnostic. /// /// -/// {arg0} +/// Warning: {arg0} /// [Event(143, Message = "{0}", Level = EventLevel.Warning)] public void GenericVerifierWarning(string arg0) => WriteEvent(143, arg0); @@ -467,7 +467,7 @@ partial class DiagnosticEventSource /// The 'GenericRuntimeWarning' diagnostic. /// /// -/// {arg0} +/// Warning: {arg0} /// [Event(144, Message = "{0}", Level = EventLevel.Warning)] public void GenericRuntimeWarning(string arg0) => WriteEvent(144, arg0); @@ -476,7 +476,7 @@ partial class DiagnosticEventSource /// The 'GenericJniWarning' diagnostic. /// /// -/// {arg0} +/// Warning: {arg0} /// [Event(145, Message = "{0}", Level = EventLevel.Warning)] public void GenericJniWarning(string arg0) => WriteEvent(145, arg0); @@ -485,7 +485,7 @@ partial class DiagnosticEventSource /// The 'UnableToCreateProxy' diagnostic. /// /// -/// Unable to create proxy "{arg0}". ("{arg1}") +/// Error: Unable to create proxy "{arg0}". ("{arg1}") /// [Event(4001, Message = "Unable to create proxy \"{0}\". (\"{1}\")", Level = EventLevel.Error)] public void UnableToCreateProxy(string arg0, string arg1) => WriteEvent(4001, arg0, arg1); @@ -494,7 +494,7 @@ partial class DiagnosticEventSource /// The 'DuplicateProxy' diagnostic. /// /// -/// Duplicate proxy "{arg0}". +/// Error: Duplicate proxy "{arg0}". /// [Event(4002, Message = "Duplicate proxy \"{0}\".", Level = EventLevel.Error)] public void DuplicateProxy(string arg0) => WriteEvent(4002, arg0); @@ -503,7 +503,7 @@ partial class DiagnosticEventSource /// The 'MapXmlUnableToResolveOpCode' diagnostic. /// /// -/// Unable to resolve opcode in remap file: {arg0}. +/// Error: Unable to resolve opcode in remap file: {arg0}. /// [Event(4003, Message = "Unable to resolve opcode in remap file: {0}.", Level = EventLevel.Error)] public void MapXmlUnableToResolveOpCode(string arg0) => WriteEvent(4003, arg0); @@ -512,7 +512,7 @@ partial class DiagnosticEventSource /// The 'MapXmlError' diagnostic. /// /// -/// Error in remap file: {arg0}. +/// Error: Error in remap file: {arg0}. /// [Event(4004, Message = "Error in remap file: {0}.", Level = EventLevel.Error)] public void MapXmlError(string arg0) => WriteEvent(4004, arg0); @@ -521,7 +521,7 @@ partial class DiagnosticEventSource /// The 'InputFileNotFound' diagnostic. /// /// -/// Source file '{arg0}' not found. +/// Error: Source file '{arg0}' not found. /// [Event(4005, Message = "Source file \'{0}\' not found.", Level = EventLevel.Error)] public void InputFileNotFound(string arg0) => WriteEvent(4005, arg0); @@ -530,7 +530,7 @@ partial class DiagnosticEventSource /// The 'UnknownFileType' diagnostic. /// /// -/// Unknown file type: {arg0}. +/// Error: Unknown file type: {arg0}. /// [Event(4006, Message = "Unknown file type: {0}.", Level = EventLevel.Error)] public void UnknownFileType(string arg0) => WriteEvent(4006, arg0); @@ -539,7 +539,7 @@ partial class DiagnosticEventSource /// The 'UnknownElementInMapFile' diagnostic. /// /// -/// Unknown element {arg0} in remap file, line {arg1}, column {arg2}. +/// Error: Unknown element {arg0} in remap file, line {arg1}, column {arg2}. /// [Event(4007, Message = "Unknown element {0} in remap file, line {1}, column {2}.", Level = EventLevel.Error)] public void UnknownElementInMapFile(string arg0, string arg1, string arg2) => WriteEvent(4007, arg0, arg1, arg2); @@ -548,7 +548,7 @@ partial class DiagnosticEventSource /// The 'UnknownAttributeInMapFile' diagnostic. /// /// -/// Unknown attribute {arg0} in remap file, line {arg1}, column {arg2}. +/// Error: Unknown attribute {arg0} in remap file, line {arg1}, column {arg2}. /// [Event(4008, Message = "Unknown attribute {0} in remap file, line {1}, column {2}.", Level = EventLevel.Error)] public void UnknownAttributeInMapFile(string arg0, string arg1, string arg2) => WriteEvent(4008, arg0, arg1, arg2); @@ -557,7 +557,7 @@ partial class DiagnosticEventSource /// The 'InvalidMemberNameInMapFile' diagnostic. /// /// -/// Invalid {arg0} name '{arg1}' in remap file in class {arg2}. +/// Error: Invalid {arg0} name '{arg1}' in remap file in class {arg2}. /// [Event(4009, Message = "Invalid {0} name \'{1}\' in remap file in class {2}.", Level = EventLevel.Error)] public void InvalidMemberNameInMapFile(string arg0, string arg1, string arg2) => WriteEvent(4009, arg0, arg1, arg2); @@ -566,7 +566,7 @@ partial class DiagnosticEventSource /// The 'InvalidMemberSignatureInMapFile' diagnostic. /// /// -/// Invalid {arg0} signature '{arg3}' in remap file for {arg0} {arg1}.{arg2}. +/// Error: Invalid {arg0} signature '{arg3}' in remap file for {arg0} {arg1}.{arg2}. /// [Event(4010, Message = "Invalid {0} signature \'{3}\' in remap file for {0} {1}.{2}.", Level = EventLevel.Error)] public void InvalidMemberSignatureInMapFile(string arg0, string arg1, string arg2, string arg3) => WriteEvent(4010, arg0, arg1, arg2, arg3); @@ -575,7 +575,7 @@ partial class DiagnosticEventSource /// The 'InvalidPropertyNameInMapFile' diagnostic. /// /// -/// Invalid property {arg0} name '{arg3}' in remap file for property {arg1}.{arg2}. +/// Error: Invalid property {arg0} name '{arg3}' in remap file for property {arg1}.{arg2}. /// [Event(4011, Message = "Invalid property {0} name \'{3}\' in remap file for property {1}.{2}.", Level = EventLevel.Error)] public void InvalidPropertyNameInMapFile(string arg0, string arg1, string arg2, string arg3) => WriteEvent(4011, arg0, arg1, arg2, arg3); @@ -584,7 +584,7 @@ partial class DiagnosticEventSource /// The 'InvalidPropertySignatureInMapFile' diagnostic. /// /// -/// Invalid property {arg0} signature '{arg3}' in remap file for property {arg1}.{arg2}. +/// Error: Invalid property {arg0} signature '{arg3}' in remap file for property {arg1}.{arg2}. /// [Event(4012, Message = "Invalid property {0} signature \'{3}\' in remap file for property {1}.{2}.", Level = EventLevel.Error)] public void InvalidPropertySignatureInMapFile(string arg0, string arg1, string arg2, string arg3) => WriteEvent(4012, arg0, arg1, arg2, arg3); @@ -593,7 +593,7 @@ partial class DiagnosticEventSource /// The 'NonPrimaryAssemblyReference' diagnostic. /// /// -/// Referenced assembly "{arg0}" is not the primary assembly of a shared class loader group, please reference primary assembly "{arg1}" instead. +/// Error: Referenced assembly "{arg0}" is not the primary assembly of a shared class loader group, please reference primary assembly "{arg1}" instead. /// [Event(4013, Message = "Referenced assembly \"{0}\" is not the primary assembly of a shared class loader gr" + "oup, please reference primary assembly \"{1}\" instead.", Level = EventLevel.Error)] @@ -603,7 +603,7 @@ partial class DiagnosticEventSource /// The 'MissingType' diagnostic. /// /// -/// Reference to type "{arg0}" claims it is defined in "{arg1}", but it could not be found. +/// Error: Reference to type "{arg0}" claims it is defined in "{arg1}", but it could not be found. /// [Event(4014, Message = "Reference to type \"{0}\" claims it is defined in \"{1}\", but it could not be found." + "", Level = EventLevel.Error)] @@ -613,7 +613,7 @@ partial class DiagnosticEventSource /// The 'MissingReference' diagnostic. /// /// -/// The type '{arg0}' is defined in an assembly that is notResponseFileDepthExceeded referenced. You must add a reference to assembly '{arg1}'. +/// Error: The type '{arg0}' is defined in an assembly that is notResponseFileDepthExceeded referenced. You must add a reference to assembly '{arg1}'. /// [Event(4015, Message = "The type \'{0}\' is defined in an assembly that is notResponseFileDepthExceeded ref" + "erenced. You must add a reference to assembly \'{1}\'.", Level = EventLevel.Error)] @@ -623,7 +623,7 @@ partial class DiagnosticEventSource /// The 'CallerSensitiveOnUnsupportedMethod' diagnostic. /// /// -/// CallerSensitive annotation on unsupported method. ("{arg0}.{arg1}{arg2}") +/// Error: CallerSensitive annotation on unsupported method. ("{arg0}.{arg1}{arg2}") /// [Event(4016, Message = "CallerSensitive annotation on unsupported method. (\"{0}.{1}{2}\")", Level = EventLevel.Error)] public void CallerSensitiveOnUnsupportedMethod(string arg0, string arg1, string arg2) => WriteEvent(4016, arg0, arg1, arg2); @@ -632,7 +632,7 @@ partial class DiagnosticEventSource /// The 'RemappedTypeMissingDefaultInterfaceMethod' diagnostic. /// /// -/// {arg0} does not implement default interface method {arg1}. +/// Error: {arg0} does not implement default interface method {arg1}. /// [Event(4017, Message = "{0} does not implement default interface method {1}.", Level = EventLevel.Error)] public void RemappedTypeMissingDefaultInterfaceMethod(string arg0, string arg1) => WriteEvent(4017, arg0, arg1); @@ -641,7 +641,7 @@ partial class DiagnosticEventSource /// The 'GenericCompilerError' diagnostic. /// /// -/// {arg0} +/// Error: {arg0} /// [Event(4018, Message = "{0}", Level = EventLevel.Error)] public void GenericCompilerError(string arg0) => WriteEvent(4018, arg0); @@ -650,7 +650,7 @@ partial class DiagnosticEventSource /// The 'GenericClassLoadingError' diagnostic. /// /// -/// {arg0} +/// Error: {arg0} /// [Event(4019, Message = "{0}", Level = EventLevel.Error)] public void GenericClassLoadingError(string arg0) => WriteEvent(4019, arg0); @@ -659,7 +659,7 @@ partial class DiagnosticEventSource /// The 'GenericVerifierError' diagnostic. /// /// -/// {arg0} +/// Error: {arg0} /// [Event(4020, Message = "{0}", Level = EventLevel.Error)] public void GenericVerifierError(string arg0) => WriteEvent(4020, arg0); @@ -668,7 +668,7 @@ partial class DiagnosticEventSource /// The 'GenericRuntimeError' diagnostic. /// /// -/// {arg0} +/// Error: {arg0} /// [Event(4021, Message = "{0}", Level = EventLevel.Error)] public void GenericRuntimeError(string arg0) => WriteEvent(4021, arg0); @@ -677,7 +677,7 @@ partial class DiagnosticEventSource /// The 'GenericJniError' diagnostic. /// /// -/// {arg0} +/// Error: {arg0} /// [Event(4022, Message = "{0}", Level = EventLevel.Error)] public void GenericJniError(string arg0) => WriteEvent(4022, arg0); @@ -686,7 +686,7 @@ partial class DiagnosticEventSource /// The 'ExportingImportsNotSupported' diagnostic. /// /// -/// Exporting previously imported assemblies is not supported. +/// Error: Exporting previously imported assemblies is not supported. /// [Event(4023, Message = "Exporting previously imported assemblies is not supported.", Level = EventLevel.Error)] public void ExportingImportsNotSupported() => WriteEvent(4023); @@ -695,7 +695,7 @@ partial class DiagnosticEventSource /// The 'ResponseFileDepthExceeded' diagnostic. /// /// -/// Response file nesting depth exceeded. +/// Fatal: Response file nesting depth exceeded. /// [Event(5000, Message = "Response file nesting depth exceeded.", Level = EventLevel.Critical)] public void ResponseFileDepthExceeded() => WriteEvent(5000); @@ -704,7 +704,7 @@ partial class DiagnosticEventSource /// The 'ErrorReadingFile' diagnostic. /// /// -/// Unable to read file: {arg0}. ({arg1}) +/// Fatal: Unable to read file: {arg0}. ({arg1}) /// [Event(5001, Message = "Unable to read file: {0}. ({1})", Level = EventLevel.Critical)] public void ErrorReadingFile(string arg0, string arg1) => WriteEvent(5001, arg0, arg1); @@ -713,7 +713,7 @@ partial class DiagnosticEventSource /// The 'NoTargetsFound' diagnostic. /// /// -/// No targets found +/// Fatal: No targets found /// [Event(5002, Message = "No targets found", Level = EventLevel.Critical)] public void NoTargetsFound() => WriteEvent(5002); @@ -722,7 +722,7 @@ partial class DiagnosticEventSource /// The 'FileFormatLimitationExceeded' diagnostic. /// /// -/// File format limitation exceeded: {arg0}. +/// Fatal: File format limitation exceeded: {arg0}. /// [Event(5003, Message = "File format limitation exceeded: {0}.", Level = EventLevel.Critical)] public void FileFormatLimitationExceeded(string arg0) => WriteEvent(5003, arg0); @@ -731,7 +731,7 @@ partial class DiagnosticEventSource /// The 'CannotSpecifyBothKeyFileAndContainer' diagnostic. /// /// -/// You cannot specify both a key file and container. +/// Fatal: You cannot specify both a key file and container. /// [Event(5004, Message = "You cannot specify both a key file and container.", Level = EventLevel.Critical)] public void CannotSpecifyBothKeyFileAndContainer() => WriteEvent(5004); @@ -740,7 +740,7 @@ partial class DiagnosticEventSource /// The 'DelaySignRequiresKey' diagnostic. /// /// -/// You cannot delay sign without a key file or container. +/// Fatal: You cannot delay sign without a key file or container. /// [Event(5005, Message = "You cannot delay sign without a key file or container.", Level = EventLevel.Critical)] public void DelaySignRequiresKey() => WriteEvent(5005); @@ -749,7 +749,7 @@ partial class DiagnosticEventSource /// The 'InvalidStrongNameKeyPair' diagnostic. /// /// -/// Invalid key {arg0} specified. ("{arg1}") +/// Fatal: Invalid key {arg0} specified. ("{arg1}") /// [Event(5006, Message = "Invalid key {0} specified. (\"{1}\")", Level = EventLevel.Critical)] public void InvalidStrongNameKeyPair(string arg0, string arg1) => WriteEvent(5006, arg0, arg1); @@ -758,7 +758,7 @@ partial class DiagnosticEventSource /// The 'ReferenceNotFound' diagnostic. /// /// -/// Reference not found: {arg0} +/// Fatal: Reference not found: {arg0} /// [Event(5007, Message = "Reference not found: {0}", Level = EventLevel.Critical)] public void ReferenceNotFound(string arg0) => WriteEvent(5007, arg0); @@ -767,7 +767,7 @@ partial class DiagnosticEventSource /// The 'OptionsMustPreceedChildLevels' diagnostic. /// /// -/// You can only specify options before any child levels. +/// Fatal: You can only specify options before any child levels. /// [Event(5008, Message = "You can only specify options before any child levels.", Level = EventLevel.Critical)] public void OptionsMustPreceedChildLevels() => WriteEvent(5008); @@ -776,7 +776,7 @@ partial class DiagnosticEventSource /// The 'UnrecognizedTargetType' diagnostic. /// /// -/// Invalid value '{arg0}' for -target option. +/// Fatal: Invalid value '{arg0}' for -target option. /// [Event(5009, Message = "Invalid value \'{0}\' for -target option.", Level = EventLevel.Critical)] public void UnrecognizedTargetType(string arg0) => WriteEvent(5009, arg0); @@ -785,7 +785,7 @@ partial class DiagnosticEventSource /// The 'UnrecognizedPlatform' diagnostic. /// /// -/// Invalid value '{arg0}' for -platform option. +/// Fatal: Invalid value '{arg0}' for -platform option. /// [Event(5010, Message = "Invalid value \'{0}\' for -platform option.", Level = EventLevel.Critical)] public void UnrecognizedPlatform(string arg0) => WriteEvent(5010, arg0); @@ -794,7 +794,7 @@ partial class DiagnosticEventSource /// The 'UnrecognizedApartment' diagnostic. /// /// -/// Invalid value '{arg0}' for -apartment option. +/// Fatal: Invalid value '{arg0}' for -apartment option. /// [Event(5011, Message = "Invalid value \'{0}\' for -apartment option.", Level = EventLevel.Critical)] public void UnrecognizedApartment(string arg0) => WriteEvent(5011, arg0); @@ -803,7 +803,7 @@ partial class DiagnosticEventSource /// The 'MissingFileSpecification' diagnostic. /// /// -/// Missing file specification for '{arg0}' option. +/// Fatal: Missing file specification for '{arg0}' option. /// [Event(5012, Message = "Missing file specification for \'{0}\' option.", Level = EventLevel.Critical)] public void MissingFileSpecification(string arg0) => WriteEvent(5012, arg0); @@ -812,7 +812,7 @@ partial class DiagnosticEventSource /// The 'PathTooLong' diagnostic. /// /// -/// Path too long: {arg0}. +/// Fatal: Path too long: {arg0}. /// [Event(5013, Message = "Path too long: {0}.", Level = EventLevel.Critical)] public void PathTooLong(string arg0) => WriteEvent(5013, arg0); @@ -821,7 +821,7 @@ partial class DiagnosticEventSource /// The 'PathNotFound' diagnostic. /// /// -/// Path not found: {arg0}. +/// Fatal: Path not found: {arg0}. /// [Event(5014, Message = "Path not found: {0}.", Level = EventLevel.Critical)] public void PathNotFound(string arg0) => WriteEvent(5014, arg0); @@ -830,7 +830,7 @@ partial class DiagnosticEventSource /// The 'InvalidPath' diagnostic. /// /// -/// Invalid path: {arg0}. +/// Fatal: Invalid path: {arg0}. /// [Event(5015, Message = "Invalid path: {0}.", Level = EventLevel.Critical)] public void InvalidPath(string arg0) => WriteEvent(5015, arg0); @@ -839,7 +839,7 @@ partial class DiagnosticEventSource /// The 'InvalidOptionSyntax' diagnostic. /// /// -/// Invalid option: {arg0}. +/// Fatal: Invalid option: {arg0}. /// [Event(5016, Message = "Invalid option: {0}.", Level = EventLevel.Critical)] public void InvalidOptionSyntax(string arg0) => WriteEvent(5016, arg0); @@ -848,7 +848,7 @@ partial class DiagnosticEventSource /// The 'ExternalResourceNotFound' diagnostic. /// /// -/// External resource file does not exist: {arg0}. +/// Fatal: External resource file does not exist: {arg0}. /// [Event(5017, Message = "External resource file does not exist: {0}.", Level = EventLevel.Critical)] public void ExternalResourceNotFound(string arg0) => WriteEvent(5017, arg0); @@ -857,7 +857,7 @@ partial class DiagnosticEventSource /// The 'ExternalResourceNameInvalid' diagnostic. /// /// -/// External resource file may not include path specification: {arg0}. +/// Fatal: External resource file may not include path specification: {arg0}. /// [Event(5018, Message = "External resource file may not include path specification: {0}.", Level = EventLevel.Critical)] public void ExternalResourceNameInvalid(string arg0) => WriteEvent(5018, arg0); @@ -866,7 +866,7 @@ partial class DiagnosticEventSource /// The 'InvalidVersionFormat' diagnostic. /// /// -/// Invalid version specified: {arg0}. +/// Fatal: Invalid version specified: {arg0}. /// [Event(5019, Message = "Invalid version specified: {0}.", Level = EventLevel.Critical)] public void InvalidVersionFormat(string arg0) => WriteEvent(5019, arg0); @@ -875,7 +875,7 @@ partial class DiagnosticEventSource /// The 'InvalidFileAlignment' diagnostic. /// /// -/// Invalid value '{arg0}' for -filealign option. +/// Fatal: Invalid value '{arg0}' for -filealign option. /// [Event(5020, Message = "Invalid value \'{0}\' for -filealign option.", Level = EventLevel.Critical)] public void InvalidFileAlignment(string arg0) => WriteEvent(5020, arg0); @@ -884,7 +884,7 @@ partial class DiagnosticEventSource /// The 'ErrorWritingFile' diagnostic. /// /// -/// Unable to write file: {arg0}. ({arg1}) +/// Fatal: Unable to write file: {arg0}. ({arg1}) /// [Event(5021, Message = "Unable to write file: {0}. ({1})", Level = EventLevel.Critical)] public void ErrorWritingFile(string arg0, string arg1) => WriteEvent(5021, arg0, arg1); @@ -893,7 +893,7 @@ partial class DiagnosticEventSource /// The 'UnrecognizedOption' diagnostic. /// /// -/// Unrecognized option: {arg0}. +/// Fatal: Unrecognized option: {arg0}. /// [Event(5022, Message = "Unrecognized option: {0}.", Level = EventLevel.Critical)] public void UnrecognizedOption(string arg0) => WriteEvent(5022, arg0); @@ -902,7 +902,7 @@ partial class DiagnosticEventSource /// The 'NoOutputFileSpecified' diagnostic. /// /// -/// No output file specified. +/// Fatal: No output file specified. /// [Event(5023, Message = "No output file specified.", Level = EventLevel.Critical)] public void NoOutputFileSpecified() => WriteEvent(5023); @@ -911,7 +911,7 @@ partial class DiagnosticEventSource /// The 'SharedClassLoaderCannotBeUsedOnModuleTarget' diagnostic. /// /// -/// Incompatible options: -target:module and -sharedclassloader cannot be combined. +/// Fatal: Incompatible options: -target:module and -sharedclassloader cannot be combined. /// [Event(5024, Message = "Incompatible options: -target:module and -sharedclassloader cannot be combined.", Level = EventLevel.Critical)] public void SharedClassLoaderCannotBeUsedOnModuleTarget() => WriteEvent(5024); @@ -920,7 +920,7 @@ partial class DiagnosticEventSource /// The 'RuntimeNotFound' diagnostic. /// /// -/// Unable to load runtime assembly. +/// Fatal: Unable to load runtime assembly. /// [Event(5025, Message = "Unable to load runtime assembly.", Level = EventLevel.Critical)] public void RuntimeNotFound() => WriteEvent(5025); @@ -929,7 +929,7 @@ partial class DiagnosticEventSource /// The 'MainClassRequiresExe' diagnostic. /// /// -/// Main class cannot be specified for library or module. +/// Fatal: Main class cannot be specified for library or module. /// [Event(5026, Message = "Main class cannot be specified for library or module.", Level = EventLevel.Critical)] public void MainClassRequiresExe() => WriteEvent(5026); @@ -938,7 +938,7 @@ partial class DiagnosticEventSource /// The 'ExeRequiresMainClass' diagnostic. /// /// -/// No main method found. +/// Fatal: No main method found. /// [Event(5027, Message = "No main method found.", Level = EventLevel.Critical)] public void ExeRequiresMainClass() => WriteEvent(5027); @@ -947,7 +947,7 @@ partial class DiagnosticEventSource /// The 'PropertiesRequireExe' diagnostic. /// /// -/// Properties cannot be specified for library or module. +/// Fatal: Properties cannot be specified for library or module. /// [Event(5028, Message = "Properties cannot be specified for library or module.", Level = EventLevel.Critical)] public void PropertiesRequireExe() => WriteEvent(5028); @@ -956,7 +956,7 @@ partial class DiagnosticEventSource /// The 'ModuleCannotHaveClassLoader' diagnostic. /// /// -/// Cannot specify assembly class loader for modules. +/// Fatal: Cannot specify assembly class loader for modules. /// [Event(5029, Message = "Cannot specify assembly class loader for modules.", Level = EventLevel.Critical)] public void ModuleCannotHaveClassLoader() => WriteEvent(5029); @@ -965,7 +965,7 @@ partial class DiagnosticEventSource /// The 'ErrorParsingMapFile' diagnostic. /// /// -/// Unable to parse remap file: {arg0}. ({arg1}) +/// Fatal: Unable to parse remap file: {arg0}. ({arg1}) /// [Event(5030, Message = "Unable to parse remap file: {0}. ({1})", Level = EventLevel.Critical)] public void ErrorParsingMapFile(string arg0, string arg1) => WriteEvent(5030, arg0, arg1); @@ -974,7 +974,7 @@ partial class DiagnosticEventSource /// The 'BootstrapClassesMissing' diagnostic. /// /// -/// Bootstrap classes missing and core assembly not found. +/// Fatal: Bootstrap classes missing and core assembly not found. /// [Event(5031, Message = "Bootstrap classes missing and core assembly not found.", Level = EventLevel.Critical)] public void BootstrapClassesMissing() => WriteEvent(5031); @@ -983,7 +983,7 @@ partial class DiagnosticEventSource /// The 'StrongNameRequiresStrongNamedRefs' diagnostic. /// /// -/// All referenced assemblies must be strong named, to be able to sign the output assembly. +/// Fatal: All referenced assemblies must be strong named, to be able to sign the output assembly. /// [Event(5032, Message = "All referenced assemblies must be strong named, to be able to sign the output ass" + "embly.", Level = EventLevel.Critical)] @@ -993,7 +993,7 @@ partial class DiagnosticEventSource /// The 'MainClassNotFound' diagnostic. /// /// -/// Main class not found. +/// Fatal: Main class not found. /// [Event(5033, Message = "Main class not found.", Level = EventLevel.Critical)] public void MainClassNotFound() => WriteEvent(5033); @@ -1002,7 +1002,7 @@ partial class DiagnosticEventSource /// The 'MainMethodNotFound' diagnostic. /// /// -/// Main method not found. +/// Fatal: Main method not found. /// [Event(5034, Message = "Main method not found.", Level = EventLevel.Critical)] public void MainMethodNotFound() => WriteEvent(5034); @@ -1011,7 +1011,7 @@ partial class DiagnosticEventSource /// The 'UnsupportedMainMethod' diagnostic. /// /// -/// Redirected main method not supported. +/// Fatal: Redirected main method not supported. /// [Event(5035, Message = "Redirected main method not supported.", Level = EventLevel.Critical)] public void UnsupportedMainMethod() => WriteEvent(5035); @@ -1020,7 +1020,7 @@ partial class DiagnosticEventSource /// The 'ExternalMainNotAccessible' diagnostic. /// /// -/// External main method must be public and in a public class. +/// Fatal: External main method must be public and in a public class. /// [Event(5036, Message = "External main method must be public and in a public class.", Level = EventLevel.Critical)] public void ExternalMainNotAccessible() => WriteEvent(5036); @@ -1029,7 +1029,7 @@ partial class DiagnosticEventSource /// The 'ClassLoaderNotFound' diagnostic. /// /// -/// Custom assembly class loader class not found. +/// Fatal: Custom assembly class loader class not found. /// [Event(5037, Message = "Custom assembly class loader class not found.", Level = EventLevel.Critical)] public void ClassLoaderNotFound() => WriteEvent(5037); @@ -1038,7 +1038,7 @@ partial class DiagnosticEventSource /// The 'ClassLoaderNotAccessible' diagnostic. /// /// -/// Custom assembly class loader class is not accessible. +/// Fatal: Custom assembly class loader class is not accessible. /// [Event(5038, Message = "Custom assembly class loader class is not accessible.", Level = EventLevel.Critical)] public void ClassLoaderNotAccessible() => WriteEvent(5038); @@ -1047,7 +1047,7 @@ partial class DiagnosticEventSource /// The 'ClassLoaderIsAbstract' diagnostic. /// /// -/// Custom assembly class loader class is abstract. +/// Fatal: Custom assembly class loader class is abstract. /// [Event(5039, Message = "Custom assembly class loader class is abstract.", Level = EventLevel.Critical)] public void ClassLoaderIsAbstract() => WriteEvent(5039); @@ -1056,7 +1056,7 @@ partial class DiagnosticEventSource /// The 'ClassLoaderNotClassLoader' diagnostic. /// /// -/// Custom assembly class loader class does not extend java.lang.ClassLoader. +/// Fatal: Custom assembly class loader class does not extend java.lang.ClassLoader. /// [Event(5040, Message = "Custom assembly class loader class does not extend java.lang.ClassLoader.", Level = EventLevel.Critical)] public void ClassLoaderNotClassLoader() => WriteEvent(5040); @@ -1065,7 +1065,7 @@ partial class DiagnosticEventSource /// The 'ClassLoaderConstructorMissing' diagnostic. /// /// -/// Custom assembly class loader constructor is missing. +/// Fatal: Custom assembly class loader constructor is missing. /// [Event(5041, Message = "Custom assembly class loader constructor is missing.", Level = EventLevel.Critical)] public void ClassLoaderConstructorMissing() => WriteEvent(5041); @@ -1074,7 +1074,7 @@ partial class DiagnosticEventSource /// The 'MapFileTypeNotFound' diagnostic. /// /// -/// Type '{arg0}' referenced in remap file was not found. +/// Fatal: Type '{arg0}' referenced in remap file was not found. /// [Event(5042, Message = "Type \'{0}\' referenced in remap file was not found.", Level = EventLevel.Critical)] public void MapFileTypeNotFound(string arg0) => WriteEvent(5042, arg0); @@ -1083,7 +1083,7 @@ partial class DiagnosticEventSource /// The 'MapFileClassNotFound' diagnostic. /// /// -/// Class '{arg0}' referenced in remap file was not found. +/// Fatal: Class '{arg0}' referenced in remap file was not found. /// [Event(5043, Message = "Class \'{0}\' referenced in remap file was not found.", Level = EventLevel.Critical)] public void MapFileClassNotFound(string arg0) => WriteEvent(5043, arg0); @@ -1092,7 +1092,7 @@ partial class DiagnosticEventSource /// The 'MaximumErrorCountReached' diagnostic. /// /// -/// Maximum error count reached. +/// Fatal: Maximum error count reached. /// [Event(5044, Message = "Maximum error count reached.", Level = EventLevel.Critical)] public void MaximumErrorCountReached() => WriteEvent(5044); @@ -1101,7 +1101,7 @@ partial class DiagnosticEventSource /// The 'LinkageError' diagnostic. /// /// -/// Link error: {arg0} +/// Fatal: Link error: {arg0} /// [Event(5045, Message = "Link error: {0}", Level = EventLevel.Critical)] public void LinkageError(string arg0) => WriteEvent(5045, arg0); @@ -1110,7 +1110,7 @@ partial class DiagnosticEventSource /// The 'RuntimeMismatch' diagnostic. /// /// -/// Referenced assembly {referencedAssemblyPath} was compiled with an incompatible IKVM.Runtime version. Current runtime: {runtimeAssemblyName}. Referenced assembly runtime: {referencedAssemblyName} +/// Fatal: Referenced assembly {referencedAssemblyPath} was compiled with an incompatible IKVM.Runtime version. Current runtime: {runtimeAssemblyName}. Referenced assembly runtime: {referencedAssemblyName} /// [Event(5046, Message = "Referenced assembly {0} was compiled with an incompatible IKVM.Runtime version. C" + "urrent runtime: {1}. Referenced assembly runtime: {2}", Level = EventLevel.Critical)] @@ -1120,7 +1120,7 @@ partial class DiagnosticEventSource /// The 'RuntimeMismatchStrongName' diagnostic. /// /// -/// +/// Fatal: /// [Event(5047, Message = "", Level = EventLevel.Critical)] public void RuntimeMismatchStrongName() => WriteEvent(5047); @@ -1129,7 +1129,7 @@ partial class DiagnosticEventSource /// The 'CoreClassesMissing' diagnostic. /// /// -/// Failed to find core classes in core library. +/// Fatal: Failed to find core classes in core library. /// [Event(5048, Message = "Failed to find core classes in core library.", Level = EventLevel.Critical)] public void CoreClassesMissing() => WriteEvent(5048); @@ -1138,7 +1138,7 @@ partial class DiagnosticEventSource /// The 'CriticalClassNotFound' diagnostic. /// /// -/// Unable to load critical class '{arg0}'. +/// Fatal: Unable to load critical class '{arg0}'. /// [Event(5049, Message = "Unable to load critical class \'{0}\'.", Level = EventLevel.Critical)] public void CriticalClassNotFound(string arg0) => WriteEvent(5049, arg0); @@ -1147,7 +1147,7 @@ partial class DiagnosticEventSource /// The 'AssemblyContainsDuplicateClassNames' diagnostic. /// /// -/// Type '{arg0}' and '{arg1}' both map to the same name '{arg2}'. ({arg3}) +/// Fatal: Type '{arg0}' and '{arg1}' both map to the same name '{arg2}'. ({arg3}) /// [Event(5050, Message = "Type \'{0}\' and \'{1}\' both map to the same name \'{2}\'. ({3})", Level = EventLevel.Critical)] public void AssemblyContainsDuplicateClassNames(string arg0, string arg1, string arg2, string arg3) => WriteEvent(5050, arg0, arg1, arg2, arg3); @@ -1156,7 +1156,7 @@ partial class DiagnosticEventSource /// The 'CallerIDRequiresHasCallerIDAnnotation' diagnostic. /// /// -/// CallerID.getCallerID() requires a HasCallerID annotation. +/// Fatal: CallerID.getCallerID() requires a HasCallerID annotation. /// [Event(5051, Message = "CallerID.getCallerID() requires a HasCallerID annotation.", Level = EventLevel.Critical)] public void CallerIDRequiresHasCallerIDAnnotation() => WriteEvent(5051); @@ -1165,7 +1165,7 @@ partial class DiagnosticEventSource /// The 'UnableToResolveInterface' diagnostic. /// /// -/// Unable to resolve interface '{arg0}' on type '{arg1}'. +/// Fatal: Unable to resolve interface '{arg0}' on type '{arg1}'. /// [Event(5052, Message = "Unable to resolve interface \'{0}\' on type \'{1}\'.", Level = EventLevel.Critical)] public void UnableToResolveInterface(string arg0, string arg1) => WriteEvent(5052, arg0, arg1); @@ -1174,7 +1174,7 @@ partial class DiagnosticEventSource /// The 'MissingBaseType' diagnostic. /// /// -/// The base class or interface '{arg0}' in assembly '{arg1}' referenced by type '{arg2}' in '{arg3}' could not be resolved. +/// Fatal: The base class or interface '{arg0}' in assembly '{arg1}' referenced by type '{arg2}' in '{arg3}' could not be resolved. /// [Event(5053, Message = "The base class or interface \'{0}\' in assembly \'{1}\' referenced by type \'{2}\' in \'" + "{3}\' could not be resolved.", Level = EventLevel.Critical)] @@ -1184,7 +1184,7 @@ partial class DiagnosticEventSource /// The 'MissingBaseTypeReference' diagnostic. /// /// -/// The type '{arg0}' is defined in an assembly that is not referenced. You must add a reference to assembly '{arg1}'. +/// Fatal: The type '{arg0}' is defined in an assembly that is not referenced. You must add a reference to assembly '{arg1}'. /// [Event(5054, Message = "The type \'{0}\' is defined in an assembly that is not referenced. You must add a r" + "eference to assembly \'{1}\'.", Level = EventLevel.Critical)] @@ -1194,7 +1194,7 @@ partial class DiagnosticEventSource /// The 'FileNotFound' diagnostic. /// /// -/// File not found: {arg0}. +/// Fatal: File not found: {arg0}. /// [Event(5055, Message = "File not found: {0}.", Level = EventLevel.Critical)] public void FileNotFound(string arg0) => WriteEvent(5055, arg0); @@ -1203,7 +1203,7 @@ partial class DiagnosticEventSource /// The 'RuntimeMethodMissing' diagnostic. /// /// -/// Runtime method '{arg0}' not found. +/// Fatal: Runtime method '{arg0}' not found. /// [Event(5056, Message = "Runtime method \'{0}\' not found.", Level = EventLevel.Critical)] public void RuntimeMethodMissing(string arg0) => WriteEvent(5056, arg0); @@ -1212,7 +1212,7 @@ partial class DiagnosticEventSource /// The 'MapFileFieldNotFound' diagnostic. /// /// -/// Field '{arg0}' referenced in remap file was not found in class '{arg1}'. +/// Fatal: Field '{arg0}' referenced in remap file was not found in class '{arg1}'. /// [Event(5057, Message = "Field \'{0}\' referenced in remap file was not found in class \'{1}\'.", Level = EventLevel.Critical)] public void MapFileFieldNotFound(string arg0, string arg1) => WriteEvent(5057, arg0, arg1); @@ -1221,7 +1221,7 @@ partial class DiagnosticEventSource /// The 'GhostInterfaceMethodMissing' diagnostic. /// /// -/// Remapped class '{arg0}' does not implement ghost interface method. ({arg1}.{arg2}{arg3}) +/// Fatal: Remapped class '{arg0}' does not implement ghost interface method. ({arg1}.{arg2}{arg3}) /// [Event(5058, Message = "Remapped class \'{0}\' does not implement ghost interface method. ({1}.{2}{3})", Level = EventLevel.Critical)] public void GhostInterfaceMethodMissing(string arg0, string arg1, string arg2, string arg3) => WriteEvent(5058, arg0, arg1, arg2, arg3); @@ -1230,7 +1230,7 @@ partial class DiagnosticEventSource /// The 'ModuleInitializerMethodRequirements' diagnostic. /// /// -/// Method '{arg1}.{arg2}{arg3}' does not meet the requirements of a module initializer. +/// Fatal: Method '{arg1}.{arg2}{arg3}' does not meet the requirements of a module initializer. /// [Event(5059, Message = "Method \'{0}.{1}{2}\' does not meet the requirements of a module initializer.", Level = EventLevel.Critical)] public void ModuleInitializerMethodRequirements(string arg1, string arg2, string arg3) => WriteEvent(5059, arg1, arg2, arg3); @@ -1239,7 +1239,7 @@ partial class DiagnosticEventSource /// The 'InvalidZip' diagnostic. /// /// -/// Invalid zip: {name}. +/// Fatal: Invalid zip: {name}. /// [Event(5060, Message = "Invalid zip: {0}.", Level = EventLevel.Critical)] public void InvalidZip(string name) => WriteEvent(5060, name); @@ -1248,7 +1248,7 @@ partial class DiagnosticEventSource /// The 'CoreAssemblyVersionMismatch' diagnostic. /// /// -/// Unable to load assembly '{0}' as it depends on a higher version of {1} than the one currently loaded. +/// Fatal: Unable to load assembly '{0}' as it depends on a higher version of {1} than the one currently loaded. /// [Event(5061, Message = "Unable to load assembly \'{-1}\' as it depends on a higher version of {-1} than the" + " one currently loaded.", Level = EventLevel.Critical)] @@ -1258,7 +1258,7 @@ partial class DiagnosticEventSource /// The 'GenericRuntimeTrace' diagnostic. /// /// -/// {arg0} +/// Trace: {arg0} /// [Event(6000, Message = "{0}", Level = EventLevel.Verbose)] public void GenericRuntimeTrace(string arg0) => WriteEvent(6000, arg0); @@ -1267,7 +1267,7 @@ partial class DiagnosticEventSource /// The 'GenericJniTrace' diagnostic. /// /// -/// {arg0} +/// Trace: {arg0} /// [Event(6001, Message = "{0}", Level = EventLevel.Verbose)] public void GenericJniTrace(string arg0) => WriteEvent(6001, arg0); @@ -1276,7 +1276,7 @@ partial class DiagnosticEventSource /// The 'GenericCompilerTrace' diagnostic. /// /// -/// {arg0} +/// Trace: {arg0} /// [Event(6002, Message = "{0}", Level = EventLevel.Verbose)] public void GenericCompilerTrace(string arg0) => WriteEvent(6002, arg0); diff --git a/src/IKVM.CoreLib/Diagnostics/Tracing/DiagnosticEventSource.g.tt b/src/IKVM.CoreLib/Diagnostics/Tracing/DiagnosticEventSource.g.tt index 3e266cf33..c689e2f47 100644 --- a/src/IKVM.CoreLib/Diagnostics/Tracing/DiagnosticEventSource.g.tt +++ b/src/IKVM.CoreLib/Diagnostics/Tracing/DiagnosticEventSource.g.tt @@ -61,7 +61,7 @@ foreach (var kvp in DiagnosticFile.Read(Host.ResolvePath(Path.Combine("..", "Dia /// <#= desc #> /// /// -<#= Util.ToCommentString(kvp.Value.Message) #> +<#= Util.ToCommentString(kvp.Value) #> /// [Event(<#= kvp.Value.Id #>, Message = <#= Util.ToStringLiteral(string.Join("", message)) #>, Level = EventLevel.<#= level #>)] public void <#= kvp.Key #>(<#= string.Join(", ", argDecl) #>) => WriteEvent(<#= string.Join(", ", argList) #>); diff --git a/src/IKVM.CoreLib/Symbols/ISymbolResolver.cs b/src/IKVM.CoreLib/Symbols/ISymbolResolver.cs index fab954603..b14842d29 100644 --- a/src/IKVM.CoreLib/Symbols/ISymbolResolver.cs +++ b/src/IKVM.CoreLib/Symbols/ISymbolResolver.cs @@ -7,12 +7,6 @@ interface ISymbolResolver { - /// - /// Gets the known core assembly. - /// - /// - IAssemblySymbol ResolveCoreAssembly(); - /// /// Resolves the named type from the core assembly. /// diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionILGenerator.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionILGenerator.cs index dcfdb68ad..c582d1300 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionILGenerator.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionILGenerator.cs @@ -242,9 +242,7 @@ public void MarkLabel(ILabel loc) /// public void MarkSequencePoint(ISymbolDocumentWriter document, int startLine, int startColumn, int endLine, int endColumn) { -#if NETFRAMEWORK _il.MarkSequencePoint(document, startLine, startColumn, endLine, endColumn); -#endif } /// diff --git a/src/IKVM.Runtime/AttributeHelper.cs b/src/IKVM.Runtime/AttributeHelper.cs index a54bacb1f..09ab28241 100644 --- a/src/IKVM.Runtime/AttributeHelper.cs +++ b/src/IKVM.Runtime/AttributeHelper.cs @@ -152,7 +152,7 @@ class AttributeHelper ITypeSymbol TypeOfConstantPoolAttribute => typeofConstantPoolAttribute ??= context.Resolver.ResolveRuntimeType(typeof(ConstantPoolAttribute).FullName); - ITypeSymbol TypeOfDebuggableAttribute => typeofDebuggableAttribute ??= context.Resolver.ResolveCoreType(typeof(DebuggableAttribute).FullName); + ITypeSymbol TypeOfDebuggableAttribute => typeofDebuggableAttribute ??= context.Resolver.ResolveSystemType(typeof(DebuggableAttribute).FullName); ITypeSymbol TypeOfCustomAssemblyClassLoaderAttribute => typeofCustomAssemblyClassLoaderAttribute ??= context.Resolver.ResolveRuntimeType(typeof(IKVM.Attributes.CustomAssemblyClassLoaderAttribute).FullName); @@ -179,7 +179,7 @@ object ParseValue(RuntimeClassLoader loader, RuntimeJavaType tw, string val) } else if (tw.IsUnloadable) { - throw new FatalCompilerErrorException(DiagnosticEvent.MapFileTypeNotFound(tw.Name)); + throw new DiagnosticEventException(DiagnosticEvent.MapFileTypeNotFound(tw.Name)); } else if (tw.TypeAsTBD.IsEnum) { @@ -374,8 +374,8 @@ ICustomAttributeBuilder GetEditorBrowsableNever() { if (editorBrowsableNever == null) { - var typeofEditorBrowsableAttribute = context.Resolver.ResolveType(typeof(EditorBrowsableAttribute).FullName); - var typeofEditorBrowsableState = context.Resolver.ResolveType(typeof(EditorBrowsableState).FullName); + var typeofEditorBrowsableAttribute = context.Resolver.ResolveSystemType(typeof(EditorBrowsableAttribute).FullName); + var typeofEditorBrowsableState = context.Resolver.ResolveSystemType(typeof(EditorBrowsableState).FullName); var ctor = typeofEditorBrowsableAttribute.GetConstructor([typeofEditorBrowsableState]); editorBrowsableNever = context.Resolver.Symbols.CreateCustomAttribute(ctor, [EditorBrowsableState.Never]); } @@ -385,13 +385,13 @@ ICustomAttributeBuilder GetEditorBrowsableNever() internal void SetCompilerGenerated(ITypeSymbolBuilder tb) { - compilerGeneratedAttribute ??= context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveType(typeof(CompilerGeneratedAttribute).FullName).GetConstructor([]), []); + compilerGeneratedAttribute ??= context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveSystemType(typeof(CompilerGeneratedAttribute).FullName).GetConstructor([]), []); tb.SetCustomAttribute(compilerGeneratedAttribute); } internal void SetCompilerGenerated(IMethodBaseSymbolBuilder mb) { - compilerGeneratedAttribute ??= context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveType(typeof(CompilerGeneratedAttribute).FullName).GetConstructor([]), []); + compilerGeneratedAttribute ??= context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveSystemType(typeof(CompilerGeneratedAttribute).FullName).GetConstructor([]), []); mb.SetCustomAttribute(compilerGeneratedAttribute); } @@ -412,25 +412,25 @@ internal void SetEditorBrowsableNever(IPropertySymbolBuilder pb) internal void SetDeprecatedAttribute(IMethodBaseSymbolBuilder mb) { - deprecatedAttribute ??= context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveCoreType(typeof(ObsoleteAttribute).FullName).GetConstructor([]), []); + deprecatedAttribute ??= context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveSystemType(typeof(ObsoleteAttribute).FullName).GetConstructor([]), []); mb.SetCustomAttribute(deprecatedAttribute); } internal void SetDeprecatedAttribute(ITypeSymbolBuilder tb) { - deprecatedAttribute ??= context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveCoreType(typeof(ObsoleteAttribute).FullName).GetConstructor([]), []); + deprecatedAttribute ??= context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveSystemType(typeof(ObsoleteAttribute).FullName).GetConstructor([]), []); tb.SetCustomAttribute(deprecatedAttribute); } internal void SetDeprecatedAttribute(IFieldSymbolBuilder fb) { - deprecatedAttribute ??= context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveCoreType(typeof(ObsoleteAttribute).FullName).GetConstructor([]), []); + deprecatedAttribute ??= context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveSystemType(typeof(ObsoleteAttribute).FullName).GetConstructor([]), []); fb.SetCustomAttribute(deprecatedAttribute); } internal void SetDeprecatedAttribute(IPropertySymbolBuilder pb) { - deprecatedAttribute ??= context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveCoreType(typeof(ObsoleteAttribute).FullName).GetConstructor([]), []); + deprecatedAttribute ??= context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveSystemType(typeof(ObsoleteAttribute).FullName).GetConstructor([]), []); pb.SetCustomAttribute(deprecatedAttribute); } @@ -438,7 +438,7 @@ internal void SetThrowsAttribute(IMethodBaseSymbolBuilder mb, string[] exception { if (exceptions != null && exceptions.Length != 0) { - throwsAttribute ??= TypeOfThrowsAttribute.GetConstructor([context.Resolver.ResolveCoreType(typeof(string).FullName).MakeArrayType()]); + throwsAttribute ??= TypeOfThrowsAttribute.GetConstructor([context.Types.String.MakeArrayType()]); exceptions = UnicodeUtil.EscapeInvalidSurrogates(exceptions); mb.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(throwsAttribute, [exceptions])); } @@ -548,7 +548,7 @@ internal void SetImplementsAttribute(ITypeSymbolBuilder typeBuilder, RuntimeJava interfaces[i] = UnicodeUtil.EscapeInvalidSurrogates(ifaceWrappers[i].Name); if (implementsAttribute == null) - implementsAttribute = TypeOfImplementsAttribute.GetConstructor([context.Resolver.ResolveCoreType(typeof(string).FullName).MakeArrayType()]); + implementsAttribute = TypeOfImplementsAttribute.GetConstructor([context.Types.String.MakeArrayType()]); typeBuilder.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(implementsAttribute, [interfaces])); } @@ -1024,7 +1024,7 @@ internal AssemblyNameInfo[] GetInternalsVisibleToAttributes(IAssemblySymbol asse foreach (var cad in assembly.GetCustomAttributes()) { - if (cad.Constructor.DeclaringType == context.Resolver.ResolveCoreType(typeof(InternalsVisibleToAttribute).FullName)) + if (cad.Constructor.DeclaringType == context.Resolver.ResolveSystemType(typeof(InternalsVisibleToAttribute).FullName)) { try { diff --git a/src/IKVM.Runtime/BigEndianBinaryReader.cs b/src/IKVM.Runtime/BigEndianBinaryReader.cs index 826c4e215..e58d009cb 100644 --- a/src/IKVM.Runtime/BigEndianBinaryReader.cs +++ b/src/IKVM.Runtime/BigEndianBinaryReader.cs @@ -205,7 +205,7 @@ internal unsafe string ReadString(string classFile, int majorVersion) fixed (byte* p = buf.Slice(pos, len).Span) s = Encoding.ASCII.GetString(p, buf.Length); #else - var s = Encoding.ASCII.GetString(buf.Slice(pos, len).Span); + var s = Encoding.ASCII.GetString(buf.Slice(pos, len).Span); #endif pos += len; return s; diff --git a/src/IKVM.Runtime/BootstrapClassLoader.cs b/src/IKVM.Runtime/BootstrapClassLoader.cs index 758fab374..a5cec2c11 100644 --- a/src/IKVM.Runtime/BootstrapClassLoader.cs +++ b/src/IKVM.Runtime/BootstrapClassLoader.cs @@ -39,7 +39,7 @@ sealed class BootstrapClassLoader : RuntimeAssemblyClassLoader /// Initializes a new instance. /// internal BootstrapClassLoader(RuntimeContext context) : - base(context, context.Resolver.ResolveBaseAssembly(), [typeof(object).Assembly.FullName, typeof(Uri).Assembly.FullName]) + base(context, context.Resolver.GetBaseAssembly(), [typeof(object).Assembly.FullName, typeof(Uri).Assembly.FullName]) { #if FIRST_PASS == false && IMPORTER == false && EXPORTER == false RegisterNativeLibrary(LibJava.Instance.Handle); diff --git a/src/IKVM.Runtime/ByteCodeHelper.cs b/src/IKVM.Runtime/ByteCodeHelper.cs index 337d16c35..07730acea 100644 --- a/src/IKVM.Runtime/ByteCodeHelper.cs +++ b/src/IKVM.Runtime/ByteCodeHelper.cs @@ -630,7 +630,7 @@ private static bool IsPrimitiveArrayType(Type type) #if FIRST_PASS throw new NotImplementedException(); #else - return type.IsArray && IsPrimitiveArrayType(JVM.Context.Resolver.ImportType(type.GetElementType())); + return type.IsArray && IsPrimitiveArrayType(JVM.Context.Resolver.GetSymbol(type.GetElementType())); #endif } @@ -1049,7 +1049,7 @@ public static void InitializeModule(Module module) throw new ArgumentOutOfRangeException(); // check for InitializeModule method present on classloader - var classLoader = JVM.Context.AssemblyClassLoaderFactory.FromAssembly(JVM.Context.Resolver.ImportAssembly(asm)).GetJavaClassLoader(); + var classLoader = JVM.Context.AssemblyClassLoaderFactory.FromAssembly(JVM.Context.Resolver.GetSymbol(asm)).GetJavaClassLoader(); if (classLoader != null) { var init = (Action)Delegate.CreateDelegate(typeof(Action), classLoader, "InitializeModule", false, false); diff --git a/src/IKVM.Runtime/ByteCodeHelperMethods.cs b/src/IKVM.Runtime/ByteCodeHelperMethods.cs index fffd0b72b..583021b74 100644 --- a/src/IKVM.Runtime/ByteCodeHelperMethods.cs +++ b/src/IKVM.Runtime/ByteCodeHelperMethods.cs @@ -172,7 +172,7 @@ static IMethodSymbol GetHelper(ITypeSymbol type, string method, ITypeSymbol[] pa var mi = parameters == null ? type.GetMethod(method) : type.GetMethod(method, parameters); if (mi == null) #if IMPORTER - throw new FatalCompilerErrorException(DiagnosticEvent.RuntimeMethodMissing(method)); + throw new DiagnosticEventException(DiagnosticEvent.RuntimeMethodMissing(method)); #else throw new InternalException("Missing ByteCodeHelper method in runtime."); #endif diff --git a/src/IKVM.Runtime/CodeEmitter.cs b/src/IKVM.Runtime/CodeEmitter.cs index 4f0c6d73e..a74869d2c 100644 --- a/src/IKVM.Runtime/CodeEmitter.cs +++ b/src/IKVM.Runtime/CodeEmitter.cs @@ -61,11 +61,11 @@ public CodeEmitterFactory(RuntimeContext context) public IMethodSymbol VerboseCastFailureMethod => verboseCastFailure ??= JVM.SafeGetEnvironmentVariable("IKVM_VERBOSE_CAST") == null ? null : context.ByteCodeHelperMethods.VerboseCastFailure; - public IMethodSymbol MonitorEnterMethod => monitorEnter ??= context.Resolver.ResolveType(typeof(System.Threading.Monitor).FullName).GetMethod("Enter", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static, [context.Types.Object]); + public IMethodSymbol MonitorEnterMethod => monitorEnter ??= context.Resolver.ResolveSystemType(typeof(System.Threading.Monitor).FullName).GetMethod("Enter", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static, [context.Types.Object]); - public IMethodSymbol MonitorExitMethod => monitorExit ??= context.Resolver.ResolveType(typeof(System.Threading.Monitor).FullName).GetMethod("Exit", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static, [context.Types.Object]); + public IMethodSymbol MonitorExitMethod => monitorExit ??= context.Resolver.ResolveSystemType(typeof(System.Threading.Monitor).FullName).GetMethod("Exit", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static, [context.Types.Object]); - public IMethodSymbol MemoryBarrierMethod => memoryBarrier ??= context.Resolver.ResolveType(typeof(System.Threading.Thread).FullName).GetMethod("MemoryBarrier", []); + public IMethodSymbol MemoryBarrierMethod => memoryBarrier ??= context.Resolver.ResolveSystemType(typeof(System.Threading.Thread).FullName).GetMethod("MemoryBarrier", []); public bool ExperimentalOptimizations = JVM.SafeGetEnvironmentVariable("IKVM_EXPERIMENTAL_OPTIMIZATIONS") != null; diff --git a/src/IKVM.Runtime/DynamicCallerIDProvider.cs b/src/IKVM.Runtime/DynamicCallerIDProvider.cs index a1ead5290..41b9eb635 100644 --- a/src/IKVM.Runtime/DynamicCallerIDProvider.cs +++ b/src/IKVM.Runtime/DynamicCallerIDProvider.cs @@ -36,7 +36,10 @@ sealed class DynamicCallerIDProvider // method to be public without giving untrusted code the ability to forge a CallerID token internal static readonly DynamicCallerIDProvider Instance = new DynamicCallerIDProvider(); - private DynamicCallerIDProvider() { } + private DynamicCallerIDProvider() + { + + } internal ikvm.@internal.CallerID GetCallerID() { @@ -56,7 +59,7 @@ internal ikvm.@internal.CallerID GetCallerID() continue; } - var caller = JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(method.DeclaringType); + var caller = JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(JVM.Context.Resolver.GetSymbol(method.DeclaringType)); return CreateCallerID(caller.Host ?? caller); } #endif diff --git a/src/IKVM.Runtime/ExceptionHelper.cs b/src/IKVM.Runtime/ExceptionHelper.cs index 20ab5b79a..0cbf5dc62 100644 --- a/src/IKVM.Runtime/ExceptionHelper.cs +++ b/src/IKVM.Runtime/ExceptionHelper.cs @@ -381,7 +381,7 @@ int GetLineNumber(StackFrame frame) var mb = frame.GetMethod(); if (mb != null && mb.DeclaringType != null) { - var mbs = context.Resolver.ImportMethodBase(mb); + var mbs = context.Resolver.GetSymbol(mb); if (context.ClassLoaderFactory.IsRemappedType(mbs.DeclaringType)) return -1; @@ -399,7 +399,7 @@ string GetFileName(StackFrame frame) var mb = frame.GetMethod(); if (mb != null && mb.DeclaringType != null) { - var mbs = context.Resolver.ImportMethodBase(mb); + var mbs = context.Resolver.GetSymbol(mb); if (context.ClassLoaderFactory.IsRemappedType(mbs.DeclaringType)) return null; diff --git a/src/IKVM.Runtime/GhostTag.cs b/src/IKVM.Runtime/GhostTag.cs index 8bf1e289a..c79e706c1 100644 --- a/src/IKVM.Runtime/GhostTag.cs +++ b/src/IKVM.Runtime/GhostTag.cs @@ -40,7 +40,7 @@ internal static void SetTag(object obj, RuntimeTypeHandle typeHandle) #if FIRST_PASS || IMPORTER throw new NotImplementedException(); #else - SetTag(obj, JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(Type.GetTypeFromHandle(typeHandle))); + SetTag(obj, JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(JVM.Context.Resolver.GetSymbol(Type.GetTypeFromHandle(typeHandle)))); #endif } @@ -74,7 +74,7 @@ internal static bool IsGhostArrayInstance(object obj, RuntimeTypeHandle typeHand var tw1 = GhostTag.GetTag(obj); if (tw1 != null) { - var tw2 = tw1.Context.ClassLoaderFactory.GetJavaTypeFromType(Type.GetTypeFromHandle(typeHandle)).MakeArrayType(rank); + var tw2 = tw1.Context.ClassLoaderFactory.GetJavaTypeFromType(JVM.Context.Resolver.GetSymbol(Type.GetTypeFromHandle(typeHandle))).MakeArrayType(rank); return tw1.IsAssignableTo(tw2); } diff --git a/src/IKVM.Runtime/IRuntimeSymbolResolver.cs b/src/IKVM.Runtime/IRuntimeSymbolResolver.cs index c3ae1c176..7a5874bc9 100644 --- a/src/IKVM.Runtime/IRuntimeSymbolResolver.cs +++ b/src/IKVM.Runtime/IRuntimeSymbolResolver.cs @@ -29,94 +29,122 @@ interface IRuntimeSymbolResolver : ISymbolResolver /// ISymbolContext Symbols { get; } + /// + /// Resolves the named type from any of the known System assemblies. + /// + /// + /// + ITypeSymbol? ResolveSystemType(string typeName); + /// /// Gets the known runtime assembly. /// /// - IAssemblySymbol ResolveRuntimeAssembly(); + IAssemblySymbol? GetRuntimeAssembly(); /// /// Resolves the named type from the IKVM runtime assembly. /// /// /// - ITypeSymbol ResolveRuntimeType(string typeName); + ITypeSymbol? ResolveRuntimeType(string typeName); /// /// Resolves the known Java base assembly. /// /// - IAssemblySymbol ResolveBaseAssembly(); + IAssemblySymbol? GetBaseAssembly(); /// /// Resolves the named type from the IKVM Java assembly. /// /// /// - ITypeSymbol ResolveBaseType(string typeName); + ITypeSymbol? ResolveBaseType(string typeName); /// /// Gets the associated with the specified assembly. /// /// /// - IAssemblySymbol ImportAssembly(Assembly assembly); + IAssemblySymbol GetSymbol(Assembly assembly); /// /// Gets the associated with the specified assembly. /// /// /// - IAssemblySymbolBuilder?ImportAssembly(AssemblyBuilder assembly); + IAssemblySymbolBuilder GetSymbol(AssemblyBuilder assembly); /// /// Gets the associated with the specified module. /// /// /// - IModuleSymbol ImportModule(Module module); + IModuleSymbol GetSymbol(Module module); /// /// Gets the associated with the specified module. /// /// /// - IModuleSymbolBuilder ImportModule(ModuleBuilder module); + IModuleSymbolBuilder GetSymbol(ModuleBuilder module); /// - /// Gets the associated with the specified type. + /// Gets the associated with the specified member. /// - /// + /// /// - ITypeSymbol ImportType(Type type); + IMemberSymbol GetSymbol(MemberInfo memberInfo); /// - /// Gets the associated with the specified member. + /// Gets the associated with the specified type. /// - /// + /// /// - IMemberSymbol ImportMember(MemberInfo memberInfo); + ITypeSymbol GetSymbol(Type type); /// /// Gets the associated with the specified method. /// /// /// - IMethodBaseSymbol ImportMethodBase(MethodBase type); + IMethodBaseSymbol GetSymbol(MethodBase type); /// - /// Gets the associated with the specified method. + /// Gets the associated with the specified constructor. /// /// /// - IConstructorSymbol ImportConstructor(ConstructorInfo ctor); + IConstructorSymbol GetSymbol(ConstructorInfo ctor); /// /// Gets the associated with the specified method. /// /// /// - IMethodSymbol ImportMethod(MethodInfo method); + IMethodSymbol GetSymbol(MethodInfo method); + + /// + /// Gets the associated with the specified field. + /// + /// + /// + IFieldSymbol GetSymbol(FieldInfo field); + + /// + /// Gets the associated with the specified property. + /// + /// + /// + IPropertySymbol GetSymbol(PropertyInfo property); + + /// + /// Gets the associated with the specified event. + /// + /// + /// + IEventSymbol GetSymbol(EventInfo @event); } diff --git a/src/IKVM.Runtime/JNI/JNIEnv.cs b/src/IKVM.Runtime/JNI/JNIEnv.cs index 51a0c46f1..6daad51be 100644 --- a/src/IKVM.Runtime/JNI/JNIEnv.cs +++ b/src/IKVM.Runtime/JNI/JNIEnv.cs @@ -628,9 +628,9 @@ static nint AllocObjectImpl(JNIEnv* pEnv, RuntimeJavaType wrapper) wrapper.Finish(); #if NETFRAMEWORK - return pEnv->MakeLocalRef(FormatterServices.GetUninitializedObject(wrapper.TypeAsBaseType)); + return pEnv->MakeLocalRef(FormatterServices.GetUninitializedObject(wrapper.TypeAsBaseType.AsReflection())); #else - return pEnv->MakeLocalRef(RuntimeHelpers.GetUninitializedObject(wrapper.TypeAsBaseType)); + return pEnv->MakeLocalRef(RuntimeHelpers.GetUninitializedObject(wrapper.TypeAsBaseType.AsReflection())); #endif } catch (RetargetableJavaException e) @@ -709,7 +709,7 @@ static object InvokeHelper(JNIEnv* pEnv, nint objHandle, nint methodID, JValue* // possible with remapped types throw new NotSupportedException($"Remapped type {mw.DeclaringType.Name} doesn't support constructor invocation on an existing instance"); } - else if (!mb.DeclaringType.IsInstanceOfType(obj)) + else if (!mb.DeclaringType.AsReflection().IsInstanceOfType(obj)) { // we're trying to initialize an existing instance of a remapped type throw new NotSupportedException($"Unable to partially construct object of type {obj.GetType().FullName} to type {mb.DeclaringType.FullName}"); @@ -734,10 +734,10 @@ static object InvokeNonVirtual(JNIEnvContext env, RuntimeJavaMethod mw, object o if (mw.HasCallerID || mw.IsDynamicOnly) throw new NotSupportedException(); - if (mw.DeclaringType.IsRemapped && !mw.DeclaringType.TypeAsBaseType.IsInstanceOfType(obj)) + if (mw.DeclaringType.IsRemapped && !mw.DeclaringType.TypeAsBaseType.AsReflection().IsInstanceOfType(obj)) return mw.InvokeNonvirtualRemapped(obj, argarray); - var del = (Delegate)Activator.CreateInstance(mw.GetDelegateType(), new object[] { obj, mw.GetMethod().MethodHandle.GetFunctionPointer() }); + var del = (Delegate)Activator.CreateInstance(mw.GetDelegateType().AsReflection(), [obj, mw.GetMethod().AsReflection().MethodHandle.GetFunctionPointer()]); try { return del.DynamicInvoke(argarray); @@ -2157,7 +2157,7 @@ internal static nint NewObjectArray(JNIEnv* pEnv, jsize len, nint clazz, nint in try { // we want to support (non-primitive) value types so we can't cast to object[] - var a = Array.CreateInstance(RuntimeJavaType.FromClass((java.lang.Class)pEnv->UnwrapRef(clazz)).TypeAsArrayType, len); + var a = Array.CreateInstance(RuntimeJavaType.FromClass((java.lang.Class)pEnv->UnwrapRef(clazz)).TypeAsArrayType.AsReflection(), len); var o = pEnv->UnwrapRef(init); if (o != null) for (int i = 0; i < a.Length; i++) @@ -2776,7 +2776,7 @@ internal static jint RegisterNatives(JNIEnv* pEnv, nint clazz, JNINativeMethod* // don't allow dotted names! if (methodSig.IndexOf('.') < 0) - fi = wrapper.TypeAsTBD.GetField(METHOD_PTR_FIELD_PREFIX + methodName + methodSig, BindingFlags.Static | BindingFlags.NonPublic); + fi = wrapper.TypeAsTBD.GetField(METHOD_PTR_FIELD_PREFIX + methodName + methodSig, BindingFlags.Static | BindingFlags.NonPublic).AsReflection(); if (fi == null) { diff --git a/src/IKVM.Runtime/JVM.Internal.cs b/src/IKVM.Runtime/JVM.Internal.cs index 4d8c83ea9..543cf847f 100644 --- a/src/IKVM.Runtime/JVM.Internal.cs +++ b/src/IKVM.Runtime/JVM.Internal.cs @@ -5,16 +5,6 @@ using IKVM.Runtime.Accessors.Java.Lang; using IKVM.Runtime.Vfs; -#if IMPORTER || EXPORTER -using IKVM.Reflection; -using Type = IKVM.Reflection.Type; -#else -#endif - -#if IMPORTER -using IKVM.Tools.Importer; -#endif - namespace IKVM.Runtime { @@ -34,8 +24,12 @@ internal static class Internal #if FIRST_PASS == false && IMPORTER == false && EXPORTER == false - internal static readonly RuntimeContextOptions contextOptions = new RuntimeContextOptions(); - internal static readonly RuntimeContext context = new RuntimeContext(contextOptions, DiagnosticEventSource.Instance, new Resolver(), false); +#if NETFRAMEWORK + internal static readonly RuntimeContextOptions contextOptions = new RuntimeContextOptions(dynamicAssemblySuffixAndPublicKey: RuntimeContextOptions.SignedDefaultDynamicAssemblySuffixAndPublicKey); +#else + internal static readonly RuntimeContextOptions contextOptions = new RuntimeContextOptions(dynamicAssemblySuffixAndPublicKey: RuntimeContextOptions.UnsignedDefaultDynamicAssemblySuffixAndPublicKey); +#endif + internal static readonly RuntimeContext context = new RuntimeContext(contextOptions, DiagnosticEventSource.Instance, new Resolver()); internal static readonly VfsTable vfs = VfsTable.BuildDefaultTable(new VfsRuntimeContext(context), Properties.HomePath); internal static readonly Lazy systemThreadGroup = new Lazy(() => ThreadGroupAccessor.Init()); internal static readonly Lazy mainThreadGroup = new Lazy(() => ThreadGroupAccessor.Init(null, SystemThreadGroup, "main")); @@ -44,7 +38,7 @@ internal static class Internal static ThreadGroupAccessor threadGroupAccessor; static SystemAccessor systemAccessor; - internal static AccessorCache BaseAccessors => AccessorCache.Get(ref baseAccessors, context.Resolver.ResolveBaseAssembly().AsReflection()); + internal static AccessorCache BaseAccessors => AccessorCache.Get(ref baseAccessors, context.Resolver.GetBaseAssembly().AsReflection()); internal static ThreadGroupAccessor ThreadGroupAccessor => BaseAccessors.Get(ref threadGroupAccessor); diff --git a/src/IKVM.Runtime/JVM.Properties.cs b/src/IKVM.Runtime/JVM.Properties.cs index b33ea8db2..c026416ed 100644 --- a/src/IKVM.Runtime/JVM.Properties.cs +++ b/src/IKVM.Runtime/JVM.Properties.cs @@ -259,7 +259,7 @@ static void InitSystemProperties(Dictionary p) p["java.ext.dirs"] = Path.Combine(HomePath, "lib", "ext"); p["java.endorsed.dirs"] = Path.Combine(HomePath, "lib", "endorsed"); p["sun.boot.library.path"] = GetBootLibraryPath(); - p["sun.boot.class.path"] = VfsTable.GetAssemblyClassesPath(Vfs.Context, Context.Resolver.ResolveBaseAssembly().AsReflection(), HomePath); + p["sun.boot.class.path"] = VfsTable.GetAssemblyClassesPath(Vfs.Context, Context.Resolver.GetBaseAssembly().AsReflection(), HomePath); p["sun.cds.enableSharedLookupCache"] = "false"; // unlimited direct memory diff --git a/src/IKVM.Runtime/JVM.Resolver.cs b/src/IKVM.Runtime/JVM.Resolver.cs index 6174d0a9c..188121ae7 100644 --- a/src/IKVM.Runtime/JVM.Resolver.cs +++ b/src/IKVM.Runtime/JVM.Resolver.cs @@ -4,15 +4,13 @@ using System.ComponentModel; using System.Linq; using System.Reflection; +using System.Reflection.Emit; using System.Runtime.CompilerServices; using IKVM.CoreLib.Symbols; +using IKVM.CoreLib.Symbols.Emit; using IKVM.CoreLib.Symbols.Reflection; -#if IMPORTER || EXPORTER -using Type = IKVM.Reflection.Type; -#endif - namespace IKVM.Runtime { @@ -31,7 +29,7 @@ internal class Resolver : IRuntimeSymbolResolver /// Gets the set of assemblies from which to load core types. /// /// - static IEnumerable GetCoreAssemblies() + static IEnumerable GetSystemAssemblies() { yield return typeof(object).Assembly; yield return typeof(RuntimeCompatibilityAttribute).Assembly; @@ -43,58 +41,206 @@ static IEnumerable GetCoreAssemblies() yield return typeof(Environment).Assembly; } - readonly static Assembly[] coreAssemblies = GetCoreAssemblies().Distinct().ToArray(); + readonly ReflectionSymbolContext _symbols = new(); + + IAssemblySymbol _coreAssembly; + readonly ConcurrentDictionary _coreTypeCache = new(); - readonly ReflectionSymbolContext _context = new(); - readonly IAssemblySymbol[] _coreAssemblies; - readonly ConcurrentDictionary _typeCache = new(); + IAssemblySymbol[] _systemAssemblies; + readonly ConcurrentDictionary _systemTypeCache = new(); + + IAssemblySymbol _runtimeAssembly; + readonly ConcurrentDictionary _runtimeTypeCache = new(); + + IAssemblySymbol _baseAssembly; + readonly ConcurrentDictionary _baseTypeCache = new(); /// /// Initializes a new instance. /// public Resolver() { - _coreAssemblies = coreAssemblies.Select(_context.GetOrCreateAssemblySymbol).ToArray(); + _systemAssemblies = GetSystemAssemblies().Distinct().ToArray().Select(GetSymbol).ToArray(); + _runtimeAssembly = GetSymbol(typeof(JVM).Assembly); } + /// + public ISymbolContext Symbols => _symbols; + /// public IAssemblySymbol ResolveAssembly(string assemblyName) { - return Assembly.Load(assemblyName) is { } a ? _context.GetOrCreateAssemblySymbol(a) : null; + return GetSymbol(Assembly.Load(assemblyName)); } /// - public IAssemblySymbol ResolveBaseAssembly() + public IAssemblySymbol GetCoreAssembly() { - return _context.GetOrCreateAssemblySymbol(typeof(java.lang.Object).Assembly); + return _coreAssembly ??= GetSymbol(typeof(object).Assembly); } /// public ITypeSymbol ResolveCoreType(string typeName) { - return _typeCache.GetOrAdd(typeName, ResolveCoreTypeImpl); + return _coreTypeCache.GetOrAdd(typeName, ResolveCoreTypeImpl); } + /// + /// Resolves the specified core type. + /// + /// + /// ITypeSymbol ResolveCoreTypeImpl(string typeName) { - // loop over core assemblies searching for type - foreach (var assembly in _coreAssemblies) + return _coreAssembly.GetType(typeName); + } + + /// + public ITypeSymbol ResolveSystemType(string typeName) + { + return _systemTypeCache.GetOrAdd(typeName, ResolveSystemTypeImpl); + } + + /// + /// Resolves the specified system type. + /// + /// + /// + ITypeSymbol ResolveSystemTypeImpl(string typeName) + { + foreach (var assembly in _systemAssemblies) if (assembly.GetType(typeName) is ITypeSymbol t) return t; return null; } + /// + public IAssemblySymbol GetRuntimeAssembly() + { + return _runtimeAssembly; + } + /// public ITypeSymbol ResolveRuntimeType(string typeName) { - return typeof(Resolver).Assembly.GetType(typeName) is { } t ? _context.GetOrCreateTypeSymbol(t) : null; + return _runtimeTypeCache.GetOrAdd(typeName, ResolveRuntimeTypeImpl); + } + + /// + /// Resolves the specified system type. + /// + /// + /// + ITypeSymbol ResolveRuntimeTypeImpl(string typeName) + { + return _runtimeAssembly.GetType(typeName); + } + + /// + public IAssemblySymbol GetBaseAssembly() + { + return _baseAssembly; + } + + /// + public ITypeSymbol ResolveBaseType(string typeName) + { + return _baseAssembly.GetType(typeName); + } + + /// + public ITypeSymbol ResolveType(string typeName) + { + foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) + if (assembly.GetType(typeName) is Type t) + return GetSymbol(t); + + return null; + } + + /// + public IAssemblySymbol GetSymbol(Assembly assembly) + { + return _symbols.GetOrCreateAssemblySymbol(assembly); + } + + /// + public IAssemblySymbolBuilder GetSymbol(AssemblyBuilder assembly) + { + return _symbols.GetOrCreateAssemblySymbol(assembly); + } + + /// + public IModuleSymbol GetSymbol(Module module) + { + return _symbols.GetOrCreateModuleSymbol(module); + } + + /// + public IModuleSymbolBuilder GetSymbol(ModuleBuilder module) + { + return _symbols.GetOrCreateModuleSymbol(module); + } + + /// + public ITypeSymbol GetSymbol(Type type) + { + return _symbols.GetOrCreateTypeSymbol(type); + } + + /// + public IMemberSymbol GetSymbol(MemberInfo member) + { + return member switch + { + MethodBase method => GetSymbol(method), + FieldInfo field => GetSymbol(field), + PropertyInfo property => GetSymbol(property), + EventInfo @event => GetSymbol(@event), + _ => throw new InvalidOperationException(), + }; + } + + /// + public IMethodBaseSymbol GetSymbol(MethodBase method) + { + return method switch + { + ConstructorInfo ctor => GetSymbol(ctor), + MethodInfo mi => GetSymbol(mi), + _ => throw new InvalidOperationException(), + }; + } + + /// + public IConstructorSymbol GetSymbol(ConstructorInfo ctor) + { + return _symbols.GetOrCreateConstructorSymbol(ctor); + } + + /// + public IMethodSymbol GetSymbol(MethodInfo method) + { + return _symbols.GetOrCreateMethodSymbol(method); + } + + /// + public IFieldSymbol GetSymbol(FieldInfo field) + { + return _symbols.GetOrCreateFieldSymbol(field); + } + + /// + public IPropertySymbol GetSymbol(PropertyInfo property) + { + return _symbols.GetOrCreatePropertySymbol(property); } /// - public ITypeSymbol ImportType(Type type) + public IEventSymbol GetSymbol(EventInfo @event) { - return type is { } t ? _context.GetOrCreateTypeSymbol(t) : null; + return _symbols.GetOrCreateEventSymbol(@event); } } diff --git a/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Util.cs b/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Util.cs index b8735c4d1..6dc9ffc64 100644 --- a/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Util.cs +++ b/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Util.cs @@ -50,7 +50,7 @@ internal static RuntimeJavaType GetTypeWrapperFromObject(RuntimeContext context, return ghostType; var t = o.GetType(); - var ts = context.Resolver.ImportType(t); + var ts = context.Resolver.GetSymbol(t); if (t.IsPrimitive || context.ClassLoaderFactory.IsRemappedType(ts) && !ts.IsSealed) return context.ManagedJavaTypeFactory.GetJavaTypeFromManagedType(ts); @@ -73,7 +73,7 @@ internal static RuntimeJavaType GetTypeWrapperFromObject(RuntimeContext context, throw new NotImplementedException(); #else var t = Type.GetTypeFromHandle(handle); - var ts = JVM.Context.Resolver.ImportType(t); + var ts = JVM.Context.Resolver.GetSymbol(t); if (t.IsPrimitive || JVM.Context.ClassLoaderFactory.IsRemappedType(ts) || t == typeof(void)) return JVM.Context.ManagedJavaTypeFactory.GetJavaTypeFromManagedType(ts).ClassObject; @@ -94,7 +94,7 @@ internal static RuntimeJavaType GetTypeWrapperFromObject(RuntimeContext context, throw new NotImplementedException(); #else var t = Type.GetTypeFromHandle(handle); - var ts = JVM.Context.Resolver.ImportType(t); + var ts = JVM.Context.Resolver.GetSymbol(t); if (ts.IsPrimitive || JVM.Context.ClassLoaderFactory.IsRemappedType(ts) || ts == typeof(void)) return JVM.Context.ManagedJavaTypeFactory.GetJavaTypeFromManagedType(ts).MakeArrayType(rank).ClassObject; @@ -114,7 +114,7 @@ internal static RuntimeJavaType GetTypeWrapperFromObject(RuntimeContext context, #if FIRST_PASS throw new NotImplementedException(); #else - var ts = JVM.Context.Resolver.ImportType(type); + var ts = JVM.Context.Resolver.GetSymbol(type); int rank = 0; while (ReflectUtil.IsVector(ts)) diff --git a/src/IKVM.Runtime/Java/Externs/java/io/ObjectStreamClass.cs b/src/IKVM.Runtime/Java/Externs/java/io/ObjectStreamClass.cs index 22ba98761..abe35f952 100644 --- a/src/IKVM.Runtime/Java/Externs/java/io/ObjectStreamClass.cs +++ b/src/IKVM.Runtime/Java/Externs/java/io/ObjectStreamClass.cs @@ -21,9 +21,9 @@ Jeroen Frijters jeroen@frijters.net */ -using System; -using System.Reflection; using IKVM.Runtime; +using IKVM.CoreLib.Symbols; + #if !NO_REF_EMIT using System.Reflection.Emit; @@ -177,41 +177,46 @@ public static bool hasStaticInitializer(global::java.lang.Class cl) #if !FIRST_PASS && !NO_REF_EMIT - private sealed class FastFieldReflector : global::ikvm.@internal.FieldReflectorBase + sealed class FastFieldReflector : global::ikvm.@internal.FieldReflectorBase { - private static readonly MethodInfo ReadByteMethod = typeof(IOHelpers).GetMethod("ReadByte"); - private static readonly MethodInfo ReadBooleanMethod = typeof(IOHelpers).GetMethod("ReadBoolean"); - private static readonly MethodInfo ReadCharMethod = typeof(IOHelpers).GetMethod("ReadChar"); - private static readonly MethodInfo ReadShortMethod = typeof(IOHelpers).GetMethod("ReadShort"); - private static readonly MethodInfo ReadIntMethod = typeof(IOHelpers).GetMethod("ReadInt"); - private static readonly MethodInfo ReadFloatMethod = typeof(IOHelpers).GetMethod("ReadFloat"); - private static readonly MethodInfo ReadLongMethod = typeof(IOHelpers).GetMethod("ReadLong"); - private static readonly MethodInfo ReadDoubleMethod = typeof(IOHelpers).GetMethod("ReadDouble"); - private static readonly MethodInfo WriteByteMethod = typeof(IOHelpers).GetMethod("WriteByte"); - private static readonly MethodInfo WriteBooleanMethod = typeof(IOHelpers).GetMethod("WriteBoolean"); - private static readonly MethodInfo WriteCharMethod = typeof(IOHelpers).GetMethod("WriteChar"); - private static readonly MethodInfo WriteShortMethod = typeof(IOHelpers).GetMethod("WriteShort"); - private static readonly MethodInfo WriteIntMethod = typeof(IOHelpers).GetMethod("WriteInt"); - private static readonly MethodInfo WriteFloatMethod = typeof(IOHelpers).GetMethod("WriteFloat"); - private static readonly MethodInfo WriteLongMethod = typeof(IOHelpers).GetMethod("WriteLong"); - private static readonly MethodInfo WriteDoubleMethod = typeof(IOHelpers).GetMethod("WriteDouble"); - private delegate void ObjFieldGetterSetter(object obj, object[] objarr); - private delegate void PrimFieldGetterSetter(object obj, byte[] objarr); - private static readonly ObjFieldGetterSetter objDummy = new ObjFieldGetterSetter(Dummy); - private static readonly PrimFieldGetterSetter primDummy = new PrimFieldGetterSetter(Dummy); - private global::java.io.ObjectStreamField[] fields; - private ObjFieldGetterSetter objFieldGetter; - private PrimFieldGetterSetter primFieldGetter; - private ObjFieldGetterSetter objFieldSetter; - private PrimFieldGetterSetter primFieldSetter; - - private static void Dummy(object obj, object[] objarr) + delegate void ObjFieldGetterSetter(object obj, object[] objarr); + delegate void PrimFieldGetterSetter(object obj, byte[] objarr); + + static readonly IMethodSymbol ReadByteMethod = JVM.Context.Resolver.GetSymbol(typeof(IOHelpers).GetMethod("ReadByte")); + static readonly IMethodSymbol ReadBooleanMethod = JVM.Context.Resolver.GetSymbol(typeof(IOHelpers).GetMethod("ReadBoolean")); + static readonly IMethodSymbol ReadCharMethod = JVM.Context.Resolver.GetSymbol(typeof(IOHelpers).GetMethod("ReadChar")); + static readonly IMethodSymbol ReadShortMethod = JVM.Context.Resolver.GetSymbol(typeof(IOHelpers).GetMethod("ReadShort")); + static readonly IMethodSymbol ReadIntMethod = JVM.Context.Resolver.GetSymbol(typeof(IOHelpers).GetMethod("ReadInt")); + static readonly IMethodSymbol ReadFloatMethod = JVM.Context.Resolver.GetSymbol(typeof(IOHelpers).GetMethod("ReadFloat")); + static readonly IMethodSymbol ReadLongMethod = JVM.Context.Resolver.GetSymbol(typeof(IOHelpers).GetMethod("ReadLong")); + static readonly IMethodSymbol ReadDoubleMethod = JVM.Context.Resolver.GetSymbol(typeof(IOHelpers).GetMethod("ReadDouble")); + static readonly IMethodSymbol WriteByteMethod = JVM.Context.Resolver.GetSymbol(typeof(IOHelpers).GetMethod("WriteByte")); + static readonly IMethodSymbol WriteBooleanMethod = JVM.Context.Resolver.GetSymbol(typeof(IOHelpers).GetMethod("WriteBoolean")); + static readonly IMethodSymbol WriteCharMethod = JVM.Context.Resolver.GetSymbol(typeof(IOHelpers).GetMethod("WriteChar")); + static readonly IMethodSymbol WriteShortMethod = JVM.Context.Resolver.GetSymbol(typeof(IOHelpers).GetMethod("WriteShort")); + static readonly IMethodSymbol WriteIntMethod = JVM.Context.Resolver.GetSymbol(typeof(IOHelpers).GetMethod("WriteInt")); + static readonly IMethodSymbol WriteFloatMethod = JVM.Context.Resolver.GetSymbol(typeof(IOHelpers).GetMethod("WriteFloat")); + static readonly IMethodSymbol WriteLongMethod = JVM.Context.Resolver.GetSymbol(typeof(IOHelpers).GetMethod("WriteLong")); + static readonly IMethodSymbol WriteDoubleMethod = JVM.Context.Resolver.GetSymbol(typeof(IOHelpers).GetMethod("WriteDouble")); + + static readonly ObjFieldGetterSetter objDummy = new ObjFieldGetterSetter(Dummy); + static readonly PrimFieldGetterSetter primDummy = new PrimFieldGetterSetter(Dummy); + + global::java.io.ObjectStreamField[] fields; + ObjFieldGetterSetter objFieldGetter; + PrimFieldGetterSetter primFieldGetter; + ObjFieldGetterSetter objFieldSetter; + PrimFieldGetterSetter primFieldSetter; + + static void Dummy(object obj, object[] objarr) { + } - private static void Dummy(object obj, byte[] barr) + static void Dummy(object obj, byte[] barr) { + } internal FastFieldReflector(global::java.io.ObjectStreamField[] fields) @@ -220,7 +225,7 @@ internal FastFieldReflector(global::java.io.ObjectStreamField[] fields) RuntimeJavaType tw = null; foreach (global::java.io.ObjectStreamField field in fields) { - RuntimeJavaField fw = GetFieldWrapper(field); + var fw = GetFieldWrapper(field); if (fw != null) { if (tw == null) @@ -234,6 +239,7 @@ internal FastFieldReflector(global::java.io.ObjectStreamField[] fields) } } } + if (tw == null) { objFieldGetter = objFieldSetter = objDummy; @@ -250,10 +256,10 @@ internal FastFieldReflector(global::java.io.ObjectStreamField[] fields) throw x.ToJava(); } - var dmObjGetter = DynamicMethodUtil.Create("__", tw.TypeAsBaseType, true, null, new Type[] { typeof(object), typeof(object[]) }); - var dmPrimGetter = DynamicMethodUtil.Create("__", tw.TypeAsBaseType, true, null, new Type[] { typeof(object), typeof(byte[]) }); - var dmObjSetter = DynamicMethodUtil.Create("__", tw.TypeAsBaseType, true, null, new Type[] { typeof(object), typeof(object[]) }); - var dmPrimSetter = DynamicMethodUtil.Create("__", tw.TypeAsBaseType, true, null, new Type[] { typeof(object), typeof(byte[]) }); + var dmObjGetter = DynamicMethodUtil.Create("__", tw.TypeAsBaseType.AsReflection(), true, null, [typeof(object), typeof(object[])]); + var dmPrimGetter = DynamicMethodUtil.Create("__", tw.TypeAsBaseType.AsReflection(), true, null, [typeof(object), typeof(byte[])]); + var dmObjSetter = DynamicMethodUtil.Create("__", tw.TypeAsBaseType.AsReflection(), true, null, [typeof(object), typeof(object[])]); + var dmPrimSetter = DynamicMethodUtil.Create("__", tw.TypeAsBaseType.AsReflection(), true, null, [typeof(object), typeof(byte[])]); var ilgenObjGetter = JVM.Context.CodeEmitterFactory.Create(dmObjGetter); var ilgenPrimGetter = JVM.Context.CodeEmitterFactory.Create(dmPrimGetter); var ilgenObjSetter = JVM.Context.CodeEmitterFactory.Create(dmObjSetter); @@ -272,13 +278,12 @@ internal FastFieldReflector(global::java.io.ObjectStreamField[] fields) foreach (global::java.io.ObjectStreamField field in fields) { - RuntimeJavaField fw = GetFieldWrapper(field); + var fw = GetFieldWrapper(field); if (fw == null) - { continue; - } + fw.ResolveField(); - RuntimeJavaType fieldType = fw.FieldTypeWrapper; + var fieldType = fw.FieldTypeWrapper; try { fieldType = fieldType.EnsureLoadable(tw.ClassLoader); @@ -288,6 +293,7 @@ internal FastFieldReflector(global::java.io.ObjectStreamField[] fields) { throw x.ToJava(); } + if (fieldType.IsPrimitive) { // Getter diff --git a/src/IKVM.Runtime/Java/Externs/java/lang/Class.cs b/src/IKVM.Runtime/Java/Externs/java/lang/Class.cs index cab514262..e7c9d49e8 100644 --- a/src/IKVM.Runtime/Java/Externs/java/lang/Class.cs +++ b/src/IKVM.Runtime/Java/Externs/java/lang/Class.cs @@ -72,7 +72,7 @@ static class Class var type = Type.GetType(name); if (type != null) - tw = JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(JVM.Context.Resolver.ImportType(type)); + tw = JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(JVM.Context.Resolver.GetSymbol(type)); if (tw == null) { diff --git a/src/IKVM.Runtime/Java/Externs/java/lang/Package.cs b/src/IKVM.Runtime/Java/Externs/java/lang/Package.cs index ce41e7611..e98641d5f 100644 --- a/src/IKVM.Runtime/Java/Externs/java/lang/Package.cs +++ b/src/IKVM.Runtime/Java/Externs/java/lang/Package.cs @@ -48,7 +48,7 @@ static void LazyInitSystemPackages() if (systemPackages == null) { var dict = new Dictionary(); - var path = Path.Combine(VfsTable.GetAssemblyResourcesPath(JVM.Vfs.Context, JVM.Context.Resolver.ResolveBaseAssembly().AsReflection(), JVM.Properties.HomePath), "resources.jar"); + var path = Path.Combine(VfsTable.GetAssemblyResourcesPath(JVM.Vfs.Context, JVM.Context.Resolver.GetBaseAssembly().AsReflection(), JVM.Properties.HomePath), "resources.jar"); foreach (var pkgs in JVM.Context.ClassLoaderFactory.GetBootstrapClassLoader().GetPackageInfo()) foreach (var pkg in pkgs.Value) dict[pkg.Replace('.', '/') + "/"] = path; diff --git a/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Proxy.cs b/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Proxy.cs index e7d5bade4..9b4827c76 100644 --- a/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Proxy.cs +++ b/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Proxy.cs @@ -41,42 +41,34 @@ public static object defineClass0(global::java.lang.ClassLoader classLoader, str #if FIRST_PASS throw new NotImplementedException(); #else - RuntimeAssemblyClassLoader acl = JVM.Context.ClassLoaderFactory.GetClassLoaderWrapper(classLoader) as RuntimeAssemblyClassLoader; + var acl = JVM.Context.ClassLoaderFactory.GetClassLoaderWrapper(classLoader) as RuntimeAssemblyClassLoader; if (acl == null) - { return null; - } - RuntimeJavaType[] wrappers = new RuntimeJavaType[interfaces.Length]; + + var wrappers = new RuntimeJavaType[interfaces.Length]; for (int i = 0; i < wrappers.Length; i++) - { wrappers[i] = RuntimeJavaType.FromClass(interfaces[i]); - } + // TODO support multi assembly class loaders - Type type = acl.MainAssembly.GetType(TypeNameUtil.GetProxyName(wrappers)); + var type = acl.MainAssembly.GetType(TypeNameUtil.GetProxyName(wrappers)); if (type == null) - { return null; - } - RuntimeJavaType tw = JVM.Context.ManagedByteCodeJavaTypeFactory.newInstance(proxyName, type); - RuntimeJavaType tw2 = acl.RegisterInitiatingLoader(tw); + + var tw = JVM.Context.ManagedByteCodeJavaTypeFactory.newInstance(proxyName, type); + var tw2 = acl.RegisterInitiatingLoader(tw); if (tw != tw2) - { return null; - } + // we need to explicitly register the type, because the type isn't visible by normal means JVM.Context.ClassLoaderFactory.SetWrapperForType(type, tw); - RuntimeJavaType[] wrappers2 = tw.Interfaces; + var wrappers2 = tw.Interfaces; if (wrappers.Length != wrappers.Length) - { return null; - } + for (int i = 0; i < wrappers.Length; i++) - { if (wrappers[i] != wrappers2[i]) - { return null; - } - } + return tw.ClassObject; #endif } diff --git a/src/IKVM.Runtime/Java/Externs/sun/reflect/ReflectionFactory.cs b/src/IKVM.Runtime/Java/Externs/sun/reflect/ReflectionFactory.cs index 3997dd1f8..ab9c1a1b1 100644 --- a/src/IKVM.Runtime/Java/Externs/sun/reflect/ReflectionFactory.cs +++ b/src/IKVM.Runtime/Java/Externs/sun/reflect/ReflectionFactory.cs @@ -31,6 +31,7 @@ Jeroen Frijters using System.Runtime.Serialization; using System.Security; +using IKVM.CoreLib.Symbols; using IKVM.Runtime; using IKVM.Runtime.Accessors.Java.Lang; using IKVM.Runtime.Util.Java.Security; @@ -261,7 +262,7 @@ sealed class SerializationConstructorAccessorImpl : global::sun.reflect.Construc { readonly RuntimeJavaMethod mw; - readonly Type type; + readonly ITypeSymbol type; /// /// Initializes a new instance. @@ -285,9 +286,9 @@ internal SerializationConstructorAccessorImpl(global::java.lang.reflect.Construc public object newInstance(object[] args) { #if NETFRAMEWORK - var obj = FormatterServices.GetUninitializedObject(type); + var obj = FormatterServices.GetUninitializedObject(type.AsReflection()); #else - var obj = RuntimeHelpers.GetUninitializedObject(type); + var obj = RuntimeHelpers.GetUninitializedObject(type.AsReflection()); #endif if (mw != null) mw.Invoke(obj, ConvertArgs(mw.DeclaringType.ClassLoader, mw.GetParameters(), args)); @@ -302,38 +303,38 @@ public object newInstance(object[] args) sealed class BoxUtil { - static readonly MethodInfo valueOfByte = typeof(global::java.lang.Byte).GetMethod("valueOf", new Type[] { typeof(byte) }); - static readonly MethodInfo valueOfBoolean = typeof(global::java.lang.Boolean).GetMethod("valueOf", new Type[] { typeof(bool) }); - static readonly MethodInfo valueOfChar = typeof(global::java.lang.Character).GetMethod("valueOf", new Type[] { typeof(char) }); - static readonly MethodInfo valueOfShort = typeof(global::java.lang.Short).GetMethod("valueOf", new Type[] { typeof(short) }); - static readonly MethodInfo valueOfInt = typeof(global::java.lang.Integer).GetMethod("valueOf", new Type[] { typeof(int) }); - static readonly MethodInfo valueOfFloat = typeof(global::java.lang.Float).GetMethod("valueOf", new Type[] { typeof(float) }); - static readonly MethodInfo valueOfLong = typeof(global::java.lang.Long).GetMethod("valueOf", new Type[] { typeof(long) }); - static readonly MethodInfo valueOfDouble = typeof(global::java.lang.Double).GetMethod("valueOf", new Type[] { typeof(double) }); - static readonly MethodInfo byteValue = typeof(global::java.lang.Byte).GetMethod("byteValue", []); - static readonly MethodInfo booleanValue = typeof(global::java.lang.Boolean).GetMethod("booleanValue", []); - static readonly MethodInfo charValue = typeof(global::java.lang.Character).GetMethod("charValue", []); - static readonly MethodInfo shortValue = typeof(global::java.lang.Short).GetMethod("shortValue", []); - static readonly MethodInfo intValue = typeof(global::java.lang.Integer).GetMethod("intValue", []); - static readonly MethodInfo floatValue = typeof(global::java.lang.Float).GetMethod("floatValue", []); - static readonly MethodInfo longValue = typeof(global::java.lang.Long).GetMethod("longValue", []); - static readonly MethodInfo doubleValue = typeof(global::java.lang.Double).GetMethod("doubleValue", []); + static readonly IMethodSymbol valueOfByte = JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.Byte)).GetMethod("valueOf", [JVM.Context.Types.Byte]); + static readonly IMethodSymbol valueOfBoolean = JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.Boolean)).GetMethod("valueOf", [JVM.Context.Types.Boolean]); + static readonly IMethodSymbol valueOfChar = JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.Character)).GetMethod("valueOf", [JVM.Context.Types.Char]); + static readonly IMethodSymbol valueOfShort = JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.Short)).GetMethod("valueOf", [JVM.Context.Types.Int16]); + static readonly IMethodSymbol valueOfInt = JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.Integer)).GetMethod("valueOf", [JVM.Context.Types.Int32]); + static readonly IMethodSymbol valueOfFloat = JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.Float)).GetMethod("valueOf", [JVM.Context.Types.Single]); + static readonly IMethodSymbol valueOfLong = JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.Long)).GetMethod("valueOf", [JVM.Context.Types.Int64]); + static readonly IMethodSymbol valueOfDouble = JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.Double)).GetMethod("valueOf", [JVM.Context.Types.Double]); + static readonly IMethodSymbol byteValue = JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.Byte)).GetMethod("byteValue", []); + static readonly IMethodSymbol booleanValue = JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.Boolean)).GetMethod("booleanValue", []); + static readonly IMethodSymbol charValue = JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.Character)).GetMethod("charValue", []); + static readonly IMethodSymbol shortValue = JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.Short)).GetMethod("shortValue", []); + static readonly IMethodSymbol intValue = JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.Integer)).GetMethod("intValue", []); + static readonly IMethodSymbol floatValue = JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.Float)).GetMethod("floatValue", []); + static readonly IMethodSymbol longValue = JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.Long)).GetMethod("longValue", []); + static readonly IMethodSymbol doubleValue = JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.Double)).GetMethod("doubleValue", []); internal static void EmitUnboxArg(CodeEmitter ilgen, RuntimeJavaType type) { if (type == ilgen.Context.PrimitiveJavaTypeFactory.BYTE) { - ilgen.Emit(OpCodes.Castclass, typeof(global::java.lang.Byte)); + ilgen.Emit(OpCodes.Castclass, JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.Byte))); ilgen.Emit(OpCodes.Call, byteValue); } else if (type == ilgen.Context.PrimitiveJavaTypeFactory.BOOLEAN) { - ilgen.Emit(OpCodes.Castclass, typeof(global::java.lang.Boolean)); + ilgen.Emit(OpCodes.Castclass, JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.Boolean))); ilgen.Emit(OpCodes.Call, booleanValue); } else if (type == ilgen.Context.PrimitiveJavaTypeFactory.CHAR) { - ilgen.Emit(OpCodes.Castclass, typeof(global::java.lang.Character)); + ilgen.Emit(OpCodes.Castclass, JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.Character))); ilgen.Emit(OpCodes.Call, charValue); } else if (type == ilgen.Context.PrimitiveJavaTypeFactory.SHORT @@ -343,10 +344,10 @@ internal static void EmitUnboxArg(CodeEmitter ilgen, RuntimeJavaType type) || type == ilgen.Context.PrimitiveJavaTypeFactory.DOUBLE) { ilgen.Emit(OpCodes.Dup); - ilgen.Emit(OpCodes.Isinst, typeof(global::java.lang.Byte)); + ilgen.Emit(OpCodes.Isinst, JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.Byte))); CodeEmitterLabel next = ilgen.DefineLabel(); ilgen.EmitBrfalse(next); - ilgen.Emit(OpCodes.Castclass, typeof(global::java.lang.Byte)); + ilgen.Emit(OpCodes.Castclass, JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.Byte))); ilgen.Emit(OpCodes.Call, byteValue); ilgen.Emit(OpCodes.Conv_I1); Expand(ilgen, type); @@ -355,77 +356,77 @@ internal static void EmitUnboxArg(CodeEmitter ilgen, RuntimeJavaType type) ilgen.MarkLabel(next); if (type == ilgen.Context.PrimitiveJavaTypeFactory.SHORT) { - ilgen.Emit(OpCodes.Castclass, typeof(global::java.lang.Short)); + ilgen.Emit(OpCodes.Castclass, JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.Short))); ilgen.Emit(OpCodes.Call, shortValue); } else { ilgen.Emit(OpCodes.Dup); - ilgen.Emit(OpCodes.Isinst, typeof(global::java.lang.Short)); + ilgen.Emit(OpCodes.Isinst, JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.Short))); next = ilgen.DefineLabel(); ilgen.EmitBrfalse(next); - ilgen.Emit(OpCodes.Castclass, typeof(global::java.lang.Short)); + ilgen.Emit(OpCodes.Castclass, JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.Short))); ilgen.Emit(OpCodes.Call, shortValue); Expand(ilgen, type); ilgen.EmitBr(done); ilgen.MarkLabel(next); ilgen.Emit(OpCodes.Dup); - ilgen.Emit(OpCodes.Isinst, typeof(global::java.lang.Character)); + ilgen.Emit(OpCodes.Isinst, JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.Character))); next = ilgen.DefineLabel(); ilgen.EmitBrfalse(next); - ilgen.Emit(OpCodes.Castclass, typeof(global::java.lang.Character)); + ilgen.Emit(OpCodes.Castclass, JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.Character))); ilgen.Emit(OpCodes.Call, charValue); Expand(ilgen, type); ilgen.EmitBr(done); ilgen.MarkLabel(next); if (type == ilgen.Context.PrimitiveJavaTypeFactory.INT) { - ilgen.Emit(OpCodes.Castclass, typeof(global::java.lang.Integer)); + ilgen.Emit(OpCodes.Castclass, JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.Integer))); ilgen.Emit(OpCodes.Call, intValue); } else { ilgen.Emit(OpCodes.Dup); - ilgen.Emit(OpCodes.Isinst, typeof(global::java.lang.Integer)); + ilgen.Emit(OpCodes.Isinst, JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.Integer))); next = ilgen.DefineLabel(); ilgen.EmitBrfalse(next); - ilgen.Emit(OpCodes.Castclass, typeof(global::java.lang.Integer)); + ilgen.Emit(OpCodes.Castclass, JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.Integer))); ilgen.Emit(OpCodes.Call, intValue); Expand(ilgen, type); ilgen.EmitBr(done); ilgen.MarkLabel(next); if (type == ilgen.Context.PrimitiveJavaTypeFactory.LONG) { - ilgen.Emit(OpCodes.Castclass, typeof(global::java.lang.Long)); + ilgen.Emit(OpCodes.Castclass, JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.Long))); ilgen.Emit(OpCodes.Call, longValue); } else { ilgen.Emit(OpCodes.Dup); - ilgen.Emit(OpCodes.Isinst, typeof(global::java.lang.Long)); + ilgen.Emit(OpCodes.Isinst, JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.Long))); next = ilgen.DefineLabel(); ilgen.EmitBrfalse(next); - ilgen.Emit(OpCodes.Castclass, typeof(global::java.lang.Long)); + ilgen.Emit(OpCodes.Castclass, JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.Long))); ilgen.Emit(OpCodes.Call, longValue); Expand(ilgen, type); ilgen.EmitBr(done); ilgen.MarkLabel(next); if (type == ilgen.Context.PrimitiveJavaTypeFactory.FLOAT) { - ilgen.Emit(OpCodes.Castclass, typeof(global::java.lang.Float)); + ilgen.Emit(OpCodes.Castclass, JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.Float))); ilgen.Emit(OpCodes.Call, floatValue); } else if (type == ilgen.Context.PrimitiveJavaTypeFactory.DOUBLE) { ilgen.Emit(OpCodes.Dup); - ilgen.Emit(OpCodes.Isinst, typeof(global::java.lang.Float)); + ilgen.Emit(OpCodes.Isinst, JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.Float))); next = ilgen.DefineLabel(); ilgen.EmitBrfalse(next); - ilgen.Emit(OpCodes.Castclass, typeof(global::java.lang.Float)); + ilgen.Emit(OpCodes.Castclass, JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.Float))); ilgen.Emit(OpCodes.Call, floatValue); ilgen.EmitBr(done); ilgen.MarkLabel(next); - ilgen.Emit(OpCodes.Castclass, typeof(global::java.lang.Double)); + ilgen.Emit(OpCodes.Castclass, JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.Double))); ilgen.Emit(OpCodes.Call, doubleValue); } else @@ -506,13 +507,13 @@ static void Expand(CodeEmitter ilgen, RuntimeJavaType type) sealed class FastMethodAccessorImpl : global::sun.reflect.MethodAccessor { - internal static readonly ConstructorInfo nullPointerExceptionCtor; - internal static readonly ConstructorInfo nullPointerExceptionWithMessageCtor; - internal static readonly ConstructorInfo illegalArgumentExceptionCtor; - internal static readonly ConstructorInfo illegalArgumentExceptionWithMessageCtor; - internal static readonly ConstructorInfo illegalArgumentExceptionWithMessageAndCauseCtor; - internal static readonly ConstructorInfo illegalArgumentExceptionWithCauseCtor; - internal static readonly ConstructorInfo invocationTargetExceptionWithCauseCtor; + internal static readonly IConstructorSymbol nullPointerExceptionCtor; + internal static readonly IConstructorSymbol nullPointerExceptionWithMessageCtor; + internal static readonly IConstructorSymbol illegalArgumentExceptionCtor; + internal static readonly IConstructorSymbol illegalArgumentExceptionWithMessageCtor; + internal static readonly IConstructorSymbol illegalArgumentExceptionWithMessageAndCauseCtor; + internal static readonly IConstructorSymbol illegalArgumentExceptionWithCauseCtor; + internal static readonly IConstructorSymbol invocationTargetExceptionWithCauseCtor; delegate object Invoker(object obj, object[] args, global::ikvm.@internal.CallerID callerID); Invoker invoker; @@ -522,13 +523,13 @@ sealed class FastMethodAccessorImpl : global::sun.reflect.MethodAccessor /// static FastMethodAccessorImpl() { - nullPointerExceptionCtor = typeof(global::java.lang.NullPointerException).GetConstructor([]); - nullPointerExceptionWithMessageCtor = typeof(global::java.lang.NullPointerException).GetConstructor(new[] { typeof(string) }); - illegalArgumentExceptionCtor = typeof(global::java.lang.IllegalArgumentException).GetConstructor([]); - illegalArgumentExceptionWithMessageCtor = typeof(global::java.lang.IllegalArgumentException).GetConstructor(new[] { typeof(string) }); - illegalArgumentExceptionWithMessageAndCauseCtor = typeof(global::java.lang.IllegalArgumentException).GetConstructor(new[] { typeof(string), typeof(Exception) }); - illegalArgumentExceptionWithCauseCtor = typeof(global::java.lang.IllegalArgumentException).GetConstructor(new[] { typeof(Exception) }); - invocationTargetExceptionWithCauseCtor = typeof(global::java.lang.reflect.InvocationTargetException).GetConstructor(new[] { typeof(Exception) }); + nullPointerExceptionCtor = JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.NullPointerException)).GetConstructor([]); + nullPointerExceptionWithMessageCtor = JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.NullPointerException)).GetConstructor([JVM.Context.Types.String]); + illegalArgumentExceptionCtor = JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.IllegalArgumentException)).GetConstructor([]); + illegalArgumentExceptionWithMessageCtor = JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.IllegalArgumentException)).GetConstructor([JVM.Context.Types.String]); + illegalArgumentExceptionWithMessageAndCauseCtor = JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.IllegalArgumentException)).GetConstructor([JVM.Context.Types.String, JVM.Context.Types.Exception]); + illegalArgumentExceptionWithCauseCtor = JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.IllegalArgumentException)).GetConstructor([JVM.Context.Types.Exception]); + invocationTargetExceptionWithCauseCtor = JVM.Context.Resolver.GetSymbol(typeof(global::java.lang.reflect.InvocationTargetException)).GetConstructor([JVM.Context.Types.Exception]); } sealed class RunClassInit @@ -586,7 +587,7 @@ internal unsafe FastMethodAccessorImpl(RuntimeJavaMethod mw) // generate new dynamic method var np = !mw.IsPublic || !mw.DeclaringType.IsPublic; - var dm = DynamicMethodUtil.Create($"____{mw.DeclaringType.Name.Replace(".", "_")}__{mw.Name}", mw.DeclaringType.TypeAsBaseType, np, typeof(object), new[] { typeof(object), typeof(object[]), typeof(global::ikvm.@internal.CallerID) }); + var dm = DynamicMethodUtil.Create($"____{mw.DeclaringType.Name.Replace(".", "_")}__{mw.Name}", mw.DeclaringType.TypeAsBaseType.AsReflection(), np, typeof(object), new[] { typeof(object), typeof(object[]), typeof(global::ikvm.@internal.CallerID) }); var il = JVM.Context.CodeEmitterFactory.Create(dm); // labels @@ -614,7 +615,7 @@ internal unsafe FastMethodAccessorImpl(RuntimeJavaMethod mw) il.MarkLabel(endIsNullLabel); // temporary variables - var e = il.AllocTempLocal(typeof(Exception)); + var e = il.AllocTempLocal(il.Context.Types.Exception); // cast target to appropriate type var endConvSelf = il.DefineLabel(); @@ -626,7 +627,7 @@ internal unsafe FastMethodAccessorImpl(RuntimeJavaMethod mw) il.EmitLeave(endConvSelf); // catch InvalidCastException, store, add message, and wrap with IllegalArgumentException - il.BeginCatchBlock(typeof(InvalidCastException)); + il.BeginCatchBlock(il.Context.Resolver.GetSymbol(typeof(InvalidCastException))); il.Emit(OpCodes.Stloc, e); il.Emit(OpCodes.Ldstr, "object is not an instance of declaring class"); il.Emit(OpCodes.Ldloc, e); @@ -634,7 +635,7 @@ internal unsafe FastMethodAccessorImpl(RuntimeJavaMethod mw) il.Emit(OpCodes.Throw); // catch Exception, wrap with IllegalArgumentException - il.BeginCatchBlock(typeof(Exception)); + il.BeginCatchBlock(il.Context.Types.Exception); il.Emit(OpCodes.Newobj, illegalArgumentExceptionWithCauseCtor); il.Emit(OpCodes.Throw); @@ -685,7 +686,7 @@ internal unsafe FastMethodAccessorImpl(RuntimeJavaMethod mw) var o = p[n++] = il.AllocTempLocal(tw.TypeAsSignatureType); // temporary variable for exceptions - var e = il.AllocTempLocal(typeof(Exception)); + var e = il.AllocTempLocal(il.Context.Types.Exception); // load and convert argument var endConvArgn = il.DefineLabel(); @@ -699,7 +700,7 @@ internal unsafe FastMethodAccessorImpl(RuntimeJavaMethod mw) il.EmitLeave(endConvArgn); // catch InvalidCastException, store, add message, and wrap with IllegalArgumentException - il.BeginCatchBlock(typeof(InvalidCastException)); + il.BeginCatchBlock(il.Context.Resolver.GetSymbol(typeof(InvalidCastException))); il.Emit(OpCodes.Stloc, e); il.Emit(OpCodes.Ldstr, $"argument type mismatch on parameter {i}"); il.Emit(OpCodes.Ldloc, e); @@ -707,7 +708,7 @@ internal unsafe FastMethodAccessorImpl(RuntimeJavaMethod mw) il.Emit(OpCodes.Throw); // catch Exception, wrap with IllegalArgumentException - il.BeginCatchBlock(typeof(Exception)); + il.BeginCatchBlock(il.Context.Types.Exception); il.Emit(OpCodes.Stloc, e); il.Emit(OpCodes.Ldstr, $"exception on parameter {i}"); il.Emit(OpCodes.Ldloc, e); @@ -721,7 +722,7 @@ internal unsafe FastMethodAccessorImpl(RuntimeJavaMethod mw) } // storage for return value - var rt = il.AllocTempLocal(typeof(object)); + var rt = il.AllocTempLocal(il.Context.Types.Object); // call method and convert result il.BeginExceptionBlock(); @@ -758,7 +759,7 @@ internal unsafe FastMethodAccessorImpl(RuntimeJavaMethod mw) il.EmitLeave(postLabel); // catch exception from call and wrap - il.BeginCatchBlock(typeof(Exception)); + il.BeginCatchBlock(il.Context.Types.Exception); il.Emit(OpCodes.Ldc_I4_0); il.Emit(OpCodes.Call, il.Context.ByteCodeHelperMethods.MapException.MakeGenericMethod(il.Context.Types.Exception)); il.Emit(OpCodes.Newobj, invocationTargetExceptionWithCauseCtor); @@ -830,7 +831,7 @@ internal FastConstructorAccessorImpl(global::java.lang.reflect.Constructor const // resolve the runtime method info mw.ResolveMethod(); var np = !mw.IsPublic || !mw.DeclaringType.IsPublic; - var dm = DynamicMethodUtil.Create($"____{mw.DeclaringType.Name.Replace(".", "_")}__{mw.Name}", mw.DeclaringType.TypeAsTBD, np, typeof(object), new[] { typeof(object[]) }); + var dm = DynamicMethodUtil.Create($"____{mw.DeclaringType.Name.Replace(".", "_")}__{mw.Name}", mw.DeclaringType.TypeAsTBD.AsReflection(), np, typeof(object), new[] { typeof(object[]) }); var il = JVM.Context.CodeEmitterFactory.Create(dm); // labels @@ -881,7 +882,7 @@ internal FastConstructorAccessorImpl(global::java.lang.reflect.Constructor const var o = p[n++] = il.AllocTempLocal(tw.TypeAsSignatureType); // temporary variable for exceptions - var e = il.AllocTempLocal(typeof(Exception)); + var e = il.AllocTempLocal(il.Context.Types.Exception); // load and convert argument var endConvArgn = il.DefineLabel(); @@ -895,7 +896,7 @@ internal FastConstructorAccessorImpl(global::java.lang.reflect.Constructor const il.EmitLeave(endConvArgn); // catch InvalidCastException, store, add message, and wrap with IllegalArgumentException - il.BeginCatchBlock(typeof(InvalidCastException)); + il.BeginCatchBlock(il.Context.Resolver.GetSymbol(typeof(InvalidCastException))); il.Emit(OpCodes.Stloc, e); il.Emit(OpCodes.Ldstr, $"argument type mismatch on parameter {i}"); il.Emit(OpCodes.Ldloc, e); @@ -903,7 +904,7 @@ internal FastConstructorAccessorImpl(global::java.lang.reflect.Constructor const il.Emit(OpCodes.Throw); // catch Exception, wrap with IllegalArgumentException - il.BeginCatchBlock(typeof(Exception)); + il.BeginCatchBlock(il.Context.Types.Exception); il.Emit(OpCodes.Stloc, e); il.Emit(OpCodes.Ldstr, $"exception on parameter {i}"); il.Emit(OpCodes.Ldloc, e); @@ -927,13 +928,13 @@ internal FastConstructorAccessorImpl(global::java.lang.reflect.Constructor const } // call constructor - var rt = il.AllocTempLocal(typeof(object)); + var rt = il.AllocTempLocal(il.Context.Types.Object); mw.EmitNewobj(il); il.Emit(OpCodes.Stloc, rt); il.EmitLeave(postLabel); // catch exception from call and wrap - il.BeginCatchBlock(typeof(Exception)); + il.BeginCatchBlock(il.Context.Types.Exception); il.Emit(OpCodes.Ldc_I4_0); il.Emit(OpCodes.Call, il.Context.ByteCodeHelperMethods.MapException.MakeGenericMethod(il.Context.Types.Exception)); il.Emit(OpCodes.Newobj, FastMethodAccessorImpl.invocationTargetExceptionWithCauseCtor); @@ -975,28 +976,29 @@ public object newInstance(object[] args) sealed class FastSerializationConstructorAccessorImpl : global::sun.reflect.ConstructorAccessor { - static readonly MethodInfo GetTypeFromHandleMethod = typeof(Type).GetMethod(nameof(Type.GetTypeFromHandle), new[] { typeof(RuntimeTypeHandle) }); + static readonly IMethodSymbol GetTypeFromHandleMethod = JVM.Context.Types.Type.GetMethod(nameof(Type.GetTypeFromHandle), [JVM.Context.Types.RuntimeTypeHandle]); #if NETFRAMEWORK - static readonly MethodInfo GetUninitializedObjectMethod = typeof(FormatterServices).GetMethod(nameof(FormatterServices.GetUninitializedObject), new[] { typeof(Type) }); + static readonly IMethodSymbol GetUninitializedObjectMethod = JVM.Context.Resolver.GetSymbol(typeof(FormatterServices)).GetMethod(nameof(FormatterServices.GetUninitializedObject), [JVM.Context.Types.Type]); #else - static readonly MethodInfo GetUninitializedObjectMethod = typeof(RuntimeHelpers).GetMethod(nameof(RuntimeHelpers.GetUninitializedObject), new[] { typeof(Type) }); + static readonly IMethodSymbol GetUninitializedObjectMethod = JVM.Context.Resolver.GetSymbol(typeof(RuntimeHelpers)).GetMethod(nameof(RuntimeHelpers.GetUninitializedObject), [JVM.Context.Types.Type]); #endif + delegate object InvokeCtor(); InvokeCtor invoker; internal FastSerializationConstructorAccessorImpl(global::java.lang.reflect.Constructor constructorToCall, global::java.lang.Class classToInstantiate) { - RuntimeJavaMethod constructor = RuntimeJavaMethod.FromExecutable(constructorToCall); + var constructor = RuntimeJavaMethod.FromExecutable(constructorToCall); if (constructor.GetParameters().Length != 0) - { throw new NotImplementedException("Serialization constructor cannot have parameters"); - } + constructor.Link(); constructor.ResolveMethod(); - Type type; + + ITypeSymbol type; try { - RuntimeJavaType wrapper = RuntimeJavaType.FromClass(classToInstantiate); + var wrapper = RuntimeJavaType.FromClass(classToInstantiate); wrapper.Finish(); type = wrapper.TypeAsBaseType; } @@ -1004,15 +1006,16 @@ internal FastSerializationConstructorAccessorImpl(global::java.lang.reflect.Cons { throw x.ToJava(); } - DynamicMethod dm = DynamicMethodUtil.Create("__", constructor.DeclaringType.TypeAsBaseType, true, typeof(object), null); - CodeEmitter ilgen = JVM.Context.CodeEmitterFactory.Create(dm); - ilgen.Emit(OpCodes.Ldtoken, type); - ilgen.Emit(OpCodes.Call, GetTypeFromHandleMethod); - ilgen.Emit(OpCodes.Call, GetUninitializedObjectMethod); - ilgen.Emit(OpCodes.Dup); - constructor.EmitCall(ilgen); - ilgen.Emit(OpCodes.Ret); - ilgen.DoEmit(); + + var dm = DynamicMethodUtil.Create("__", constructor.DeclaringType.TypeAsBaseType.AsReflection(), true, typeof(object), null); + var il = JVM.Context.CodeEmitterFactory.Create(dm); + il.Emit(OpCodes.Ldtoken, type); + il.Emit(OpCodes.Call, GetTypeFromHandleMethod); + il.Emit(OpCodes.Call, GetUninitializedObjectMethod); + il.Emit(OpCodes.Dup); + constructor.EmitCall(il); + il.Emit(OpCodes.Ret); + il.DoEmit(); invoker = (InvokeCtor)dm.CreateDelegate(typeof(InvokeCtor)); } @@ -1035,7 +1038,7 @@ public object newInstance(object[] args) sealed class ActivatorConstructorAccessor : global::sun.reflect.ConstructorAccessor { - private readonly Type type; + readonly ITypeSymbol type; internal ActivatorConstructorAccessor(RuntimeJavaMethod mw) { @@ -1049,7 +1052,7 @@ public object newInstance(object[] objarr) try { - return Activator.CreateInstance(type); + return Activator.CreateInstance(type.AsReflection()); } catch (TargetInvocationException x) { @@ -1316,7 +1319,7 @@ private T lazyGet(object obj) { throw GetIllegalArgumentException(obj); } - else if (fw.DeclaringType.IsRemapped && !fw.DeclaringType.TypeAsBaseType.IsInstanceOfType(obj)) + else if (fw.DeclaringType.IsRemapped && !fw.DeclaringType.TypeAsBaseType.AsReflection().IsInstanceOfType(obj)) { throw GetUnsupportedRemappedFieldException(obj); } @@ -1361,7 +1364,7 @@ private void lazySet(object obj, T value) { throw SetIllegalArgumentException(obj); } - else if (fw.DeclaringType.IsRemapped && !fw.DeclaringType.TypeAsBaseType.IsInstanceOfType(obj)) + else if (fw.DeclaringType.IsRemapped && !fw.DeclaringType.TypeAsBaseType.AsReflection().IsInstanceOfType(obj)) { throw GetUnsupportedRemappedFieldException(obj); } @@ -2049,9 +2052,11 @@ protected sealed override object JavaBox(object value) } #if !NO_REF_EMIT + private Delegate GenerateFastGetter(Type delegateType, Type fieldType, RuntimeJavaField fw) { RuntimeJavaType fieldTypeWrapper; + try { fieldTypeWrapper = fw.FieldTypeWrapper.EnsureLoadable(fw.DeclaringType.ClassLoader); @@ -2062,36 +2067,38 @@ private Delegate GenerateFastGetter(Type delegateType, Type fieldType, RuntimeJa { throw x.ToJava(); } + fw.ResolveField(); - DynamicMethod dm = DynamicMethodUtil.Create("__", fw.DeclaringType.TypeAsBaseType, !fw.IsPublic || !fw.DeclaringType.IsPublic, fieldType, new Type[] { typeof(IReflectionException), typeof(object), typeof(object) }); - CodeEmitter ilgen = JVM.Context.CodeEmitterFactory.Create(dm); + + var dm = DynamicMethodUtil.Create("__", fw.DeclaringType.TypeAsBaseType.AsReflection(), !fw.IsPublic || !fw.DeclaringType.IsPublic, fieldType, [typeof(IReflectionException), typeof(object), typeof(object)]); + var il = JVM.Context.CodeEmitterFactory.Create(dm); if (fw.IsStatic) { - fw.EmitGet(ilgen); - fieldTypeWrapper.EmitConvSignatureTypeToStackType(ilgen); + fw.EmitGet(il); + fieldTypeWrapper.EmitConvSignatureTypeToStackType(il); } else { - ilgen.BeginExceptionBlock(); - ilgen.Emit(OpCodes.Ldarg_1); - ilgen.Emit(OpCodes.Castclass, fw.DeclaringType.TypeAsBaseType); - fw.EmitGet(ilgen); - fieldTypeWrapper.EmitConvSignatureTypeToStackType(ilgen); - CodeEmitterLocal local = ilgen.DeclareLocal(fieldType); - ilgen.Emit(OpCodes.Stloc, local); - CodeEmitterLabel label = ilgen.DefineLabel(); - ilgen.EmitLeave(label); - ilgen.BeginCatchBlock(typeof(InvalidCastException)); - ilgen.Emit(OpCodes.Ldarg_0); - ilgen.Emit(OpCodes.Ldarg_1); - ilgen.Emit(OpCodes.Callvirt, typeof(IReflectionException).GetMethod("GetIllegalArgumentException")); - ilgen.Emit(OpCodes.Throw); - ilgen.EndExceptionBlock(); - ilgen.MarkLabel(label); - ilgen.Emit(OpCodes.Ldloc, local); - } - ilgen.Emit(OpCodes.Ret); - ilgen.DoEmit(); + il.BeginExceptionBlock(); + il.Emit(OpCodes.Ldarg_1); + il.Emit(OpCodes.Castclass, fw.DeclaringType.TypeAsBaseType); + fw.EmitGet(il); + fieldTypeWrapper.EmitConvSignatureTypeToStackType(il); + CodeEmitterLocal local = il.DeclareLocal(il.Context.Resolver.GetSymbol(fieldType)); + il.Emit(OpCodes.Stloc, local); + CodeEmitterLabel label = il.DefineLabel(); + il.EmitLeave(label); + il.BeginCatchBlock(il.Context.Resolver.GetSymbol(typeof(InvalidCastException))); + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Ldarg_1); + il.Emit(OpCodes.Callvirt, il.Context.Resolver.GetSymbol(typeof(IReflectionException)).GetMethod("GetIllegalArgumentException")); + il.Emit(OpCodes.Throw); + il.EndExceptionBlock(); + il.MarkLabel(label); + il.Emit(OpCodes.Ldloc, local); + } + il.Emit(OpCodes.Ret); + il.DoEmit(); return dm.CreateDelegate(delegateType, this); } @@ -2108,58 +2115,59 @@ private Delegate GenerateFastSetter(Type delegateType, Type fieldType, RuntimeJa { throw x.ToJava(); } + fw.ResolveField(); - DynamicMethod dm = DynamicMethodUtil.Create("__", fw.DeclaringType.TypeAsBaseType, !fw.IsPublic || !fw.DeclaringType.IsPublic, null, new Type[] { typeof(IReflectionException), typeof(object), fieldType, typeof(object) }); - CodeEmitter ilgen = JVM.Context.CodeEmitterFactory.Create(dm); + + var dm = DynamicMethodUtil.Create("__", fw.DeclaringType.TypeAsBaseType.AsReflection(), !fw.IsPublic || !fw.DeclaringType.IsPublic, null, [typeof(IReflectionException), typeof(object), fieldType, typeof(object)]); + var il = JVM.Context.CodeEmitterFactory.Create(dm); if (fw.IsStatic) { if (fieldType == typeof(object)) { - ilgen.BeginExceptionBlock(); - ilgen.Emit(OpCodes.Ldarg_2); - fieldTypeWrapper.EmitCheckcast(ilgen); - fieldTypeWrapper.EmitConvStackTypeToSignatureType(ilgen, null); - fw.EmitSet(ilgen); - CodeEmitterLabel label = ilgen.DefineLabel(); - ilgen.EmitLeave(label); - ilgen.BeginCatchBlock(typeof(InvalidCastException)); - ilgen.Emit(OpCodes.Ldarg_0); - ilgen.Emit(OpCodes.Ldarg_1); - ilgen.Emit(OpCodes.Callvirt, typeof(IReflectionException).GetMethod("SetIllegalArgumentException")); - ilgen.Emit(OpCodes.Throw); - ilgen.EndExceptionBlock(); - ilgen.MarkLabel(label); + il.BeginExceptionBlock(); + il.Emit(OpCodes.Ldarg_2); + fieldTypeWrapper.EmitCheckcast(il); + fieldTypeWrapper.EmitConvStackTypeToSignatureType(il, null); + fw.EmitSet(il); + CodeEmitterLabel label = il.DefineLabel(); + il.EmitLeave(label); + il.BeginCatchBlock(il.Context.Resolver.GetSymbol(typeof(InvalidCastException))); + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Ldarg_1); + il.Emit(OpCodes.Callvirt, il.Context.Resolver.GetSymbol(typeof(IReflectionException)).GetMethod("SetIllegalArgumentException")); + il.Emit(OpCodes.Throw); + il.EndExceptionBlock(); + il.MarkLabel(label); } else { - ilgen.Emit(OpCodes.Ldarg_2); - fw.EmitSet(ilgen); + il.Emit(OpCodes.Ldarg_2); + fw.EmitSet(il); } } else { - ilgen.BeginExceptionBlock(); - ilgen.Emit(OpCodes.Ldarg_1); - ilgen.Emit(OpCodes.Castclass, fw.DeclaringType.TypeAsBaseType); - ilgen.Emit(OpCodes.Ldarg_2); + il.BeginExceptionBlock(); + il.Emit(OpCodes.Ldarg_1); + il.Emit(OpCodes.Castclass, fw.DeclaringType.TypeAsBaseType); + il.Emit(OpCodes.Ldarg_2); if (fieldType == typeof(object)) - { - fieldTypeWrapper.EmitCheckcast(ilgen); - } - fieldTypeWrapper.EmitConvStackTypeToSignatureType(ilgen, null); - fw.EmitSet(ilgen); - CodeEmitterLabel label = ilgen.DefineLabel(); - ilgen.EmitLeave(label); - ilgen.BeginCatchBlock(typeof(InvalidCastException)); - ilgen.Emit(OpCodes.Ldarg_0); - ilgen.Emit(OpCodes.Ldarg_1); - ilgen.Emit(OpCodes.Callvirt, typeof(IReflectionException).GetMethod("SetIllegalArgumentException")); - ilgen.Emit(OpCodes.Throw); - ilgen.EndExceptionBlock(); - ilgen.MarkLabel(label); - } - ilgen.Emit(OpCodes.Ret); - ilgen.DoEmit(); + fieldTypeWrapper.EmitCheckcast(il); + + fieldTypeWrapper.EmitConvStackTypeToSignatureType(il, null); + fw.EmitSet(il); + var label = il.DefineLabel(); + il.EmitLeave(label); + il.BeginCatchBlock(il.Context.Resolver.GetSymbol(typeof(InvalidCastException))); + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Ldarg_1); + il.Emit(OpCodes.Callvirt, il.Context.Resolver.GetSymbol(typeof(IReflectionException)).GetMethod("SetIllegalArgumentException")); + il.Emit(OpCodes.Throw); + il.EndExceptionBlock(); + il.MarkLabel(label); + } + il.Emit(OpCodes.Ret); + il.DoEmit(); return dm.CreateDelegate(delegateType, this); } #endif // !NO_REF_EMIT diff --git a/src/IKVM.Runtime/MethodAnalyzer.cs b/src/IKVM.Runtime/MethodAnalyzer.cs index b6a1652c0..65643053b 100644 --- a/src/IKVM.Runtime/MethodAnalyzer.cs +++ b/src/IKVM.Runtime/MethodAnalyzer.cs @@ -2856,37 +2856,27 @@ private RuntimeJavaType SigTypeToClassName(RuntimeJavaType type, RuntimeJavaType private int AllocErrorMessage(string message) { - if (errorMessages == null) - { - errorMessages = new List(); - } - int index = errorMessages.Count; + errorMessages ??= []; + var index = errorMessages.Count; errorMessages.Add(message); return index; } - private string CheckLoaderConstraints(ClassFile.ConstantPoolItemMI cpi, RuntimeJavaMethod mw) + string CheckLoaderConstraints(ClassFile.ConstantPoolItemMI cpi, RuntimeJavaMethod mw) { -#if NETFRAMEWORK if (cpi.GetRetType() != mw.ReturnType && !cpi.GetRetType().IsUnloadable && !mw.ReturnType.IsUnloadable) -#else - if (cpi.GetRetType() != mw.ReturnType && cpi.GetRetType().Name != mw.ReturnType.Name && !cpi.GetRetType().IsUnloadable && !mw.ReturnType.IsUnloadable) -#endif { #if IMPORTER StaticCompiler.LinkageError("Method \"{2}.{3}{4}\" has a return type \"{0}\" instead of type \"{1}\" as expected by \"{5}\"", mw.ReturnType, cpi.GetRetType(), cpi.GetClassType().Name, cpi.Name, cpi.Signature, classFile.Name); #endif return "Loader constraints violated (return type): " + mw.DeclaringType.Name + "." + mw.Name + mw.Signature; } - RuntimeJavaType[] here = cpi.GetArgTypes(); - RuntimeJavaType[] there = mw.GetParameters(); + + var here = cpi.GetArgTypes(); + var there = mw.GetParameters(); for (int i = 0; i < here.Length; i++) { -#if NETFRAMEWORK if (here[i] != there[i] && !here[i].IsUnloadable && !there[i].IsUnloadable) -#else - if (here[i] != there[i] && here[i].Name != there[i].Name && !here[i].IsUnloadable && !there[i].IsUnloadable) -#endif { #if IMPORTER StaticCompiler.LinkageError("Method \"{2}.{3}{4}\" has a argument type \"{0}\" instead of type \"{1}\" as expected by \"{5}\"", there[i], here[i], cpi.GetClassType().Name, cpi.Name, cpi.Signature, classFile.Name); @@ -2903,9 +2893,7 @@ ClassFile.ConstantPoolItemInvokeDynamic GetInvokeDynamic(int index) { var item = classFile.GetInvokeDynamic(new InvokeDynamicConstantHandle(checked((ushort)index))); if (item != null) - { return item; - } } catch (OverflowException) { diff --git a/src/IKVM.Runtime/MethodHandleUtil.jniexport.cs b/src/IKVM.Runtime/MethodHandleUtil.jniexport.cs index d44636cb6..d3fd060a5 100644 --- a/src/IKVM.Runtime/MethodHandleUtil.jniexport.cs +++ b/src/IKVM.Runtime/MethodHandleUtil.jniexport.cs @@ -28,13 +28,15 @@ Jeroen Frijters using System.Reflection.Emit; using System.Runtime.CompilerServices; +using IKVM.CoreLib.Symbols; + namespace IKVM.Runtime { partial class MethodHandleUtil { - internal Type GetMemberWrapperDelegateType(global::java.lang.invoke.MethodType type) + internal ITypeSymbol GetMemberWrapperDelegateType(global::java.lang.invoke.MethodType type) { #if FIRST_PASS throw new NotImplementedException(); @@ -45,7 +47,7 @@ internal Type GetMemberWrapperDelegateType(global::java.lang.invoke.MethodType t #if FIRST_PASS == false - Type CreateMethodHandleDelegateType(java.lang.invoke.MethodType type) + ITypeSymbol CreateMethodHandleDelegateType(java.lang.invoke.MethodType type) { var args = new RuntimeJavaType[type.parameterCount()]; for (int i = 0; i < args.Length; i++) @@ -58,20 +60,20 @@ Type CreateMethodHandleDelegateType(java.lang.invoke.MethodType type) return CreateMethodHandleDelegateType(args, ret); } - static Type[] GetParameterTypes(MethodBase mb) + static ITypeSymbol[] GetParameterTypes(IMethodBaseSymbol mb) { var pi = mb.GetParameters(); - var args = new Type[pi.Length]; + var args = new ITypeSymbol[pi.Length]; for (int i = 0; i < args.Length; i++) args[i] = pi[i].ParameterType; return args; } - internal static Type[] GetParameterTypes(Type thisType, MethodBase mb) + internal static ITypeSymbol[] GetParameterTypes(ITypeSymbol thisType, IMethodBaseSymbol mb) { var pi = mb.GetParameters(); - var args = new Type[pi.Length + 1]; + var args = new ITypeSymbol[pi.Length + 1]; args[0] = thisType; for (int i = 1; i < args.Length; i++) args[i] = pi[i - 1].ParameterType; @@ -79,7 +81,7 @@ internal static Type[] GetParameterTypes(Type thisType, MethodBase mb) return args; } - internal java.lang.invoke.MethodType GetDelegateMethodType(Type type) + internal java.lang.invoke.MethodType GetDelegateMethodType(ITypeSymbol type) { java.lang.Class[] types; var mi = GetDelegateInvokeMethod(type); @@ -124,13 +126,13 @@ internal sealed class DynamicMethodBuilder readonly RuntimeContext context; readonly java.lang.invoke.MethodType type; readonly int firstArg; - readonly Type delegateType; + readonly ITypeSymbol delegateType; readonly object firstBoundValue; readonly object secondBoundValue; - readonly Type container; + readonly ITypeSymbol container; readonly DynamicMethod dm; readonly CodeEmitter ilgen; - readonly Type packedArgType; + readonly ITypeSymbol packedArgType; readonly int packedArgPos; sealed class Container @@ -159,7 +161,7 @@ public Container(T1 target, T2 value) /// /// /// - DynamicMethodBuilder(RuntimeContext context, string name, java.lang.invoke.MethodType type, Type container, object target, object value, Type owner, bool useBasicTypes) + DynamicMethodBuilder(RuntimeContext context, string name, java.lang.invoke.MethodType type, ITypeSymbol container, object target, object value, ITypeSymbol owner, bool useBasicTypes) { this.context = context ?? throw new ArgumentNullException(nameof(context)); this.type = type; @@ -171,7 +173,7 @@ public Container(T1 target, T2 value) var mi = context.MethodHandleUtil.GetDelegateInvokeMethod(delegateType); - Type[] paramTypes; + ITypeSymbol[] paramTypes; if (container != null) { firstArg = 1; @@ -180,17 +182,17 @@ public Container(T1 target, T2 value) else if (target != null) { firstArg = 1; - paramTypes = GetParameterTypes(target.GetType(), mi); + paramTypes = GetParameterTypes(context.Resolver.GetSymbol(target.GetType()), mi); } else { paramTypes = GetParameterTypes(mi); } - if (!ReflectUtil.CanOwnDynamicMethod(owner)) - owner = typeof(DynamicMethodBuilder); + if (!ReflectUtil.CanOwnDynamicMethod(owner.AsReflection())) + owner = context.Resolver.GetSymbol(typeof(DynamicMethodBuilder)); - dm = new DynamicMethod(name, mi.ReturnType, paramTypes, owner, true); + dm = new DynamicMethod(name, mi.ReturnType.AsReflection(), paramTypes.AsReflection(), owner.AsReflection(), true); ilgen = context.CodeEmitterFactory.Create(dm); if (type.parameterCount() > MaxArity) @@ -211,9 +213,9 @@ internal static Delegate CreateVoidAdapter(RuntimeContext context, global::java. var targetDelegateType = context.MethodHandleUtil.GetMemberWrapperDelegateType(type); dm.Ldarg(0); dm.EmitCheckcast(context.JavaBase.TypeOfJavaLangInvokeMethodHandle); - dm.ilgen.Emit(OpCodes.Ldfld, typeof(global::java.lang.invoke.MethodHandle).GetField(METHOD_HANDLE_FORM_FIELD, BindingFlags.Instance | BindingFlags.NonPublic)); - dm.ilgen.Emit(OpCodes.Ldfld, typeof(global::java.lang.invoke.LambdaForm).GetField(LAMBDA_FORM_VMENTRY_FIELD, BindingFlags.Instance | BindingFlags.NonPublic)); - dm.ilgen.Emit(OpCodes.Ldfld, typeof(global::java.lang.invoke.MemberName).GetField(MEMBER_NAME_VMTARGET_FIELD, BindingFlags.Instance | BindingFlags.NonPublic)); + dm.ilgen.Emit(OpCodes.Ldfld, context.Resolver.GetSymbol(typeof(global::java.lang.invoke.MethodHandle)).GetField(METHOD_HANDLE_FORM_FIELD, BindingFlags.Instance | BindingFlags.NonPublic)); + dm.ilgen.Emit(OpCodes.Ldfld, context.Resolver.GetSymbol(typeof(global::java.lang.invoke.LambdaForm)).GetField(LAMBDA_FORM_VMENTRY_FIELD, BindingFlags.Instance | BindingFlags.NonPublic)); + dm.ilgen.Emit(OpCodes.Ldfld, context.Resolver.GetSymbol(typeof(global::java.lang.invoke.MemberName)).GetField(MEMBER_NAME_VMTARGET_FIELD, BindingFlags.Instance | BindingFlags.NonPublic)); dm.ilgen.Emit(OpCodes.Castclass, targetDelegateType); for (int i = 0; i < type.parameterCount(); i++) dm.Ldarg(i); @@ -229,15 +231,15 @@ internal static DynamicMethod CreateInvokeExact(RuntimeContext context, global:: { FinishTypes(type); - var dm = new DynamicMethodBuilder(context, "InvokeExact", type, typeof(java.lang.invoke.MethodHandle), null, null, null, false); + var dm = new DynamicMethodBuilder(context, "InvokeExact", type, context.Resolver.GetSymbol(typeof(java.lang.invoke.MethodHandle)), null, null, null, false); var targetDelegateType = context.MethodHandleUtil.GetMemberWrapperDelegateType(type.insertParameterTypes(0, context.JavaBase.TypeOfJavaLangInvokeMethodHandle.ClassObject)); dm.ilgen.Emit(OpCodes.Ldarg_0); - dm.ilgen.Emit(OpCodes.Ldfld, typeof(global::java.lang.invoke.MethodHandle).GetField(METHOD_HANDLE_FORM_FIELD, BindingFlags.Instance | BindingFlags.NonPublic)); - dm.ilgen.Emit(OpCodes.Ldfld, typeof(global::java.lang.invoke.LambdaForm).GetField(LAMBDA_FORM_VMENTRY_FIELD, BindingFlags.Instance | BindingFlags.NonPublic)); + dm.ilgen.Emit(OpCodes.Ldfld, context.Resolver.GetSymbol(typeof(global::java.lang.invoke.MethodHandle)).GetField(METHOD_HANDLE_FORM_FIELD, BindingFlags.Instance | BindingFlags.NonPublic)); + dm.ilgen.Emit(OpCodes.Ldfld, context.Resolver.GetSymbol(typeof(global::java.lang.invoke.LambdaForm)).GetField(LAMBDA_FORM_VMENTRY_FIELD, BindingFlags.Instance | BindingFlags.NonPublic)); if (type.returnType() == java.lang.Void.TYPE) - dm.ilgen.Emit(OpCodes.Call, typeof(MethodHandleUtil).GetMethod(nameof(GetVoidAdapter), BindingFlags.Static | BindingFlags.NonPublic)); + dm.ilgen.Emit(OpCodes.Call, context.Resolver.GetSymbol(typeof(MethodHandleUtil)).GetMethod(nameof(GetVoidAdapter), BindingFlags.Static | BindingFlags.NonPublic)); else - dm.ilgen.Emit(OpCodes.Ldfld, typeof(java.lang.invoke.MemberName).GetField(MEMBER_NAME_VMTARGET_FIELD, BindingFlags.Instance | BindingFlags.NonPublic)); + dm.ilgen.Emit(OpCodes.Ldfld, context.Resolver.GetSymbol(typeof(java.lang.invoke.MemberName)).GetField(MEMBER_NAME_VMTARGET_FIELD, BindingFlags.Instance | BindingFlags.NonPublic)); dm.ilgen.Emit(OpCodes.Castclass, targetDelegateType); dm.ilgen.Emit(OpCodes.Ldarg_0); @@ -273,8 +275,8 @@ internal static Delegate CreateMethodHandleLinkTo(RuntimeContext context, java.l var delegateType = context.MethodHandleUtil.GetMemberWrapperDelegateType(type.dropParameterTypes(type.parameterCount() - 1, type.parameterCount())); var dm = new DynamicMethodBuilder(context, "DirectMethodHandle." + mn.getName() + type, type, null, null, null, null, true); dm.Ldarg(type.parameterCount() - 1); - dm.ilgen.EmitCastclass(typeof(java.lang.invoke.MemberName)); - dm.ilgen.Emit(OpCodes.Ldfld, typeof(java.lang.invoke.MemberName).GetField(MEMBER_NAME_VMTARGET_FIELD, BindingFlags.Instance | BindingFlags.NonPublic)); + dm.ilgen.EmitCastclass(context.Resolver.GetSymbol(typeof(java.lang.invoke.MemberName))); + dm.ilgen.Emit(OpCodes.Ldfld, context.Resolver.GetSymbol(typeof(java.lang.invoke.MemberName)).GetField(MEMBER_NAME_VMTARGET_FIELD, BindingFlags.Instance | BindingFlags.NonPublic)); dm.ilgen.Emit(OpCodes.Castclass, delegateType); for (int i = 0, count = type.parameterCount() - 1; i < count; i++) dm.Ldarg(i); @@ -288,7 +290,7 @@ internal static Delegate CreateMethodHandleInvoke(RuntimeContext context, java.l { var type = mn.getMethodType().insertParameterTypes(0, mn.getDeclaringClass()); var targetDelegateType = context.MethodHandleUtil.GetMemberWrapperDelegateType(type); - var dm = new DynamicMethodBuilder(context, "DirectMethodHandle." + mn.getName() + type, type, typeof(Container<,>).MakeGenericType(typeof(object), typeof(IKVM.Runtime.InvokeCache<>).MakeGenericType(targetDelegateType)), null, null, null, true); + var dm = new DynamicMethodBuilder(context, "DirectMethodHandle." + mn.getName() + type, type, context.Resolver.GetSymbol(typeof(Container<,>)).MakeGenericType(context.Types.Object, context.Resolver.GetSymbol(typeof(IKVM.Runtime.InvokeCache<>)).MakeGenericType(targetDelegateType)), null, null, null, true); dm.Ldarg(0); dm.EmitCheckcast(context.JavaBase.TypeOfJavaLangInvokeMethodHandle); switch (mn.getName()) @@ -332,7 +334,7 @@ internal static Delegate CreateDynamicOnly(RuntimeContext context, RuntimeJavaMe dm.Ldarg(0); dm.BoxArgs(1); } - dm.Callvirt(typeof(RuntimeJavaMethod).GetMethod("Invoke", BindingFlags.Instance | BindingFlags.NonPublic)); + dm.Callvirt(context.Resolver.GetSymbol(typeof(RuntimeJavaMethod)).GetMethod("Invoke", BindingFlags.Instance | BindingFlags.NonPublic)); dm.UnboxReturnValue(); dm.Ret(); @@ -439,12 +441,12 @@ internal static Delegate CreateMemberName(RuntimeContext context, RuntimeJavaMet return dm.CreateDelegate(); } - internal void Call(MethodInfo method) + internal void Call(IMethodSymbol method) { ilgen.Emit(OpCodes.Call, method); } - internal void Callvirt(MethodInfo method) + internal void Callvirt(IMethodSymbol method) { ilgen.Emit(OpCodes.Callvirt, method); } @@ -459,7 +461,7 @@ internal void Callvirt(RuntimeJavaMethod mw) mw.EmitCallvirt(ilgen); } - internal void CallDelegate(Type delegateType) + internal void CallDelegate(ITypeSymbol delegateType) { context.MethodHandleUtil.EmitCallDelegateInvokeMethod(ilgen, delegateType); } @@ -512,8 +514,8 @@ internal Delegate CreateDelegate() //ilgen.DumpMethod(); ilgen.DoEmit(); return ValidateDelegate(firstArg == 0 - ? dm.CreateDelegate(delegateType) - : dm.CreateDelegate(delegateType, container == null ? firstBoundValue : Activator.CreateInstance(container, firstBoundValue, secondBoundValue))); + ? dm.CreateDelegate(delegateType.AsReflection()) + : dm.CreateDelegate(delegateType.AsReflection(), container == null ? firstBoundValue : Activator.CreateInstance(container.AsReflection(), firstBoundValue, secondBoundValue))); } internal void BoxArgs(int start) @@ -578,14 +580,14 @@ internal void EmitCheckcast(RuntimeJavaType tw) tw.EmitCheckcast(ilgen); } - internal void EmitCastclass(Type type) + internal void EmitCastclass(ITypeSymbol type) { ilgen.EmitCastclass(type); } internal void EmitWriteLine() { - ilgen.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(object) })); + ilgen.Emit(OpCodes.Call, context.Resolver.GetSymbol(typeof(Console)).GetMethod("WriteLine", [context.Types.Object])); } internal void CastByte() @@ -627,10 +629,10 @@ static Delegate ValidateDelegate(Delegate d) return d; } - internal Type GetDelegateTypeForInvokeExact(global::java.lang.invoke.MethodType type) + internal ITypeSymbol GetDelegateTypeForInvokeExact(global::java.lang.invoke.MethodType type) { - type._invokeExactDelegateType ??= CreateMethodHandleDelegateType(type); - return type._invokeExactDelegateType; + type._invokeExactDelegateType ??= CreateMethodHandleDelegateType(type).AsReflection(); + return context.Resolver.GetSymbol(type._invokeExactDelegateType); } internal T GetDelegateForInvokeExact(global::java.lang.invoke.MethodHandle mh) @@ -640,13 +642,13 @@ internal T GetDelegateForInvokeExact(global::java.lang.invoke.MethodHandle mh if (mh._invokeExactDelegate == null) { type._invokeExactDynamicMethod ??= DynamicMethodBuilder.CreateInvokeExact(context, type); - mh._invokeExactDelegate = type._invokeExactDynamicMethod.CreateDelegate(GetDelegateTypeForInvokeExact(type), mh); + mh._invokeExactDelegate = type._invokeExactDynamicMethod.CreateDelegate(GetDelegateTypeForInvokeExact(type).AsReflection(), mh); var del = mh._invokeExactDelegate as T; if (del != null) return del; } - throw java.lang.invoke.Invokers.newWrongMethodTypeException(GetDelegateMethodType(typeof(T)), type); + throw java.lang.invoke.Invokers.newWrongMethodTypeException(GetDelegateMethodType(context.Resolver.GetSymbol(typeof(T))), type); } /// @@ -668,7 +670,7 @@ internal static object GetVoidAdapter(java.lang.invoke.MemberName mn) return type.voidAdapter; } - internal void LoadPackedArg(CodeEmitter ilgen, int index, int firstArg, int packedArgPos, Type packedArgType) + internal void LoadPackedArg(CodeEmitter ilgen, int index, int firstArg, int packedArgPos, ITypeSymbol packedArgType) { index += firstArg; if (index >= packedArgPos) diff --git a/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs b/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs index 9869a856e..d064ee8df 100644 --- a/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs +++ b/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs @@ -705,7 +705,7 @@ internal virtual RuntimeJavaType GetJavaTypeFromAssemblyType(ITypeSymbol type) if (javaType.TypeAsTBD != type && (!javaType.IsRemapped || javaType.TypeAsBaseType != type)) { #if IMPORTER - throw new FatalCompilerErrorException(DiagnosticEvent.AssemblyContainsDuplicateClassNames(type.FullName, javaType.TypeAsTBD.FullName, javaType.Name, type.Assembly.FullName)); + throw new DiagnosticEventException(DiagnosticEvent.AssemblyContainsDuplicateClassNames(type.FullName, javaType.TypeAsTBD.FullName, javaType.Name, type.Assembly.FullName)); #else throw new InternalException($"\nType \"{type.FullName}\" and \"{javaType.TypeAsTBD.FullName}\" both map to the same name \"{javaType.Name}\"."); #endif diff --git a/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishContext.cs b/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishContext.cs index 6c26b41fc..a300dae6e 100644 --- a/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishContext.cs +++ b/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishContext.cs @@ -1661,11 +1661,11 @@ public JniBuilder(RuntimeContext context) IMethodSymbol UnwrapLocalRefMethod => LocalRefStructType.GetMethod("UnwrapLocalRef"); - IMethodSymbol WriteLineMethod => context.Resolver.ResolveType(typeof(Console).FullName).GetMethod("WriteLine", [context.Types.Object]); + IMethodSymbol WriteLineMethod => context.Resolver.ResolveSystemType(typeof(Console).FullName).GetMethod("WriteLine", [context.Types.Object]); - IMethodSymbol MonitorEnterMethod => context.Resolver.ResolveType(typeof(System.Threading.Monitor).FullName).GetMethod("Enter", [context.Types.Object]); + IMethodSymbol MonitorEnterMethod => context.Resolver.ResolveSystemType(typeof(System.Threading.Monitor).FullName).GetMethod("Enter", [context.Types.Object]); - IMethodSymbol MonitorExitMethod => context.Resolver.ResolveType(typeof(System.Threading.Monitor).FullName).GetMethod("Exit", [context.Types.Object]); + IMethodSymbol MonitorExitMethod => context.Resolver.ResolveSystemType(typeof(System.Threading.Monitor).FullName).GetMethod("Exit", [context.Types.Object]); internal void Generate(RuntimeByteCodeJavaType.FinishContext context, CodeEmitter ilGenerator, RuntimeByteCodeJavaType wrapper, RuntimeJavaMethod mw, ITypeSymbolBuilder typeBuilder, ClassFile classFile, ClassFile.Method m, RuntimeJavaType[] args, bool thruProxy) { @@ -1896,7 +1896,7 @@ void EmitCallerIDStub(RuntimeJavaMethod mw, string[] parameterNames) } ilgen.Emit(OpCodes.Ldc_I4_1); ilgen.Emit(OpCodes.Ldc_I4_0); - ilgen.Emit(OpCodes.Newobj, context.Resolver.ResolveType(typeof(StackFrame).FullName).GetConstructor([context.Types.Int32, context.Types.Boolean])); + ilgen.Emit(OpCodes.Newobj, context.Resolver.ResolveSystemType(typeof(StackFrame).FullName).GetConstructor([context.Types.Int32, context.Types.Boolean])); var callerID = context.JavaBase.TypeOfIkvmInternalCallerID.GetMethodWrapper("create", "(Lcli.System.Diagnostics.StackFrame;)Likvm.internal.CallerID;", false); callerID.Link(); callerID.EmitCall(ilgen); diff --git a/src/IKVM.Runtime/RuntimeByteCodeJavaType.cs b/src/IKVM.Runtime/RuntimeByteCodeJavaType.cs index ea1dadac6..3c960048f 100644 --- a/src/IKVM.Runtime/RuntimeByteCodeJavaType.cs +++ b/src/IKVM.Runtime/RuntimeByteCodeJavaType.cs @@ -88,9 +88,9 @@ private static void CheckMissing(RuntimeJavaType prev, RuntimeJavaType tw) { var mt = ReflectUtil.GetMissingType(missing.MissingType); if (mt.Assembly.IsMissing) - throw new FatalCompilerErrorException(DiagnosticEvent.MissingBaseTypeReference(mt.FullName, mt.Assembly.FullName)); + throw new DiagnosticEventException(DiagnosticEvent.MissingBaseTypeReference(mt.FullName, mt.Assembly.FullName)); - throw new FatalCompilerErrorException(DiagnosticEvent.MissingBaseType(mt.FullName, mt.Assembly.FullName, prev.TypeAsBaseType.FullName, prev.TypeAsBaseType.Module.Name)); + throw new DiagnosticEventException(DiagnosticEvent.MissingBaseType(mt.FullName, mt.Assembly.FullName, prev.TypeAsBaseType.FullName, prev.TypeAsBaseType.Module.Name)); } foreach (RuntimeJavaType iface in tw.Interfaces) @@ -657,7 +657,7 @@ private bool IsPInvokeMethod(ClassFile.Method m) { if (method.Attributes != null) foreach (IKVM.Tools.Importer.MapXml.Attribute attr in method.Attributes) - if (Context.StaticCompiler.GetType(classLoader, attr.Type) == Context.Resolver.ResolveCoreType(typeof(System.Runtime.InteropServices.DllImportAttribute).FullName)) + if (Context.StaticCompiler.GetType(classLoader, attr.Type) == Context.Resolver.ResolveSystemType(typeof(System.Runtime.InteropServices.DllImportAttribute).FullName)) return true; break; diff --git a/src/IKVM.Runtime/RuntimeClassLoaderFactory.cs b/src/IKVM.Runtime/RuntimeClassLoaderFactory.cs index 27f07f5db..6e564b166 100644 --- a/src/IKVM.Runtime/RuntimeClassLoaderFactory.cs +++ b/src/IKVM.Runtime/RuntimeClassLoaderFactory.cs @@ -102,17 +102,17 @@ internal void LoadRemappedTypes() // if we're compiling the base assembly, we won't be able to resolve one if (context.Options.Bootstrap == false && remappedTypes.Count == 0) { - var baseAssembly = context.Resolver.ResolveBaseAssembly(); + var baseAssembly = context.Resolver.GetBaseAssembly(); var remapped = context.AttributeHelper.GetRemappedClasses(baseAssembly); if (remapped.Length > 0) { foreach (var r in remapped) - remappedTypes.Add(context.Resolver.ImportType(r.RemappedType), r.Name); + remappedTypes.Add(context.Resolver.GetSymbol(r.RemappedType), r.Name); } else { #if IMPORTER - throw new FatalCompilerErrorException(DiagnosticEvent.CoreClassesMissing()); + throw new DiagnosticEventException(DiagnosticEvent.CoreClassesMissing()); #else throw new InternalException("Failed to find core classes in core library."); #endif @@ -283,7 +283,7 @@ internal RuntimeJavaType LoadClassCritical(string name) #if IMPORTER var wrapper = GetBootstrapClassLoader().TryLoadClassByName(name); if (wrapper == null) - throw new FatalCompilerErrorException(DiagnosticEvent.CriticalClassNotFound(name)); + throw new DiagnosticEventException(DiagnosticEvent.CriticalClassNotFound(name)); return wrapper; #else @@ -384,9 +384,9 @@ internal RuntimeClassLoader GetAssemblyClassLoaderByName(string name) return GetGenericClassLoaderByName(name); #if NETFRAMEWORK - return context.AssemblyClassLoaderFactory.FromAssembly(context.Resolver.ImportAssembly( Assembly.Load(name))); + return context.AssemblyClassLoaderFactory.FromAssembly(context.Resolver.GetSymbol(Assembly.Load(name))); #else - return context.AssemblyClassLoaderFactory.FromAssembly(context.Resolver.ImportAssembly(AssemblyLoadContext.GetLoadContext(typeof(RuntimeClassLoader).Assembly).LoadFromAssemblyName(new AssemblyName(name)))); + return context.AssemblyClassLoaderFactory.FromAssembly(context.Resolver.GetSymbol(AssemblyLoadContext.GetLoadContext(typeof(RuntimeClassLoader).Assembly).LoadFromAssemblyName(new AssemblyName(name)))); #endif } diff --git a/src/IKVM.Runtime/RuntimeContextOptions.cs b/src/IKVM.Runtime/RuntimeContextOptions.cs index 159bef830..20f1f047c 100644 --- a/src/IKVM.Runtime/RuntimeContextOptions.cs +++ b/src/IKVM.Runtime/RuntimeContextOptions.cs @@ -4,11 +4,8 @@ internal class RuntimeContextOptions { -#if NETFRAMEWORK - internal const string DefaultDynamicAssemblySuffixAndPublicKey = "-ikvm-runtime-injected, PublicKey=00240000048000009400000006020000002400005253413100040000010001009D674F3D63B8D7A4C428BD7388341B025C71AA61C6224CD53A12C21330A3159D300051FE2EED154FE30D70673A079E4529D0FD78113DCA771DA8B0C1EF2F77B73651D55645B0A4294F0AF9BF7078432E13D0F46F951D712C2FCF02EB15552C0FE7817FC0AED58E0984F86661BF64D882F29B619899DD264041E7D4992548EB9E"; -#else - internal const string DefaultDynamicAssemblySuffixAndPublicKey = "-ikvm-runtime-injected"; -#endif + internal const string SignedDefaultDynamicAssemblySuffixAndPublicKey = "-ikvm-runtime-injected, PublicKey=00240000048000009400000006020000002400005253413100040000010001009D674F3D63B8D7A4C428BD7388341B025C71AA61C6224CD53A12C21330A3159D300051FE2EED154FE30D70673A079E4529D0FD78113DCA771DA8B0C1EF2F77B73651D55645B0A4294F0AF9BF7078432E13D0F46F951D712C2FCF02EB15552C0FE7817FC0AED58E0984F86661BF64D882F29B619899DD264041E7D4992548EB9E"; + internal const string UnsignedDefaultDynamicAssemblySuffixAndPublicKey = "-ikvm-runtime-injected"; readonly bool bootstrap; readonly string dynamicAssemblySuffixAndPublicKey; @@ -21,7 +18,7 @@ internal class RuntimeContextOptions public RuntimeContextOptions(bool bootstrap = false, string dynamicAssemblySuffixAndPublicKey = null) { this.bootstrap = bootstrap; - this.dynamicAssemblySuffixAndPublicKey = dynamicAssemblySuffixAndPublicKey ?? DefaultDynamicAssemblySuffixAndPublicKey; + this.dynamicAssemblySuffixAndPublicKey = dynamicAssemblySuffixAndPublicKey ?? UnsignedDefaultDynamicAssemblySuffixAndPublicKey; } /// diff --git a/src/IKVM.Runtime/RuntimeJavaType.cs b/src/IKVM.Runtime/RuntimeJavaType.cs index 6fb940ce1..c127cf360 100644 --- a/src/IKVM.Runtime/RuntimeJavaType.cs +++ b/src/IKVM.Runtime/RuntimeJavaType.cs @@ -302,7 +302,7 @@ internal static RuntimeJavaType FromClass(java.lang.Class clazz) return FromClass(clazz); } - var symbol = JVM.Context.Resolver.ImportType(type); + var symbol = JVM.Context.Resolver.GetSymbol(type); if (type == typeof(void) || type.IsPrimitive || JVM.Context.ClassLoaderFactory.IsRemappedType(symbol)) tw = JVM.Context.ManagedJavaTypeFactory.GetJavaTypeFromManagedType(symbol); else diff --git a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.RemappedJavaType.cs b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.RemappedJavaType.cs index ca2fb0d06..bf52e19ed 100644 --- a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.RemappedJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.RemappedJavaType.cs @@ -58,7 +58,7 @@ internal RemappedJavaType(RuntimeContext context, string name, ITypeSymbol type) base(context, name, type) { var attr = Context.AttributeHelper.GetRemappedType(type) ?? throw new InvalidOperationException(); - remappedType = Context.Resolver.ImportType(attr.Type); + remappedType = Context.Resolver.GetSymbol(attr.Type); } internal override ITypeSymbol TypeAsTBD => remappedType; diff --git a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs index cce286431..840ebdc54 100644 --- a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs @@ -137,7 +137,7 @@ static RuntimeJavaType GetBaseTypeWrapper(RuntimeContext context, ITypeSymbol ty var attr = context.AttributeHelper.GetRemappedType(type); if (attr != null) { - if (context.Resolver.ImportType(attr.Type) == context.Types.Object) + if (context.Resolver.GetSymbol(attr.Type) == context.Types.Object) return null; else return context.JavaBase.TypeOfJavaLangObject; @@ -312,7 +312,7 @@ private RuntimeJavaType[] GetInterfaces() if (interfaceWrappers[i] == null) { #if IMPORTER - throw new FatalCompilerErrorException(DiagnosticEvent.UnableToResolveInterface(interfaceNames[i], ToString())); + throw new DiagnosticEventException(DiagnosticEvent.UnableToResolveInterface(interfaceNames[i], ToString())); #else throw new InternalException($"Unable to resolve interface {interfaceNames[i]} on type {this}"); #endif @@ -1183,7 +1183,7 @@ internal sealed class CompiledAnnotation : Annotation internal CompiledAnnotation(RuntimeContext context, ITypeSymbol type) { this.context = context ?? throw new ArgumentNullException(nameof(context)); - constructor = type.GetConstructor([context.Resolver.ResolveCoreType(typeof(object).FullName).MakeArrayType()]); + constructor = type.GetConstructor([context.Types.Object.MakeArrayType()]); } private ICustomAttributeBuilder MakeCustomAttributeBuilder(RuntimeClassLoader loader, object annotation) @@ -1254,7 +1254,7 @@ internal override ITypeSymbol EnumType internal override string GetSourceFileName() { - var attr = type.GetCustomAttribute(Context.Resolver.ImportType(typeof(SourceFileAttribute))); + var attr = type.GetCustomAttribute(Context.Resolver.GetSymbol(typeof(SourceFileAttribute))); if (attr != null && attr.Value.ConstructorArguments.Length > 0) return (string)attr.Value.ConstructorArguments[0].Value; @@ -1264,7 +1264,7 @@ internal override string GetSourceFileName() if (IsNestedTypeAnonymousOrLocalClass(type)) return Context.ClassLoaderFactory.GetJavaTypeFromType(type.DeclaringType).GetSourceFileName(); - if (type.Module.IsDefined(Context.Resolver.ImportType(typeof(SourceFileAttribute)), false)) + if (type.Module.IsDefined(Context.Resolver.GetSymbol(typeof(SourceFileAttribute)), false)) return type.Name + ".java"; return null; @@ -1272,7 +1272,7 @@ internal override string GetSourceFileName() internal override int GetSourceLineNumber(IMethodBaseSymbol mb, int ilOffset) { - var attr = type.GetCustomAttribute(Context.Resolver.ImportType(typeof(LineNumberTableAttribute))); + var attr = type.GetCustomAttribute(Context.Resolver.GetSymbol(typeof(LineNumberTableAttribute))); if (attr != null && attr.Value.Constructor != null) return ((LineNumberTableAttribute)attr.Value.Constructor.AsReflection().Invoke(attr.Value.ConstructorArguments.Cast().ToArray())).GetLineNumber(ilOffset); diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.cs index ae41f128c..b762ef101 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.cs @@ -71,7 +71,7 @@ internal AttributeAnnotationJavaType(RuntimeContext context, string name, ITypeS #if IMPORTER || EXPORTER this.fakeType = context.FakeTypes.GetAttributeType(attributeType); #elif !FIRST_PASS - this.fakeType = context.Resolver.ImportType(typeof(ikvm.@internal.AttributeAnnotation<>)).MakeGenericType(attributeType); + this.fakeType = context.Resolver.GetSymbol(typeof(ikvm.@internal.AttributeAnnotation<>)).MakeGenericType(attributeType); #endif this.attributeType = attributeType; } diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.DelegateInnerClassJavaType.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.DelegateInnerClassJavaType.cs index f3703bba6..0173a94b4 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.DelegateInnerClassJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.DelegateInnerClassJavaType.cs @@ -53,7 +53,7 @@ internal DelegateInnerClassJavaType(RuntimeContext context, string name, ITypeSy #if IMPORTER || EXPORTER this.fakeType = context.FakeTypes.GetDelegateType(delegateType); #elif !FIRST_PASS - this.fakeType = context.Resolver.ImportType(typeof(ikvm.@internal.DelegateInterface<>)).MakeGenericType(delegateType); + this.fakeType = context.Resolver.GetSymbol(typeof(ikvm.@internal.DelegateInterface<>)).MakeGenericType(delegateType); #endif var invoke = delegateType.GetMethod("Invoke"); var parameters = invoke.GetParameters(); diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.EnumEnumJavaType.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.EnumEnumJavaType.cs index b9765c952..709b00704 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.EnumEnumJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.EnumEnumJavaType.cs @@ -56,7 +56,7 @@ internal EnumEnumJavaType(RuntimeContext context, string name, ITypeSymbol enumT #if IMPORTER || EXPORTER this.fakeType = context.FakeTypes.GetEnumType(enumType); #elif !FIRST_PASS - this.fakeType = context.Resolver.ImportType(typeof(ikvm.@internal.EnumEnum<>)).MakeGenericType(enumType); + this.fakeType = context.Resolver.GetSymbol(typeof(ikvm.@internal.EnumEnum<>)).MakeGenericType(enumType); #endif } diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.cs index 758e61747..7b20b06a8 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.cs @@ -541,7 +541,7 @@ protected override void LazyPublishMembers() #if !IMPORTER && !EXPORTER && !FIRST_PASS // support serializing .NET exceptions (by replacing them with a placeholder exception) - if (Context.Types.Exception.IsAssignableFrom(type) && Context.Resolver.ImportType(typeof(java.io.Serializable.__Interface)).IsAssignableFrom(type) == false && methodsList.ContainsKey("writeReplace()Ljava.lang.Object;") == false) + if (Context.Types.Exception.IsAssignableFrom(type) && Context.Resolver.GetSymbol(typeof(java.io.Serializable.__Interface)).IsAssignableFrom(type) == false && methodsList.ContainsKey("writeReplace()Ljava.lang.Object;") == false) methodsList.Add("writeReplace()Ljava.lang.Object;", new ExceptionWriteReplaceJavaMethod(this)); #endif diff --git a/src/IKVM.Runtime/StubGen/StubGenerator.cs b/src/IKVM.Runtime/StubGen/StubGenerator.cs index 51d7f4833..2706d4c18 100644 --- a/src/IKVM.Runtime/StubGen/StubGenerator.cs +++ b/src/IKVM.Runtime/StubGen/StubGenerator.cs @@ -329,7 +329,7 @@ void AddExceptionsAttribute(ClassFileBuilder builder, RuntimeJavaType type, Runt if (throws.types != null) foreach (var ex in throws.types) - e.Class(builder.Constants.GetOrAddClass(context.ClassLoaderFactory.GetJavaTypeFromType(context.Resolver.ImportType(ex)).Name.Replace('.', '/'))); + e.Class(builder.Constants.GetOrAddClass(context.ClassLoaderFactory.GetJavaTypeFromType(context.Resolver.GetSymbol(ex)).Name.Replace('.', '/'))); }); } } @@ -580,7 +580,7 @@ bool EncodeAnnotations(ClassFileBuilder builder, ref AnnotationTableEncoder enco #if !FIRST_PASS && !EXPORTER if (source != null) { - foreach (var cad in CustomAttributeData.GetCustomAttributes(source)) + foreach (var cad in source.GetCustomAttributes()) { var ann = GetAnnotation(cad); if (ann != null) @@ -615,7 +615,7 @@ bool EncodeParameterAnnotations(ClassFileBuilder builder, ref ParameterAnnotatio { encoder.ParameterAnnotation(e2 => { - foreach (var cad in CustomAttributeData.GetCustomAttributes(parameters[i])) + foreach (var cad in parameters[i].GetCustomAttributes()) { var ann = GetAnnotation(cad); if (ann != null) @@ -913,12 +913,12 @@ public PackageConstantHandle Map(PackageConstantHandle handle) object[] GetAnnotation(CustomAttribute cad) { // attribute is either a AnnotationAttributeBase or a DynamicAnnotationAttribute with a single object[] in our internal annotation format - if (cad.ConstructorArguments.Count == 1 && cad.ConstructorArguments[0].ArgumentType == typeof(object[]) && (cad.Constructor.DeclaringType.BaseType == typeof(ikvm.@internal.AnnotationAttributeBase) || cad.Constructor.DeclaringType == typeof(DynamicAnnotationAttribute))) + if (cad.ConstructorArguments.Length == 1 && cad.ConstructorArguments[0].ArgumentType == context.Types.Object.MakeArrayType() && (cad.Constructor.DeclaringType.BaseType == context.Resolver.ResolveBaseType(typeof(ikvm.@internal.AnnotationAttributeBase).FullName) || cad.Constructor.DeclaringType == context.Resolver.ResolveBaseType(typeof(DynamicAnnotationAttribute).FullName))) { return UnpackArray((IList)cad.ConstructorArguments[0].Value); } - if (cad.Constructor.DeclaringType.BaseType == typeof(ikvm.@internal.AnnotationAttributeBase)) + if (cad.Constructor.DeclaringType.BaseType == context.Resolver.ResolveBaseType(typeof(ikvm.@internal.AnnotationAttributeBase).FullName)) { var annotationType = GetAnnotationInterface(cad); if (annotationType != null) @@ -948,12 +948,12 @@ object[] GetAnnotation(CustomAttribute cad) return null; } - string GetAnnotationInterface(CustomAttributeData cad) + string GetAnnotationInterface(CustomAttribute cad) { - var attr = cad.Constructor.DeclaringType.GetCustomAttributes(typeof(IKVM.Attributes.ImplementsAttribute), false); - if (attr.Length == 1) + var attr = cad.Constructor.DeclaringType.GetCustomAttribute(context.Resolver.ResolveRuntimeType(typeof(ImplementsAttribute).FullName), false); + if (attr != null) { - var interfaces = ((IKVM.Attributes.ImplementsAttribute)attr[0]).Interfaces; + var interfaces = (string[])attr.Value.ConstructorArguments[0].Value; if (interfaces.Length == 1) return interfaces[0]; } @@ -974,11 +974,11 @@ object GetAnnotationValue(CustomAttributeTypedArgument arg) { // if GetWrapperFromType returns null, we've got an ikvmc synthesized .NET enum nested inside a Java enum var tw = context.ClassLoaderFactory.GetJavaTypeFromType(arg.ArgumentType) ?? context.ClassLoaderFactory.GetJavaTypeFromType(arg.ArgumentType.DeclaringType); - return new object[] { IKVM.Attributes.AnnotationDefaultAttribute.TAG_ENUM, EncodeTypeName(tw), Enum.GetName(arg.ArgumentType, arg.Value) }; + return new object[] { IKVM.Attributes.AnnotationDefaultAttribute.TAG_ENUM, EncodeTypeName(tw), arg.ArgumentType.GetEnumName(arg.Value) }; } // argument is directly a type, so we encode it as a TAG_CLASS - if (arg.Value is Type type) + if (arg.Value is ITypeSymbol type) { return new object[] { IKVM.Attributes.AnnotationDefaultAttribute.TAG_CLASS, EncodeTypeName(context.ClassLoaderFactory.GetJavaTypeFromType(type)) }; } diff --git a/src/IKVM.Runtime/Util/Java/Lang/Invoke/NativeInvokerBytecodeGenerator.cs b/src/IKVM.Runtime/Util/Java/Lang/Invoke/NativeInvokerBytecodeGenerator.cs index bb0d5d136..355ca0447 100644 --- a/src/IKVM.Runtime/Util/Java/Lang/Invoke/NativeInvokerBytecodeGenerator.cs +++ b/src/IKVM.Runtime/Util/Java/Lang/Invoke/NativeInvokerBytecodeGenerator.cs @@ -29,10 +29,10 @@ using System; using System.Collections.Generic; -using System.Reflection; using System.Reflection.Emit; using IKVM.Attributes; +using IKVM.CoreLib.Symbols; using java.lang.invoke; @@ -63,11 +63,11 @@ public static MemberName generateCustomizedCode(LambdaForm form, MethodType invo readonly RuntimeContext context; readonly java.lang.invoke.LambdaForm lambdaForm; readonly java.lang.invoke.MethodType invokerType; - readonly Type delegateType; + readonly ITypeSymbol delegateType; readonly DynamicMethod dm; readonly CodeEmitter ilgen; readonly int packedArgPos; - readonly Type packedArgType; + readonly ITypeSymbol packedArgType; readonly CodeEmitterLocal[] locals; readonly List constants = new List(); @@ -112,10 +112,10 @@ internal BailoutException(Bailout reason, object data) this.delegateType = context.MethodHandleUtil.GetMemberWrapperDelegateType(invokerType); var mi = context.MethodHandleUtil.GetDelegateInvokeMethod(delegateType); - var paramTypes = MethodHandleUtil.GetParameterTypes(typeof(object[]), mi); + var paramTypes = MethodHandleUtil.GetParameterTypes(context.Types.Object.MakeArrayType(), mi); // HACK the code we generate is not verifiable (known issue: locals aren't typed correctly), so we stick the DynamicMethod into mscorlib (a security critical assembly) - this.dm = new DynamicMethod(lambdaForm.debugName, mi.ReturnType, paramTypes, typeof(object).Module, true); + this.dm = new DynamicMethod(lambdaForm.debugName, mi.ReturnType.AsReflection(), paramTypes.AsReflection(), typeof(object).Module, true); this.ilgen = context.CodeEmitterFactory.Create(this.dm); if (invokerType.parameterCount() > MethodHandleUtil.MaxArity) { @@ -124,7 +124,7 @@ internal BailoutException(Bailout reason, object data) } else { - this.packedArgPos = Int32.MaxValue; + this.packedArgPos = int.MaxValue; } locals = new CodeEmitterLocal[lambdaForm.names.Length]; @@ -334,7 +334,7 @@ public AnonymousClass(RuntimeContext context) : internal override RuntimeClassLoader ClassLoader => Context.ClassLoaderFactory.GetBootstrapClassLoader(); - internal override Type TypeAsTBD + internal override ITypeSymbol TypeAsTBD { get { throw new InvalidOperationException(); } } @@ -439,7 +439,7 @@ private Delegate generateCustomizedCodeBytes() emitReturn(onStack); ilgen.DoEmit(); - return dm.CreateDelegate(delegateType, constants.ToArray()); + return dm.CreateDelegate(delegateType.AsReflection(), constants.ToArray()); } void emitArrayLoad(Name name) @@ -816,12 +816,12 @@ private Name emitGuardWithCatch(int pos) ilgen.EmitLeave(L_done); // Exceptional case - ilgen.BeginCatchBlock(typeof(Exception)); + ilgen.BeginCatchBlock(context.Types.Exception); // [IKVM] map the exception and store it in a local and exit the handler ilgen.EmitLdc_I4(0); - ilgen.Emit(OpCodes.Call, context.ByteCodeHelperMethods.MapException.MakeGenericMethod(typeof(Exception))); - CodeEmitterLocal exception = ilgen.DeclareLocal(typeof(Exception)); + ilgen.Emit(OpCodes.Call, context.ByteCodeHelperMethods.MapException.MakeGenericMethod(context.Types.Exception)); + CodeEmitterLocal exception = ilgen.DeclareLocal(context.Types.Exception); ilgen.Emit(OpCodes.Stloc, exception); ilgen.EmitLeave(L_handler); ilgen.EndExceptionBlock(); diff --git a/src/IKVM.Runtime/atomic.cs b/src/IKVM.Runtime/atomic.cs index 42f2af31c..7c7b282c8 100644 --- a/src/IKVM.Runtime/atomic.cs +++ b/src/IKVM.Runtime/atomic.cs @@ -143,7 +143,7 @@ public InterlockedMethods(RuntimeContext context) { this.context = context; - var type = context.Resolver.ResolveType(typeof(System.Threading.Interlocked).FullName); + var type = context.Resolver.ResolveSystemType(typeof(System.Threading.Interlocked).FullName); AddInt32 = type.GetMethod("Add", [context.Types.Int32.MakeByRefType(), context.Types.Int32]); CompareExchangeInt32 = type.GetMethod("CompareExchange", [context.Types.Int32.MakeByRefType(), context.Types.Int32, context.Types.Int32]); CompareExchangeInt64 = type.GetMethod("CompareExchange", [context.Types.Int64.MakeByRefType(), context.Types.Int64, context.Types.Int64]); diff --git a/src/IKVM.Runtime/compiler.cs b/src/IKVM.Runtime/compiler.cs index b2da6523b..bc17ee9d9 100644 --- a/src/IKVM.Runtime/compiler.cs +++ b/src/IKVM.Runtime/compiler.cs @@ -1743,7 +1743,7 @@ void Compile(Block block, int startIndex) } case NormalizedByteCode.__multianewarray: { - var localArray = ilGenerator.UnsafeAllocTempLocal(finish.Context.Resolver.ResolveCoreType(typeof(int).FullName).MakeArrayType()); + var localArray = ilGenerator.UnsafeAllocTempLocal(finish.Context.Types.Int32.MakeArrayType()); var localInt = ilGenerator.UnsafeAllocTempLocal(finish.Context.Types.Int32); ilGenerator.EmitLdc_I4(instr.Arg2); ilGenerator.Emit(System.Reflection.Emit.OpCodes.Newarr, finish.Context.Types.Int32); @@ -3439,24 +3439,25 @@ internal override void EmitCall(CodeEmitter ilgen) internal static void EmitLinkToCall(RuntimeContext context, CodeEmitter ilgen, RuntimeJavaType[] args, RuntimeJavaType retType) { #if !FIRST_PASS && !IMPORTER - CodeEmitterLocal[] temps = new CodeEmitterLocal[args.Length]; + var temps = new CodeEmitterLocal[args.Length]; for (int i = args.Length - 1; i > 0; i--) { temps[i] = ilgen.DeclareLocal(context.MethodHandleUtil.AsBasicType(args[i])); ToBasic(args[i], ilgen); ilgen.Emit(System.Reflection.Emit.OpCodes.Stloc, temps[i]); } + temps[0] = ilgen.DeclareLocal(args[0].TypeAsSignatureType); ilgen.Emit(System.Reflection.Emit.OpCodes.Stloc, temps[0]); Array.Resize(ref args, args.Length - 1); - Type delegateType = context.MethodHandleUtil.CreateMemberWrapperDelegateType(args, retType); + + var delegateType = context.MethodHandleUtil.CreateMemberWrapperDelegateType(args, retType); ilgen.Emit(System.Reflection.Emit.OpCodes.Ldloc, temps[args.Length]); - ilgen.Emit(System.Reflection.Emit.OpCodes.Ldfld, typeof(java.lang.invoke.MemberName).GetField("vmtarget", BindingFlags.Instance | BindingFlags.NonPublic)); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldfld, context.Resolver.ResolveBaseType(typeof(java.lang.invoke.MemberName).FullName).GetField("vmtarget", BindingFlags.Instance | BindingFlags.NonPublic)); ilgen.Emit(System.Reflection.Emit.OpCodes.Castclass, delegateType); for (int i = 0; i < args.Length; i++) - { ilgen.Emit(System.Reflection.Emit.OpCodes.Ldloc, temps[i]); - } + context.MethodHandleUtil.EmitCallDelegateInvokeMethod(ilgen, delegateType); FromBasic(retType, ilgen); #else @@ -3464,7 +3465,7 @@ internal static void EmitLinkToCall(RuntimeContext context, CodeEmitter ilgen, R #endif } - private void EmitInvokeExact(CodeEmitter ilgen) + void EmitInvokeExact(CodeEmitter ilgen) { var args = cpi.GetArgTypes(); var temps = new CodeEmitterLocal[args.Length]; @@ -3494,7 +3495,7 @@ private void EmitInvokeExact(CodeEmitter ilgen) ilgen.Context.MethodHandleUtil.EmitCallDelegateInvokeMethod(ilgen, delegateType); } - private void EmitInvokeMaxArity(CodeEmitter ilgen) + void EmitInvokeMaxArity(CodeEmitter ilgen) { RuntimeJavaType[] args = cpi.GetArgTypes(); CodeEmitterLocal[] temps = new CodeEmitterLocal[args.Length]; @@ -3510,9 +3511,8 @@ private void EmitInvokeMaxArity(CodeEmitter ilgen) var mi = compiler.finish.Context.ByteCodeHelperMethods.GetDelegateForInvokeExact.MakeGenericMethod(delegateType); ilgen.Emit(System.Reflection.Emit.OpCodes.Call, mi); for (int i = 0; i < args.Length; i++) - { ilgen.Emit(System.Reflection.Emit.OpCodes.Ldloc, temps[i]); - } + compiler.finish.Context.MethodHandleUtil.EmitCallDelegateInvokeMethod(ilgen, delegateType); } @@ -3553,15 +3553,14 @@ void EmitInvoke(CodeEmitter ilgen) ilgen.Emit(System.Reflection.Emit.OpCodes.Ldsflda, fb); ilgen.Emit(System.Reflection.Emit.OpCodes.Call, mi); for (int i = 0; i < args.Length; i++) - { ilgen.Emit(System.Reflection.Emit.OpCodes.Ldloc, temps[i]); - } + compiler.finish.Context.MethodHandleUtil.EmitCallDelegateInvokeMethod(ilgen, delegateType); } - private void EmitInvokeBasic(CodeEmitter ilgen) + void EmitInvokeBasic(CodeEmitter ilgen) { - RuntimeJavaType retType = cpi.GetRetType(); + var retType = cpi.GetRetType(); EmitInvokeBasic(wrapper.Context, ilgen, cpi.GetArgTypes(), retType, true); FromBasic(retType, ilgen); } @@ -3574,21 +3573,20 @@ internal static void EmitInvokeBasic(RuntimeContext context, CodeEmitter ilgen, { temps[i] = ilgen.DeclareLocal(context.MethodHandleUtil.AsBasicType(args[i])); if (toBasic) - { ToBasic(args[i], ilgen); - } + ilgen.Emit(System.Reflection.Emit.OpCodes.Stloc, temps[i]); } temps[0] = ilgen.DeclareLocal(args[0].TypeAsSignatureType); ilgen.Emit(System.Reflection.Emit.OpCodes.Stloc, temps[0]); + var delegateType = context.MethodHandleUtil.CreateMemberWrapperDelegateType(args, retType); var mi = context.ByteCodeHelperMethods.GetDelegateForInvokeBasic.MakeGenericMethod(delegateType); ilgen.Emit(System.Reflection.Emit.OpCodes.Ldloc, temps[0]); ilgen.Emit(System.Reflection.Emit.OpCodes.Call, mi); for (int i = 0; i < args.Length; i++) - { ilgen.Emit(System.Reflection.Emit.OpCodes.Ldloc, temps[i]); - } + context.MethodHandleUtil.EmitCallDelegateInvokeMethod(ilgen, delegateType); } @@ -3614,12 +3612,13 @@ internal override void EmitNewobj(CodeEmitter ilgen) { throw new InvalidOperationException(); } + } - private sealed class DynamicFieldBinder + sealed class DynamicFieldBinder { - private IMethodSymbol method; + IMethodSymbol method; internal void Emit(Compiler compiler, ClassFile.ConstantPoolItemFieldref cpi, MethodHandleKind kind) { @@ -3659,7 +3658,7 @@ private static IMethodSymbol CreateMethod(Compiler compiler, ClassFile.ConstantP } } - private sealed class DynamicBinder + sealed class DynamicBinder { RuntimeJavaMethod mw; diff --git a/src/IKVM.Runtime/intrinsics.cs b/src/IKVM.Runtime/intrinsics.cs index 14f5c24ff..ef29d314f 100644 --- a/src/IKVM.Runtime/intrinsics.cs +++ b/src/IKVM.Runtime/intrinsics.cs @@ -370,7 +370,7 @@ private static bool CallerID_getCallerID(EmitIntrinsicContext eic) } else { - throw new FatalCompilerErrorException(DiagnosticEvent.CallerIDRequiresHasCallerIDAnnotation()); + throw new DiagnosticEventException(DiagnosticEvent.CallerIDRequiresHasCallerIDAnnotation()); } } diff --git a/src/IKVM.Tools.Core/Diagnostics/ConsoleDiagnosticFormatter.cs b/src/IKVM.Tools.Core/Diagnostics/ConsoleDiagnosticFormatter.cs index e92a76624..abd2d80b6 100644 --- a/src/IKVM.Tools.Core/Diagnostics/ConsoleDiagnosticFormatter.cs +++ b/src/IKVM.Tools.Core/Diagnostics/ConsoleDiagnosticFormatter.cs @@ -31,9 +31,19 @@ public ConsoleDiagnosticFormatter(ConsoleDiagnosticFormatterOptions options) _options = options ?? throw new ArgumentNullException(nameof(options)); } + /// + public bool CanWrite(in DiagnosticEvent @event) + { + return true; + } + /// public void Write(in DiagnosticEvent @event) { + // skip events we cannot write + if (CanWrite(@event) == false) + return; + try { WriteDiagnosticEvent(@event); @@ -50,7 +60,7 @@ public void Write(in DiagnosticEvent @event) /// /// /// - protected virtual Markup WriteDiagnosticLevel(DiagnosticLevel level) + protected virtual Markup GetDiagnosticLevelMarkup(DiagnosticLevel level) { return level switch { @@ -63,12 +73,23 @@ protected virtual Markup WriteDiagnosticLevel(DiagnosticLevel level) }; } + /// + /// Returns the output text for the given . + /// + /// + /// + /// + protected virtual void WriteDiagnosticLevel(DiagnosticLevel level) + { + AnsiConsole.Write(GetDiagnosticLevelMarkup(level)); + } + /// /// Formats the output text for the given diagnostic code. /// /// /// - protected virtual void WriteDiagnosticCode(int code) + protected virtual void WriteDiagnosticCode(DiagnosticLevel level, int code) { AnsiConsole.Write("IKVM"); AnsiConsole.Write($"{code:D4}"); @@ -79,7 +100,7 @@ protected virtual void WriteDiagnosticCode(int code) /// /// /// - protected virtual void WriteDiagnosticMessage(string message, ReadOnlySpan args) + protected virtual void WriteDiagnosticMessage(DiagnosticLevel level, string message, ReadOnlySpan args) { AnsiConsole.MarkupInterpolated(FormattableStringFactory.Create(message, args.ToArray())); } @@ -92,9 +113,9 @@ protected virtual void WriteDiagnosticEvent(in DiagnosticEvent @event) { WriteDiagnosticLevel(@event.Diagnostic.Level); AnsiConsole.Write(" "); - WriteDiagnosticCode(@event.Diagnostic.Id); + WriteDiagnosticCode(@event.Diagnostic.Level, @event.Diagnostic.Id); AnsiConsole.Write(": "); - WriteDiagnosticMessage(@event.Diagnostic.Message, @event.Args); + WriteDiagnosticMessage(@event.Diagnostic.Level, @event.Diagnostic.Message, @event.Args); AnsiConsole.WriteLine(); if (@event.Exception != null) diff --git a/src/IKVM.Tools.Core/Diagnostics/DiagnosticChannelFormatter.cs b/src/IKVM.Tools.Core/Diagnostics/DiagnosticChannelFormatter.cs index f407ef8c0..ceeb1488a 100644 --- a/src/IKVM.Tools.Core/Diagnostics/DiagnosticChannelFormatter.cs +++ b/src/IKVM.Tools.Core/Diagnostics/DiagnosticChannelFormatter.cs @@ -26,14 +26,36 @@ public DiagnosticChannelFormatter(TOptions options) /// public TOptions Options => _options; + /// + public bool CanWrite(in DiagnosticEvent @event) + { + // filter out nowarn + if (@event.Diagnostic.Level is DiagnosticLevel.Warning) + { + if (Options.NoWarn) + return false; + else if (Options.NoWarnDiagnostics.Contains(@event.Diagnostic)) + return false; + } + + // any unknown diagnostic can be written + return @event.Diagnostic.Level is not DiagnosticLevel.Unknown; + } + /// public void Write(in DiagnosticEvent @event) { var level = @event.Diagnostic.Level; - if (level is DiagnosticLevel.Warning && Options.WarnAsError) - level = DiagnosticLevel.Error; - if (level is DiagnosticLevel.Warning && Options.WarnAsErrorDiagnostics.Contains(@event.Diagnostic)) - level = DiagnosticLevel.Error; + if (CanWrite(@event) == false) + return; + + if (level is DiagnosticLevel.Warning) + { + if (Options.WarnAsError) + level = DiagnosticLevel.Error; + else if (Options.WarnAsErrorDiagnostics.Contains(@event.Diagnostic)) + level = DiagnosticLevel.Error; + } // find the writer for the event's level var channel = level switch diff --git a/src/IKVM.Tools.Core/Diagnostics/DiagnosticServiceCollectionExtensions.cs b/src/IKVM.Tools.Core/Diagnostics/DiagnosticServiceCollectionExtensions.cs index fef86d45b..4d2fd5930 100644 --- a/src/IKVM.Tools.Core/Diagnostics/DiagnosticServiceCollectionExtensions.cs +++ b/src/IKVM.Tools.Core/Diagnostics/DiagnosticServiceCollectionExtensions.cs @@ -19,6 +19,7 @@ public static IServiceCollection AddToolsDiagnostics(this IServiceCollection ser services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); return services; } diff --git a/src/IKVM.Tools.Core/Diagnostics/IDiagnosticFormatter.cs b/src/IKVM.Tools.Core/Diagnostics/IDiagnosticFormatter.cs index 02dfebe0a..007eadce4 100644 --- a/src/IKVM.Tools.Core/Diagnostics/IDiagnosticFormatter.cs +++ b/src/IKVM.Tools.Core/Diagnostics/IDiagnosticFormatter.cs @@ -6,6 +6,13 @@ namespace IKVM.Tools.Core.Diagnostics interface IDiagnosticFormatter { + /// + /// Returns true if the given event should be written. + /// + /// + /// + bool CanWrite(in DiagnosticEvent @event); + /// /// Writes the event. /// diff --git a/src/IKVM.Tools.Core/IKVM.Tools.Core.csproj b/src/IKVM.Tools.Core/IKVM.Tools.Core.csproj index e08766661..5205a8c68 100644 --- a/src/IKVM.Tools.Core/IKVM.Tools.Core.csproj +++ b/src/IKVM.Tools.Core/IKVM.Tools.Core.csproj @@ -11,7 +11,7 @@ - + @@ -23,5 +23,9 @@ + + + + diff --git a/src/IKVM.Tools.Exporter/ExportImpl.cs b/src/IKVM.Tools.Exporter/ExportImpl.cs index b7e4b327b..09494ee74 100644 --- a/src/IKVM.Tools.Exporter/ExportImpl.cs +++ b/src/IKVM.Tools.Exporter/ExportImpl.cs @@ -146,12 +146,11 @@ public int Execute() } compiler = new StaticCompiler(universe, assemblyResolver, runtimeAssembly); - context = new RuntimeContext(new RuntimeContextOptions(true), diagnostics, new ManagedTypeResolver(symbols, universe, runtimeAssembly, null), compiler); + context = new RuntimeContext(new RuntimeContextOptions(true), diagnostics, new ExportRuntimeSymbolResolver(diagnostics, universe, symbols), compiler); context.ClassLoaderFactory.SetBootstrapClassLoader(new RuntimeBootstrapClassLoader(context)); } else { - var runtimeAssemblyPath = references.FirstOrDefault(i => Path.GetFileNameWithoutExtension(i) == "IKVM.Runtime"); if (runtimeAssemblyPath != null) runtimeAssembly = assemblyResolver.LoadFile(runtimeAssemblyPath); @@ -173,10 +172,10 @@ public int Execute() } compiler = new StaticCompiler(universe, assemblyResolver, runtimeAssembly); - context = new RuntimeContext(new RuntimeContextOptions(), diagnostics, new ManagedTypeResolver(symbols, universe, runtimeAssembly, baseAssembly), compiler); + context = new RuntimeContext(new RuntimeContextOptions(), diagnostics, new ExportRuntimeSymbolResolver(diagnostics, universe, symbols), compiler); } - if (context.AttributeHelper.IsJavaModule(context.Resolver.ImportModule(assembly.ManifestModule))) + if (context.AttributeHelper.IsJavaModule(context.Resolver.GetSymbol(assembly.ManifestModule))) { diagnostics.ExportingImportsNotSupported(); return 1; @@ -368,7 +367,7 @@ bool ExportNamespace(IList namespaces, ITypeSymbol type) int ProcessTypes(RuntimeContext context, Type[] types) { int rc = 0; - foreach (var t in types.Select(context.Resolver.ImportType)) + foreach (var t in types.Select(context.Resolver.GetSymbol)) { if ((t.IsPublic || options.IncludeNonPublicTypes) && ExportNamespace(options.Namespaces, t) && !t.IsGenericTypeDefinition && !context.AttributeHelper.IsHideFromJava(t) && (!t.IsGenericType || !context.AttributeHelper.IsJavaModule(t.Module))) { diff --git a/src/IKVM.Tools.Exporter/ExportRuntimeSymbolResolver.cs b/src/IKVM.Tools.Exporter/ExportRuntimeSymbolResolver.cs new file mode 100644 index 000000000..cb41963e3 --- /dev/null +++ b/src/IKVM.Tools.Exporter/ExportRuntimeSymbolResolver.cs @@ -0,0 +1,287 @@ +/* + Copyright (C) 2002-2014 Jeroen Frijters + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jeroen Frijters + jeroen@frijters.net + +*/ +#nullable enable + +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; + +using IKVM.CoreLib.Diagnostics; +using IKVM.CoreLib.Symbols; +using IKVM.CoreLib.Symbols.Emit; +using IKVM.CoreLib.Symbols.IkvmReflection; +using IKVM.Reflection; +using IKVM.Reflection.Emit; +using IKVM.Runtime; + +using Type = IKVM.Reflection.Type; + +namespace IKVM.Tools.Exporter +{ + + class ExportRuntimeSymbolResolver : IRuntimeSymbolResolver + { + + /// + /// Gets the set of types from which to discover system assemblies. + /// + /// + static IEnumerable GetSystemTypeNames() + { + yield return "System.Object"; + yield return "System.Runtime.CompilerServices.RuntimeCompatibilityAttribute"; + yield return "System.Console"; + yield return "System.Threading.Interlocked"; + yield return "System.ComponentModel.EditorBrowsableAttribute"; + yield return "System.Collections.IEnumerable"; + yield return "System.Collections.Generic.IEnumerable`1"; + yield return "System.Environment"; + } + + readonly IDiagnosticHandler _diagnostics; + readonly Universe _universe; + readonly IkvmReflectionSymbolContext _symbols; + + IAssemblySymbol? _coreAssembly; + readonly ConcurrentDictionary _coreTypeCache = new(); + + IAssemblySymbol[]? _systemAssemblies; + readonly ConcurrentDictionary _systemTypeCache = new(); + + IAssemblySymbol? _runtimeAssembly; + readonly ConcurrentDictionary _runtimeTypeCache = new(); + + IAssemblySymbol? _baseAssembly; + readonly ConcurrentDictionary _baseTypeCache = new(); + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + public ExportRuntimeSymbolResolver(IDiagnosticHandler diagnostics, Universe universe, IkvmReflectionSymbolContext symbols) + { + _diagnostics = diagnostics ?? throw new ArgumentNullException(nameof(diagnostics)); + _universe = universe ?? throw new ArgumentNullException(nameof(universe)); + _symbols = symbols ?? throw new ArgumentNullException(nameof(symbols)); + } + + /// + public ISymbolContext Symbols => _symbols; + + /// + public IAssemblySymbol GetCoreAssembly() + { + return (_coreAssembly ??= GetSymbol(_universe.CoreLib)) ?? throw new DiagnosticEventException(DiagnosticEvent.CoreClassesMissing()); + } + + /// + public IAssemblySymbol GetRuntimeAssembly() + { + return (_runtimeAssembly ??= FindRuntimeAssembly()) ?? throw new DiagnosticEventException(DiagnosticEvent.RuntimeNotFound()); + } + + /// + /// Attempts to load the runtime assembly. + /// + IAssemblySymbol? FindRuntimeAssembly() + { + foreach (var assembly in _universe.GetAssemblies()) + if (assembly.GetType("IKVM.Runtime.JVM") is Type) + return GetSymbol(assembly); + + return null; + } + + /// + public IAssemblySymbol GetBaseAssembly() + { + return (_baseAssembly ??= FindBaseAssembly()) ?? throw new DiagnosticEventException(DiagnosticEvent.BootstrapClassesMissing()); + } + + /// + /// Attempts to load the base assembly. + /// + IAssemblySymbol? FindBaseAssembly() + { + foreach (var assembly in _universe.GetAssemblies()) + if (assembly.GetType("java.lang.Object") is Type) + return GetSymbol(assembly); + + return null; + } + + /// + public ITypeSymbol ResolveCoreType(string typeName) + { + return _coreTypeCache.GetOrAdd(typeName, _ => GetCoreAssembly().GetType(_)) ?? throw new DiagnosticEventException(DiagnosticEvent.CoreClassesMissing()); + } + + /// + /// Resolves the set of system assemblies. + /// + /// + IAssemblySymbol[] ResolveSystemAssemblies() + { + return _systemAssemblies ??= ResolveSystemAssembliesIter().Distinct().ToArray(); + } + + /// + /// Resolves the set of system assemblies that contain the system types. + /// + /// + IEnumerable ResolveSystemAssembliesIter() + { + foreach (var assembly in _universe.GetAssemblies()) + foreach (var typeName in GetSystemTypeNames()) + if (assembly.GetType(typeName) is Type t) + yield return GetSymbol(assembly); + } + + /// + public ITypeSymbol ResolveSystemType(string typeName) + { + return _systemTypeCache.GetOrAdd(typeName, FindSystemType) ?? throw new DiagnosticEventException(DiagnosticEvent.ClassNotFound(typeName)); + } + + /// + /// Attempts to load the specified system type. + /// + /// + /// + ITypeSymbol? FindSystemType(string typeName) + { + foreach (var assembly in ResolveSystemAssemblies()) + if (assembly.GetType(typeName) is { } t) + return t; + + return null; + } + + /// + public ITypeSymbol? ResolveRuntimeType(string typeName) + { + return GetRuntimeAssembly().GetType(typeName); + } + + /// + public ITypeSymbol? ResolveBaseType(string typeName) + { + return GetBaseAssembly().GetType(typeName); + } + + /// + public IAssemblySymbol? ResolveAssembly(string assemblyName) + { + return _universe.Load(assemblyName) is { } a ? GetSymbol(a) : null; + } + + /// + public ITypeSymbol? ResolveType(string typeName) + { + foreach (var assembly in _universe.GetAssemblies()) + if (assembly.GetType(typeName) is Type t) + return GetSymbol(t); + + return null; + } + + /// + public IAssemblySymbol GetSymbol(Assembly assembly) + { + return _symbols.GetOrCreateAssemblySymbol(assembly); + } + + /// + public IAssemblySymbolBuilder GetSymbol(AssemblyBuilder assembly) + { + return _symbols.GetOrCreateAssemblySymbol(assembly); + } + + /// + public IModuleSymbol GetSymbol(Module module) + { + return _symbols.GetOrCreateModuleSymbol(module); + } + + /// + public IModuleSymbolBuilder GetSymbol(ModuleBuilder module) + { + return _symbols.GetOrCreateModuleSymbol(module); + } + + /// + public ITypeSymbol GetSymbol(Type type) + { + return _symbols.GetOrCreateTypeSymbol(type); + } + + /// + public IMemberSymbol GetSymbol(MemberInfo memberInfo) + { + return _symbols.GetOrCreateMemberSymbol(memberInfo); + } + + /// + public IMethodBaseSymbol GetSymbol(MethodBase type) + { + return _symbols.GetOrCreateMethodBaseSymbol(type); + } + + /// + public IConstructorSymbol GetSymbol(ConstructorInfo ctor) + { + return _symbols.GetOrCreateConstructorSymbol(ctor); + } + + /// + public IMethodSymbol GetSymbol(MethodInfo method) + { + return _symbols.GetOrCreateMethodSymbol(method); + } + + /// + public IFieldSymbol GetSymbol(FieldInfo field) + { + return _symbols.GetOrCreateFieldSymbol(field); + } + + /// + public IPropertySymbol GetSymbol(PropertyInfo property) + { + return _symbols.GetOrCreatePropertySymbol(property); + } + + /// + public IEventSymbol GetSymbol(EventInfo @event) + { + return _symbols.GetOrCreateEventSymbol(@event); + } + + } + +} \ No newline at end of file diff --git a/src/IKVM.Tools.Exporter/ExportTool.cs b/src/IKVM.Tools.Exporter/ExportTool.cs index 2a6eb04b6..b8e3ae086 100644 --- a/src/IKVM.Tools.Exporter/ExportTool.cs +++ b/src/IKVM.Tools.Exporter/ExportTool.cs @@ -60,7 +60,7 @@ static Task ExecuteImplAsync(ExportOptions options, Func(); - services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); using var provider = services.BuildServiceProvider(); var exporter = provider.GetRequiredService(); diff --git a/src/IKVM.Tools.Exporter/ManagedTypeResolver.cs b/src/IKVM.Tools.Exporter/ManagedTypeResolver.cs deleted file mode 100644 index 55d36ccea..000000000 --- a/src/IKVM.Tools.Exporter/ManagedTypeResolver.cs +++ /dev/null @@ -1,163 +0,0 @@ -#nullable enable - -using System; - -using IKVM.CoreLib.Symbols; -using IKVM.CoreLib.Symbols.Emit; -using IKVM.CoreLib.Symbols.IkvmReflection; -using IKVM.Reflection; -using IKVM.Reflection.Emit; -using IKVM.Runtime; - -using Type = IKVM.Reflection.Type; - -namespace IKVM.Tools.Exporter -{ - - class ManagedTypeResolver : IRuntimeSymbolResolver - { - - readonly Universe universe; - readonly Assembly runtimeAssembly; - readonly Assembly baseAssembly; - readonly IkvmReflectionSymbolContext symbols; - - /// - /// Initializes a new instance. - /// - /// - /// - public ManagedTypeResolver(IkvmReflectionSymbolContext symbols, Universe universe, Assembly runtimeAssembly, Assembly baseAssembly) - { - this.symbols = symbols ?? throw new ArgumentNullException(nameof(symbols)); - this.universe = universe ?? throw new ArgumentNullException(nameof(universe)); - this.runtimeAssembly = runtimeAssembly ?? throw new ArgumentNullException(nameof(runtimeAssembly)); - this.baseAssembly = baseAssembly; - } - - /// - public ISymbolContext Symbols => symbols; - - /// - public IAssemblySymbol ResolveCoreAssembly() - { - return ImportAssembly(universe.CoreLib); - } - - /// - public ITypeSymbol ResolveCoreType(string typeName) - { - return ResolveCoreAssembly().GetType(typeName) ?? throw new InvalidOperationException(); - } - - /// - public IAssemblySymbol ResolveRuntimeAssembly() - { - return ImportAssembly(runtimeAssembly); - } - - /// - public ITypeSymbol ResolveRuntimeType(string typeName) - { - return ResolveRuntimeAssembly().GetType(typeName) ?? throw new InvalidOperationException(); - } - - /// - public IAssemblySymbol ResolveBaseAssembly() - { - return ImportAssembly(baseAssembly); - } - - /// - public ITypeSymbol ResolveBaseType(string typeName) - { - throw new NotImplementedException(); - } - - /// - public ITypeSymbol? ResolveType(string typeName) - { - throw new NotImplementedException(); - } - - /// - public IAssemblySymbol ResolveAssembly(string assemblyName) - { - return ImportAssembly(universe.Load(assemblyName)); - } - - /// - public IAssemblySymbol ImportAssembly(Assembly assembly) - { - return symbols.GetOrCreateAssemblySymbol(assembly); - } - - /// - public IAssemblySymbolBuilder ImportAssembly(AssemblyBuilder assembly) - { - return symbols.GetOrCreateAssemblySymbol(assembly); - } - - /// - public IModuleSymbol ImportModule(Module module) - { - return symbols.GetOrCreateModuleSymbol(module); - } - - /// - public IModuleSymbolBuilder ImportModule(ModuleBuilder module) - { - return symbols.GetOrCreateModuleSymbol(module); - } - - /// - public ITypeSymbol ImportType(Type type) - { - return symbols.GetOrCreateTypeSymbol(type) ; - } - - /// - public ITypeSymbolBuilder ResolveType(TypeBuilder type) - { - return symbols.GetOrCreateTypeSymbol(type); - } - - /// - public IMemberSymbol ImportMember(MemberInfo module) - { - return symbols.GetOrCreateMemberSymbol(module); - } - - /// - public IMethodBaseSymbol ImportMethodBase(MethodBase method) - { - return symbols.GetOrCreateMethodBaseSymbol(method); - } - - /// - public IConstructorSymbol ImportConstructor(ConstructorInfo ctor) - { - return symbols.GetOrCreateConstructorSymbol(ctor); - } - - /// - public IConstructorSymbolBuilder ResolveConstructor(ConstructorBuilder ctor) - { - return symbols.GetOrCreateConstructorSymbol(ctor); - } - - /// - public IMethodSymbol ImportMethod(MethodInfo method) - { - return symbols.GetOrCreateMethodSymbol(method); - } - - /// - public IMethodSymbolBuilder ResolveMethod(MethodBuilder method) - { - return symbols.GetOrCreateMethodSymbol(method); - } - - } - -} diff --git a/src/IKVM.Tools.Importer/ImportAssemblyResolver.cs b/src/IKVM.Tools.Importer/ImportAssemblyResolver.cs index 4814a786d..b51a8be78 100644 --- a/src/IKVM.Tools.Importer/ImportAssemblyResolver.cs +++ b/src/IKVM.Tools.Importer/ImportAssemblyResolver.cs @@ -87,7 +87,7 @@ public ImportAssemblyResolver(Universe universe, ImportOptions options, IDiagnos /// /// /// - /// + /// internal Assembly LoadFile(string path) { string ex = null; @@ -101,7 +101,7 @@ internal Assembly LoadFile(string path) // to avoid problems (i.e. weird exceptions), we don't allow assemblies to load that reference a newer version of the corelib foreach (var asmref in module.GetReferencedAssemblies()) if (asmref.Name == universe.CoreLibName && asmref.Version > coreLibVersion) - throw new FatalCompilerErrorException(DiagnosticEvent.CoreAssemblyVersionMismatch(asmref.Name, universe.CoreLibName)); + throw new DiagnosticEventException(DiagnosticEvent.CoreAssemblyVersionMismatch(asmref.Name, universe.CoreLibName)); } var asm = universe.LoadAssembly(module); diff --git a/src/IKVM.Tools.Importer/ImportClassLoader.cs b/src/IKVM.Tools.Importer/ImportClassLoader.cs index b889c289c..908069f17 100644 --- a/src/IKVM.Tools.Importer/ImportClassLoader.cs +++ b/src/IKVM.Tools.Importer/ImportClassLoader.cs @@ -165,7 +165,7 @@ internal IModuleSymbolBuilder CreateModuleBuilder() name.Version = state.version; // define a dynamic assembly and module - assemblyBuilder = Context.Resolver.ImportAssembly(Context.StaticCompiler.Universe.DefineDynamicAssembly(name, AssemblyBuilderAccess.ReflectionOnly, assemblyDir)); + assemblyBuilder = Context.Resolver.GetSymbol(Context.StaticCompiler.Universe.DefineDynamicAssembly(name, AssemblyBuilderAccess.ReflectionOnly, assemblyDir)); var moduleBuilder = assemblyBuilder.DefineModule(assemblyName, assemblyFile, EmitSymbols); // if configured to emit stack trace info set source file @@ -631,11 +631,11 @@ void Save() } catch (IOException x) { - throw new FatalCompilerErrorException(DiagnosticEvent.ErrorWritingFile(GetTypeWrapperFactory().ModuleBuilder.FullyQualifiedName, x.Message)); + throw new DiagnosticEventException(DiagnosticEvent.ErrorWritingFile(GetTypeWrapperFactory().ModuleBuilder.FullyQualifiedName, x.Message)); } catch (UnauthorizedAccessException x) { - throw new FatalCompilerErrorException(DiagnosticEvent.ErrorWritingFile(GetTypeWrapperFactory().ModuleBuilder.FullyQualifiedName, x.Message)); + throw new DiagnosticEventException(DiagnosticEvent.ErrorWritingFile(GetTypeWrapperFactory().ModuleBuilder.FullyQualifiedName, x.Message)); } } else @@ -648,11 +648,11 @@ void Save() } catch (IOException x) { - throw new FatalCompilerErrorException(DiagnosticEvent.ErrorWritingFile(Path.Combine(assemblyDir, assemblyFile), x.Message)); + throw new DiagnosticEventException(DiagnosticEvent.ErrorWritingFile(Path.Combine(assemblyDir, assemblyFile), x.Message)); } catch (UnauthorizedAccessException x) { - throw new FatalCompilerErrorException(DiagnosticEvent.ErrorWritingFile(Path.Combine(assemblyDir, assemblyFile), x.Message)); + throw new DiagnosticEventException(DiagnosticEvent.ErrorWritingFile(Path.Combine(assemblyDir, assemblyFile), x.Message)); } } } @@ -674,7 +674,7 @@ void AddJavaModuleAttribute(IModuleSymbolBuilder mb) } list = UnicodeUtil.EscapeInvalidSurrogates(list); - var cab = Context.Resolver.Symbols.CreateCustomAttribute(typeofJavaModuleAttribute.GetConstructor([Context.Resolver.ResolveCoreType(typeof(string).FullName).MakeArrayType()]), [list], propInfos, propValues); + var cab = Context.Resolver.Symbols.CreateCustomAttribute(typeofJavaModuleAttribute.GetConstructor([Context.Types.String.MakeArrayType()]), [list], propInfos, propValues); mb.SetCustomAttribute(cab); } else @@ -897,7 +897,7 @@ internal RemapperTypeWrapper(RuntimeContext context, ImportClassLoader classLoad this.baseTypeWrapper = GetBaseWrapper(context, c); classDef = c; bool baseIsSealed = false; - shadowType = context.Resolver.ImportType(context.StaticCompiler.Universe.GetType(c.Shadows, true)); + shadowType = context.Resolver.GetSymbol(context.StaticCompiler.Universe.GetType(c.Shadows, true)); classLoader.SetRemappedType(shadowType, this); var baseType = shadowType; ITypeSymbol baseInterface = null; @@ -1757,7 +1757,7 @@ private void EmitRedirect(ITypeSymbol baseType, CodeEmitter ilgen) // type specified, or class missing, assume loading .NET type if (m.Redirect.Type != null || m.Redirect.Class == null) { - var type = m.Redirect.Type != null ? DeclaringType.Context.Resolver.ImportType(DeclaringType.Context.StaticCompiler.Universe.GetType(m.Redirect.Type, true)) : baseType; + var type = m.Redirect.Type != null ? DeclaringType.Context.Resolver.GetSymbol(DeclaringType.Context.StaticCompiler.Universe.GetType(m.Redirect.Type, true)) : baseType; var redirParamTypes = classLoader.ArgTypeListFromSig(redirSig); var mi = type.GetMethod(m.Redirect.Name, redirParamTypes) ?? throw new InvalidOperationException(); ilgen.Emit(System.Reflection.Emit.OpCodes.Call, mi); @@ -2301,7 +2301,7 @@ internal void Emit(MapXml.CodeGenContext context, CodeEmitter ilgen) for (int i = 0; i < map.Length; i++) { ilgen.Emit(System.Reflection.Emit.OpCodes.Dup); - ilgen.Emit(System.Reflection.Emit.OpCodes.Ldtoken, rcontext.Resolver.ResolveCoreType(map[i].Source)); + ilgen.Emit(System.Reflection.Emit.OpCodes.Ldtoken, rcontext.Resolver.ResolveType(map[i].Source)); ilgen.Emit(System.Reflection.Emit.OpCodes.Call, rcontext.CompilerFactory.GetTypeFromHandleMethod); ilgen.Emit(System.Reflection.Emit.OpCodes.Ceq); var label = ilgen.DefineLabel(); @@ -2593,7 +2593,7 @@ internal static int Compile(RuntimeContext context, StaticCompiler compiler, IDi } catch (FileFormatLimitationExceededException e) { - throw new FatalCompilerErrorException(DiagnosticEvent.FileFormatLimitationExceeded(e.Message)); + throw new DiagnosticEventException(DiagnosticEvent.FileFormatLimitationExceeded(e.Message)); } return 0; @@ -2604,7 +2604,7 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, IDiag diagnostics.GenericCompilerInfo($"JVM.Compile path: {import.path}, assembly: {import.assembly}"); // locate specified runtime assembly - var runtimeAssembly = context.Resolver.ResolveRuntimeAssembly(); + var runtimeAssembly = context.Resolver.GetRuntimeAssembly(); var allReferencesAreStrongNamed = IsSigned(runtimeAssembly); var references = new List(); @@ -2625,12 +2625,12 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, IDiag { // TODO we really should support binding redirects here to allow different revisions to be mixed if (asmref.FullName != runtimeAssembly.FullName) - throw new FatalCompilerErrorException(DiagnosticEvent.RuntimeMismatch(reference.Location, runtimeAssembly.FullName, asmref.FullName)); + throw new DiagnosticEventException(DiagnosticEvent.RuntimeMismatch(reference.Location, runtimeAssembly.FullName, asmref.FullName)); } else { if (asmref.PublicKeyOrToken.IsEmpty == false) - throw new FatalCompilerErrorException(DiagnosticEvent.RuntimeMismatch(reference.Location, runtimeAssembly.FullName, asmref.FullName)); + throw new DiagnosticEventException(DiagnosticEvent.RuntimeMismatch(reference.Location, runtimeAssembly.FullName, asmref.FullName)); } } } @@ -2744,10 +2744,10 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, IDiag import.target = IKVM.CoreLib.Symbols.Emit.PEFileKinds.Dll; if (import.target != IKVM.CoreLib.Symbols.Emit.PEFileKinds.Dll && import.mainClass == null) - throw new FatalCompilerErrorException(DiagnosticEvent.ExeRequiresMainClass()); + throw new DiagnosticEventException(DiagnosticEvent.ExeRequiresMainClass()); if (import.target == IKVM.CoreLib.Symbols.Emit.PEFileKinds.Dll && import.props.Count != 0) - throw new FatalCompilerErrorException(DiagnosticEvent.PropertiesRequireExe()); + throw new DiagnosticEventException(DiagnosticEvent.PropertiesRequireExe()); if (import.path == null) { @@ -2767,7 +2767,7 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, IDiag if (import.targetIsModule) { if (import.classLoader != null) - throw new FatalCompilerErrorException(DiagnosticEvent.ModuleCannotHaveClassLoader()); + throw new DiagnosticEventException(DiagnosticEvent.ModuleCannotHaveClassLoader()); // TODO if we're overwriting a user specified assembly name, we need to emit a warning import.assembly = import.path.Name; @@ -2801,7 +2801,7 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, IDiag } catch (Exception e) { - throw new FatalCompilerErrorException(DiagnosticEvent.ErrorReadingFile(import.remapfile.FullName, e.Message)); + throw new DiagnosticEventException(DiagnosticEvent.ErrorReadingFile(import.remapfile.FullName, e.Message)); } try @@ -2814,7 +2814,7 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, IDiag } catch (MapXml.MapXmlException x) { - throw new FatalCompilerErrorException(DiagnosticEvent.ErrorParsingMapFile(import.remapfile.FullName, x.Message)); + throw new DiagnosticEventException(DiagnosticEvent.ErrorParsingMapFile(import.remapfile.FullName, x.Message)); } if (loader.ValidateAndSetMap(map) == false) @@ -2831,13 +2831,13 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, IDiag if (import.bootstrap == false) { - allReferencesAreStrongNamed &= IsSigned(context.Resolver.ResolveBaseAssembly()); - loader.AddReference(context.AssemblyClassLoaderFactory.FromAssembly(context.Resolver.ResolveBaseAssembly())); + allReferencesAreStrongNamed &= IsSigned(context.Resolver.GetBaseAssembly()); + loader.AddReference(context.AssemblyClassLoaderFactory.FromAssembly(context.Resolver.GetBaseAssembly())); } if ((import.keyPair != null || import.publicKey != null) && !allReferencesAreStrongNamed) { - throw new FatalCompilerErrorException(DiagnosticEvent.StrongNameRequiresStrongNamedRefs()); + throw new DiagnosticEventException(DiagnosticEvent.StrongNameRequiresStrongNamedRefs()); } if (loader.map != null) @@ -2848,7 +2848,7 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, IDiag if (import.bootstrap == false) { loader.fakeTypes = context.FakeTypes; - loader.fakeTypes.Load(context.Resolver.ResolveBaseAssembly()); + loader.fakeTypes.Load(context.Resolver.GetBaseAssembly()); } return 0; @@ -2960,22 +2960,22 @@ int CompilePass3() } if (wrapper == null) { - throw new FatalCompilerErrorException(DiagnosticEvent.MainClassNotFound()); + throw new DiagnosticEventException(DiagnosticEvent.MainClassNotFound()); } var mw = wrapper.GetMethodWrapper("main", "([Ljava.lang.String;)V", false); if (mw == null || !mw.IsStatic) - throw new FatalCompilerErrorException(DiagnosticEvent.MainMethodNotFound()); + throw new DiagnosticEventException(DiagnosticEvent.MainMethodNotFound()); mw.Link(); var method = mw.GetMethod() as IMethodSymbol; if (method == null) - throw new FatalCompilerErrorException(DiagnosticEvent.UnsupportedMainMethod()); + throw new DiagnosticEventException(DiagnosticEvent.UnsupportedMainMethod()); if (!ReflectUtil.IsFromAssembly(method.DeclaringType, assemblyBuilder) && (!method.IsPublic || !method.DeclaringType.IsPublic)) { - throw new FatalCompilerErrorException(DiagnosticEvent.ExternalMainNotAccessible()); + throw new DiagnosticEventException(DiagnosticEvent.ExternalMainNotAccessible()); } var apartmentAttributeType = state.apartment switch @@ -3001,7 +3001,7 @@ int CompilePass3() } catch (IKVM.Reflection.MissingMemberException x) { - Context.StaticCompiler.IssueMissingTypeMessage((ITypeSymbol)Context.Resolver.ImportMember(x.MemberInfo)); + Context.StaticCompiler.IssueMissingTypeMessage((ITypeSymbol)Context.Resolver.GetSymbol(x.MemberInfo)); return 1; } } @@ -3046,20 +3046,20 @@ int CompilePass3() } if (classLoaderType == null) - throw new FatalCompilerErrorException(DiagnosticEvent.ClassLoaderNotFound()); + throw new DiagnosticEventException(DiagnosticEvent.ClassLoaderNotFound()); if (classLoaderType.IsPublic == false && ReflectUtil.IsFromAssembly(classLoaderType.TypeAsBaseType, assemblyBuilder) == false) - throw new FatalCompilerErrorException(DiagnosticEvent.ClassLoaderNotAccessible()); + throw new DiagnosticEventException(DiagnosticEvent.ClassLoaderNotAccessible()); if (classLoaderType.IsAbstract) - throw new FatalCompilerErrorException(DiagnosticEvent.ClassLoaderIsAbstract()); + throw new DiagnosticEventException(DiagnosticEvent.ClassLoaderIsAbstract()); if (classLoaderType.IsAssignableTo(Context.ClassLoaderFactory.LoadClassCritical("java.lang.ClassLoader")) == false) - throw new FatalCompilerErrorException(DiagnosticEvent.ClassLoaderNotClassLoader()); + throw new DiagnosticEventException(DiagnosticEvent.ClassLoaderNotClassLoader()); var classLoaderInitMethod = classLoaderType.GetMethodWrapper("", "(Lcli.System.Reflection.Assembly;)V", false); if (classLoaderInitMethod == null) - throw new FatalCompilerErrorException(DiagnosticEvent.ClassLoaderConstructorMissing()); + throw new DiagnosticEventException(DiagnosticEvent.ClassLoaderConstructorMissing()); // apply custom attribute specifying custom class loader Context.AttributeHelper.SetCustomAssemblyClassLoaderAttribute(assemblyBuilder, classLoaderType.TypeAsTBD); diff --git a/src/IKVM.Tools.Importer/ImportCommand.cs b/src/IKVM.Tools.Importer/ImportCommand.cs index b2e088a8d..dd5706f71 100644 --- a/src/IKVM.Tools.Importer/ImportCommand.cs +++ b/src/IKVM.Tools.Importer/ImportCommand.cs @@ -294,36 +294,6 @@ public ImportCommand(bool root = true) ResourceOption.AddValidator(ValidateResource); } - /// - /// Parse an option set of Diagnostic ID values. - /// - /// - /// - Diagnostic[]? ParseDiagnosticArray(ArgumentResult result) - { - List? l = null; - - foreach (var i in result.Tokens) - { - foreach (var j in i.Value.Split(LIST_SEPARATOR, StringSplitOptions.RemoveEmptyEntries)) - { - if (int.TryParse(j, out var id) && Diagnostic.GetById(id) is { } diagnostic) - { - l ??= new(); - l.Add(diagnostic); - } - - if (j.StartsWith("IKVM", StringComparison.OrdinalIgnoreCase) && int.TryParse(j["IKVM".Length..], out var id2) && Diagnostic.GetById(id2) is { } diagnostic2) - { - l ??= new(); - l.Add(diagnostic2); - } - } - } - - return l?.ToArray(); - } - /// /// Parses an optional string option. An optional string argument represents three states: not present (null), /// empty (present with no values) or specified (present with values). diff --git a/src/IKVM.Tools.Importer/ImportContextFactory.cs b/src/IKVM.Tools.Importer/ImportContextFactory.cs index b151d670a..40c8f58d9 100644 --- a/src/IKVM.Tools.Importer/ImportContextFactory.cs +++ b/src/IKVM.Tools.Importer/ImportContextFactory.cs @@ -73,7 +73,7 @@ public List Create(ImportOptions options) /// /// /// - /// + /// void Create(ImportOptions options, ImportContext import, List targets) { if (options.Output != null) @@ -102,7 +102,7 @@ void Create(ImportOptions options, ImportContext import, List tar import.guessFileKind = false; break; default: - throw new FatalCompilerErrorException(DiagnosticEvent.UnrecognizedTargetType(options.Target.ToString())); + throw new DiagnosticEventException(DiagnosticEvent.UnrecognizedTargetType(options.Target.ToString())); } switch (options.Platform) @@ -132,7 +132,7 @@ void Create(ImportOptions options, ImportContext import, List tar import.imageFileMachine = IKVM.CoreLib.Symbols.ImageFileMachine.Unknown; break; default: - throw new FatalCompilerErrorException(DiagnosticEvent.UnrecognizedPlatform(options.Platform.ToString())); + throw new DiagnosticEventException(DiagnosticEvent.UnrecognizedPlatform(options.Platform.ToString())); } switch (options.Apartment) @@ -147,7 +147,7 @@ void Create(ImportOptions options, ImportContext import, List tar import.apartment = ApartmentState.Unknown; break; default: - throw new FatalCompilerErrorException(DiagnosticEvent.UnrecognizedApartment(options.Apartment.ToString())); + throw new DiagnosticEventException(DiagnosticEvent.UnrecognizedApartment(options.Apartment.ToString())); } if (options.NoGlobbing) @@ -218,20 +218,20 @@ void Create(ImportOptions options, ImportContext import, List tar } catch (PathTooLongException) { - throw new FatalCompilerErrorException(DiagnosticEvent.PathTooLong(spec)); + throw new DiagnosticEventException(DiagnosticEvent.PathTooLong(spec)); } catch (DirectoryNotFoundException) { - throw new FatalCompilerErrorException(DiagnosticEvent.PathNotFound(spec)); + throw new DiagnosticEventException(DiagnosticEvent.PathNotFound(spec)); } catch (ArgumentException) { - throw new FatalCompilerErrorException(DiagnosticEvent.InvalidPath(spec)); + throw new DiagnosticEventException(DiagnosticEvent.InvalidPath(spec)); } } if (!found) - throw new FatalCompilerErrorException(DiagnosticEvent.FileNotFound(spec)); + throw new DiagnosticEventException(DiagnosticEvent.FileNotFound(spec)); } foreach (var kvp in options.Resources) @@ -244,9 +244,9 @@ void Create(ImportOptions options, ImportContext import, List tar foreach (var kvp in options.ExternalResources) { if (!File.Exists(kvp.Value.FullName)) - throw new FatalCompilerErrorException(DiagnosticEvent.ExternalResourceNotFound(kvp.Value.FullName)); + throw new DiagnosticEventException(DiagnosticEvent.ExternalResourceNotFound(kvp.Value.FullName)); if (Path.GetFileName(kvp.Value.FullName) != kvp.Value.FullName) - throw new FatalCompilerErrorException(DiagnosticEvent.ExternalResourceNameInvalid(kvp.Value.FullName)); + throw new DiagnosticEventException(DiagnosticEvent.ExternalResourceNameInvalid(kvp.Value.FullName)); // TODO resource name clashes should be tested import.externalResources ??= new Dictionary(); @@ -346,7 +346,7 @@ void Create(ImportOptions options, ImportContext import, List tar if (options.FileAlign != null) { if (!uint.TryParse(options.FileAlign, out var filealign) || filealign < 512 || filealign > 8192 || (filealign & (filealign - 1)) != 0) - throw new FatalCompilerErrorException(DiagnosticEvent.InvalidFileAlignment(options.FileAlign)); + throw new DiagnosticEventException(DiagnosticEvent.InvalidFileAlignment(options.FileAlign)); import.fileAlignment = filealign; } @@ -397,7 +397,7 @@ void Create(ImportOptions options, ImportContext import, List tar import.bootstrap = true; if (import.targetIsModule && import.sharedclassloader != null) - throw new FatalCompilerErrorException(DiagnosticEvent.SharedClassLoaderCannotBeUsedOnModuleTarget()); + throw new DiagnosticEventException(DiagnosticEvent.SharedClassLoaderCannotBeUsedOnModuleTarget()); ReadFiles(import, options.Inputs.Select(i => i.FullName).ToList()); @@ -414,7 +414,7 @@ void Create(ImportOptions options, ImportContext import, List tar { var basename = import.path == null ? import.defaultAssemblyName : import.path.Name; if (basename == null) - throw new FatalCompilerErrorException(DiagnosticEvent.NoOutputFileSpecified()); + throw new DiagnosticEventException(DiagnosticEvent.NoOutputFileSpecified()); int idx = basename.LastIndexOf('.'); if (idx > 0) @@ -446,7 +446,7 @@ void Create(ImportOptions options, ImportContext import, List tar /// Resolves the intra-peer references in the list of imports. /// /// - /// + /// void ResolveReferences(List imports) { var cache = new Dictionary(); @@ -474,12 +474,12 @@ void ResolveReferences(List imports) } if (resolver.ResolveReference(cache, refs, reference) == false) - throw new FatalCompilerErrorException(DiagnosticEvent.ReferenceNotFound(reference)); + throw new DiagnosticEventException(DiagnosticEvent.ReferenceNotFound(reference)); } // transform references into symbols foreach (var a in refs) - import.references.Add(runtime.Resolver.ImportAssembly(a)); + import.references.Add(runtime.Resolver.GetSymbol(a)); } } @@ -510,16 +510,16 @@ void ResolveReferences(List imports) /// Resolves any strong name keys. /// /// - /// + /// void ResolveStrongNameKeys(List targets) { foreach (var options in targets) { if (options.keyfile != null && options.keycontainer != null) - throw new FatalCompilerErrorException(DiagnosticEvent.CannotSpecifyBothKeyFileAndContainer()); + throw new DiagnosticEventException(DiagnosticEvent.CannotSpecifyBothKeyFileAndContainer()); if (options.keyfile == null && options.keycontainer == null && options.delaysign) - throw new FatalCompilerErrorException(DiagnosticEvent.DelaySignRequiresKey()); + throw new DiagnosticEventException(DiagnosticEvent.DelaySignRequiresKey()); if (options.keyfile != null) { @@ -563,7 +563,7 @@ static internal byte[] ReadAllBytes(FileInfo path) } catch (Exception x) { - throw new FatalCompilerErrorException(DiagnosticEvent.ErrorReadingFile(path.ToString(), x.Message)); + throw new DiagnosticEventException(DiagnosticEvent.ErrorReadingFile(path.ToString(), x.Message)); } } @@ -575,26 +575,26 @@ static internal FileInfo GetFileInfo(string path) if (fileInfo.Directory == null) { // this happens with an incorrect unc path (e.g. "\\foo\bar") - throw new FatalCompilerErrorException(DiagnosticEvent.InvalidPath(path)); + throw new DiagnosticEventException(DiagnosticEvent.InvalidPath(path)); } return fileInfo; } catch (ArgumentException) { - throw new FatalCompilerErrorException(DiagnosticEvent.InvalidPath(path)); + throw new DiagnosticEventException(DiagnosticEvent.InvalidPath(path)); } catch (NotSupportedException) { - throw new FatalCompilerErrorException(DiagnosticEvent.InvalidPath(path)); + throw new DiagnosticEventException(DiagnosticEvent.InvalidPath(path)); } catch (PathTooLongException) { - throw new FatalCompilerErrorException(DiagnosticEvent.PathTooLong(path)); + throw new DiagnosticEventException(DiagnosticEvent.PathTooLong(path)); } catch (UnauthorizedAccessException) { // this exception does not appear to be possible - throw new FatalCompilerErrorException(DiagnosticEvent.InvalidPath(path)); + throw new DiagnosticEventException(DiagnosticEvent.InvalidPath(path)); } } @@ -714,7 +714,7 @@ void SetStrongNameKeyPair(ref StrongNameKeyPair strongNameKeyPair, FileInfo keyF } catch (Exception e) { - throw new FatalCompilerErrorException(DiagnosticEvent.InvalidStrongNameKeyPair(keyFile != null ? "file" : "container", e.Message)); + throw new DiagnosticEventException(DiagnosticEvent.InvalidStrongNameKeyPair(keyFile != null ? "file" : "container", e.Message)); } } @@ -861,7 +861,7 @@ bool ProcessZipFile(ImportContext import, string file, Predicate annotations, string filename) } catch (Exception x) { - throw new FatalCompilerErrorException(DiagnosticEvent.ErrorReadingFile(filename, x.Message)); + throw new DiagnosticEventException(DiagnosticEvent.ErrorReadingFile(filename, x.Message)); } } diff --git a/src/IKVM.Tools.Importer/ImportDiagnosticHandler.cs b/src/IKVM.Tools.Importer/ImportDiagnosticHandler.cs index 09a816b42..53d32a8a1 100644 --- a/src/IKVM.Tools.Importer/ImportDiagnosticHandler.cs +++ b/src/IKVM.Tools.Importer/ImportDiagnosticHandler.cs @@ -30,8 +30,8 @@ public ImportDiagnosticHandler(ImportOptions options, string spec, DiagnosticFor /// public override bool IsEnabled(Diagnostic diagnostic) { - if (diagnostic.Level is DiagnosticLevel.Trace or DiagnosticLevel.Info) - return false; + //if (diagnostic.Level is DiagnosticLevel.Trace or DiagnosticLevel.Info) + // return false; if (diagnostic.Level == DiagnosticLevel.Warning && _options.NoWarn.Any(i => i.Id == diagnostic.Id)) return false; diff --git a/src/IKVM.Tools.Importer/ImportRuntimeSymbolResolver.cs b/src/IKVM.Tools.Importer/ImportRuntimeSymbolResolver.cs index 927dbfc67..87799b064 100644 --- a/src/IKVM.Tools.Importer/ImportRuntimeSymbolResolver.cs +++ b/src/IKVM.Tools.Importer/ImportRuntimeSymbolResolver.cs @@ -21,9 +21,12 @@ Jeroen Frijters jeroen@frijters.net */ +#nullable enable + using System; -using System.IO; -using System.Threading; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; using IKVM.CoreLib.Diagnostics; using IKVM.CoreLib.Symbols; @@ -41,12 +44,37 @@ namespace IKVM.Tools.Importer class ImportRuntimeSymbolResolver : IRuntimeSymbolResolver { - readonly IDiagnosticHandler diagnostics; - readonly Universe universe; - readonly IkvmReflectionSymbolContext symbols; - readonly ImportOptions options; - IAssemblySymbol runtimeAssembly; - IAssemblySymbol baseAssembly; + /// + /// Gets the set of types from which to discover system assemblies. + /// + /// + static IEnumerable GetSystemTypeNames() + { + yield return "System.Object"; + yield return "System.Runtime.CompilerServices.RuntimeCompatibilityAttribute"; + yield return "System.Console"; + yield return "System.Threading.Interlocked"; + yield return "System.ComponentModel.EditorBrowsableAttribute"; + yield return "System.Collections.IEnumerable"; + yield return "System.Collections.Generic.IEnumerable`1"; + yield return "System.Environment"; + } + + readonly IDiagnosticHandler _diagnostics; + readonly Universe _universe; + readonly IkvmReflectionSymbolContext _symbols; + + IAssemblySymbol? _coreAssembly; + readonly ConcurrentDictionary _coreTypeCache = new(); + + IAssemblySymbol[]? _systemAssemblies; + readonly ConcurrentDictionary _systemTypeCache = new(); + + IAssemblySymbol? _runtimeAssembly; + readonly ConcurrentDictionary _runtimeTypeCache = new(); + + IAssemblySymbol? _baseAssembly; + readonly ConcurrentDictionary _baseTypeCache = new(); /// /// Initializes a new instance. @@ -54,165 +82,206 @@ class ImportRuntimeSymbolResolver : IRuntimeSymbolResolver /// /// /// - /// /// - public ImportRuntimeSymbolResolver(IDiagnosticHandler diagnostics, Universe universe, IkvmReflectionSymbolContext symbols, ImportOptions options) + public ImportRuntimeSymbolResolver(IDiagnosticHandler diagnostics, Universe universe, IkvmReflectionSymbolContext symbols) { - this.diagnostics = diagnostics ?? throw new ArgumentNullException(nameof(diagnostics)); - this.universe = universe ?? throw new ArgumentNullException(nameof(universe)); - this.symbols = symbols ?? throw new ArgumentNullException(nameof(symbols)); - this.options = options ?? throw new ArgumentNullException(nameof(options)); + _diagnostics = diagnostics ?? throw new ArgumentNullException(nameof(diagnostics)); + _universe = universe ?? throw new ArgumentNullException(nameof(universe)); + _symbols = symbols ?? throw new ArgumentNullException(nameof(symbols)); } /// - public ISymbolContext Symbols => symbols; + public ISymbolContext Symbols => _symbols; /// - public IAssemblySymbol ResolveCoreAssembly() + public IAssemblySymbol GetCoreAssembly() { - try - { - if (ImportAssembly(universe.CoreLib) is { } a) - return a; - } - catch (FileNotFoundException) - { - - } - - throw new FatalCompilerErrorException(DiagnosticEvent.CoreClassesMissing()); + return (_coreAssembly ??= GetSymbol(_universe.CoreLib)) ?? throw new DiagnosticEventException(DiagnosticEvent.CoreClassesMissing()); } /// - public IAssemblySymbol ResolveRuntimeAssembly() + public IAssemblySymbol GetRuntimeAssembly() { - if (runtimeAssembly == null) - Interlocked.CompareExchange(ref runtimeAssembly, LoadRuntimeAssembly(), null); - - return runtimeAssembly; + return (_runtimeAssembly ??= FindRuntimeAssembly()) ?? throw new DiagnosticEventException(DiagnosticEvent.RuntimeNotFound()); } /// /// Attempts to load the runtime assembly. /// - /// - IAssemblySymbol LoadRuntimeAssembly() + IAssemblySymbol? FindRuntimeAssembly() { - foreach (var assembly in universe.GetAssemblies()) + foreach (var assembly in _universe.GetAssemblies()) if (assembly.GetType("IKVM.Runtime.JVM") is Type) - return ImportAssembly(assembly); + return GetSymbol(assembly); - throw new FatalCompilerErrorException(DiagnosticEvent.RuntimeNotFound()); + return null; } /// - public IAssemblySymbol ResolveBaseAssembly() + public IAssemblySymbol GetBaseAssembly() { - if (baseAssembly == null) - Interlocked.CompareExchange(ref baseAssembly, LoadBaseAssembly(), null); - - return baseAssembly; + return (_baseAssembly ??= FindBaseAssembly()) ?? throw new DiagnosticEventException(DiagnosticEvent.BootstrapClassesMissing()); } /// /// Attempts to load the base assembly. /// - IAssemblySymbol LoadBaseAssembly() + IAssemblySymbol? FindBaseAssembly() { - foreach (var assembly in universe.GetAssemblies()) + foreach (var assembly in _universe.GetAssemblies()) if (assembly.GetType("java.lang.Object") is Type) - return ImportAssembly(assembly); + return GetSymbol(assembly); - throw new Exception(); + return null; } /// public ITypeSymbol ResolveCoreType(string typeName) { - return ResolveCoreAssembly().GetType(typeName); + return _coreTypeCache.GetOrAdd(typeName, _ => GetCoreAssembly().GetType(_)) ?? throw new DiagnosticEventException(DiagnosticEvent.CoreClassesMissing()); + } + + /// + /// Resolves the set of system assemblies. + /// + /// + IAssemblySymbol[] ResolveSystemAssemblies() + { + return _systemAssemblies ??= ResolveSystemAssembliesIter().Distinct().ToArray(); + } + + /// + /// Resolves the set of system assemblies that contain the system types. + /// + /// + IEnumerable ResolveSystemAssembliesIter() + { + foreach (var assembly in _universe.GetAssemblies()) + foreach (var typeName in GetSystemTypeNames()) + if (assembly.GetType(typeName) is Type t) + yield return GetSymbol(assembly); } /// - public ITypeSymbol ResolveRuntimeType(string typeName) + public ITypeSymbol ResolveSystemType(string typeName) { - return ResolveRuntimeAssembly().GetType(typeName); + return _systemTypeCache.GetOrAdd(typeName, FindSystemType) ?? throw new DiagnosticEventException(DiagnosticEvent.ClassNotFound(typeName)); + } + + /// + /// Attempts to load the specified system type. + /// + /// + /// + ITypeSymbol? FindSystemType(string typeName) + { + foreach (var assembly in ResolveSystemAssemblies()) + if (assembly.GetType(typeName) is { } t) + return t; + + return null; + } + + /// + public ITypeSymbol? ResolveRuntimeType(string typeName) + { + return GetRuntimeAssembly().GetType(typeName); } /// - public ITypeSymbol ResolveBaseType(string typeName) + public ITypeSymbol? ResolveBaseType(string typeName) { - return ResolveBaseAssembly().GetType(typeName); + return GetBaseAssembly().GetType(typeName); } /// - public IAssemblySymbol ResolveAssembly(string assemblyName) + public IAssemblySymbol? ResolveAssembly(string assemblyName) { - return universe.Load(assemblyName) is { } a ? symbols.GetOrCreateAssemblySymbol(a) : null; + return _universe.Load(assemblyName) is { } a ? GetSymbol(a) : null; } /// - public ITypeSymbol ResolveType(string typeName) + public ITypeSymbol? ResolveType(string typeName) { - foreach (var assembly in universe.GetAssemblies()) + foreach (var assembly in _universe.GetAssemblies()) if (assembly.GetType(typeName) is Type t) - return ImportType(t); + return GetSymbol(t); return null; } /// - public IAssemblySymbol ImportAssembly(Assembly assembly) + public IAssemblySymbol GetSymbol(Assembly assembly) { - return symbols.GetOrCreateAssemblySymbol(assembly); + return _symbols.GetOrCreateAssemblySymbol(assembly); } /// - public IAssemblySymbolBuilder ImportAssembly(AssemblyBuilder assembly) + public IAssemblySymbolBuilder GetSymbol(AssemblyBuilder assembly) { - return symbols.GetOrCreateAssemblySymbol(assembly); + return _symbols.GetOrCreateAssemblySymbol(assembly); } /// - public IModuleSymbol ImportModule(Module module) + public IModuleSymbol GetSymbol(Module module) { - return symbols.GetOrCreateModuleSymbol(module); + return _symbols.GetOrCreateModuleSymbol(module); } /// - public IModuleSymbolBuilder ImportModule(ModuleBuilder module) + public IModuleSymbolBuilder GetSymbol(ModuleBuilder module) { - return symbols.GetOrCreateModuleSymbol(module); + return _symbols.GetOrCreateModuleSymbol(module); } /// - public ITypeSymbol ImportType(Type type) + public ITypeSymbol GetSymbol(Type type) { - return symbols.GetOrCreateTypeSymbol(type); + return _symbols.GetOrCreateTypeSymbol(type); } /// - public IMemberSymbol ImportMember(MemberInfo memberInfo) + public IMemberSymbol GetSymbol(MemberInfo memberInfo) { - return symbols.GetOrCreateMemberSymbol(memberInfo); + return _symbols.GetOrCreateMemberSymbol(memberInfo); } /// - public IMethodBaseSymbol ImportMethodBase(MethodBase type) + public IMethodBaseSymbol GetSymbol(MethodBase type) { - return symbols.GetOrCreateMethodBaseSymbol(type); + return _symbols.GetOrCreateMethodBaseSymbol(type); } /// - public IConstructorSymbol ImportConstructor(ConstructorInfo ctor) + public IConstructorSymbol GetSymbol(ConstructorInfo ctor) { - return symbols.GetOrCreateConstructorSymbol(ctor); + return _symbols.GetOrCreateConstructorSymbol(ctor); } /// - public IMethodSymbol ImportMethod(MethodInfo method) + public IMethodSymbol GetSymbol(MethodInfo method) { - return symbols.GetOrCreateMethodSymbol(method); + return _symbols.GetOrCreateMethodSymbol(method); } + + /// + public IFieldSymbol GetSymbol(FieldInfo field) + { + return _symbols.GetOrCreateFieldSymbol(field); + } + + /// + public IPropertySymbol GetSymbol(PropertyInfo property) + { + return _symbols.GetOrCreatePropertySymbol(property); + } + + /// + public IEventSymbol GetSymbol(EventInfo @event) + { + return _symbols.GetOrCreateEventSymbol(@event); + } + } } \ No newline at end of file diff --git a/src/IKVM.Tools.Importer/ImportTool.cs b/src/IKVM.Tools.Importer/ImportTool.cs index 5690e4466..6dd53d232 100644 --- a/src/IKVM.Tools.Importer/ImportTool.cs +++ b/src/IKVM.Tools.Importer/ImportTool.cs @@ -7,6 +7,7 @@ using System.IO; using System.Reflection.Metadata; using System.Reflection.PortableExecutable; +using System.Runtime.ExceptionServices; using System.Threading; using System.Threading.Tasks; @@ -70,7 +71,7 @@ async Task ExecuteImplAsync(ImportOptions options, CancellationToken cancel services.AddSingleton(p => p.GetRequiredService().Universe); services.AddSingleton(); services.AddSingleton(); - services.AddSingleton(p => new RuntimeContextOptions(p.GetRequiredService().Bootstrap)); + services.AddSingleton(p => CreateContextOptions(p)); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); @@ -78,28 +79,34 @@ async Task ExecuteImplAsync(ImportOptions options, CancellationToken cancel try { - // convert options to imports - var imports = provider.GetRequiredService().Create(options); - if (imports.Count == 0) - throw new FatalCompilerErrorException(DiagnosticEvent.NoTargetsFound()); - - // execute the compiler - return await Task.Run(() => Execute( - provider.GetRequiredService(), - provider.GetRequiredService(), - provider.GetRequiredService(), - imports)); + try + { + // convert options to imports + var imports = provider.GetRequiredService().Create(options); + if (imports.Count == 0) + throw new DiagnosticEventException(DiagnosticEvent.NoTargetsFound()); + + // execute the compiler + return await Task.Run(() => Execute( + provider.GetRequiredService(), + provider.GetRequiredService(), + provider.GetRequiredService(), + imports)); + } + catch (DiagnosticEventException e) + { + ExceptionDispatchInfo.Capture(e).Throw(); + throw; + } + catch (Exception e) + { + throw new DiagnosticEventException(DiagnosticEvent.GenericCompilerError(e.Message)); + } } - catch (FatalCompilerErrorException e) + catch (DiagnosticEventException e) { provider.GetRequiredService().Report(e.Event); return e.Event.Diagnostic.Id; - - } - catch (Exception e) - { - provider.GetRequiredService().GenericCompilerError(e.Message); - return Diagnostic.GenericCompilerError.Id; } } @@ -270,6 +277,19 @@ static DiagnosticOptions GetDiagnosticOptions(IServiceProvider services, ImportO }; } + /// + /// Creates the . + /// + /// + /// + static RuntimeContextOptions CreateContextOptions(IServiceProvider services) + { + var u = services.GetRequiredService(); + var isNetFX = u.CoreLibName == "mscorlib"; + var dynamicSuffix = isNetFX ? RuntimeContextOptions.SignedDefaultDynamicAssemblySuffixAndPublicKey : RuntimeContextOptions.UnsignedDefaultDynamicAssemblySuffixAndPublicKey; + return new RuntimeContextOptions(services.GetRequiredService().Bootstrap, dynamicSuffix); + } + /// /// Initializes a new instance. /// diff --git a/src/IKVM.Tools.Importer/RuntimeImportByteCodeJavaType.cs b/src/IKVM.Tools.Importer/RuntimeImportByteCodeJavaType.cs index 0cad9fc1f..13b650c2e 100644 --- a/src/IKVM.Tools.Importer/RuntimeImportByteCodeJavaType.cs +++ b/src/IKVM.Tools.Importer/RuntimeImportByteCodeJavaType.cs @@ -696,7 +696,7 @@ protected override void FinishGhost(ITypeSymbolBuilder typeBuilder, RuntimeJavaM if (methods[i].IsAbstract) { // This should only happen for remapped types (defined in map.xml), because normally you'd get a miranda method. - throw new FatalCompilerErrorException(DiagnosticEvent.GhostInterfaceMethodMissing(implementers[j].Name, Name, methods[i].Name, methods[i].Signature)); + throw new DiagnosticEventException(DiagnosticEvent.GhostInterfaceMethodMissing(implementers[j].Name, Name, methods[i].Name, methods[i].Signature)); } // We're inheriting a default method ilgen.Emit(OpCodes.Pop); diff --git a/src/IKVM.Tools.Importer/StaticCompiler.cs b/src/IKVM.Tools.Importer/StaticCompiler.cs index 52f8d526c..ab413e256 100644 --- a/src/IKVM.Tools.Importer/StaticCompiler.cs +++ b/src/IKVM.Tools.Importer/StaticCompiler.cs @@ -80,19 +80,19 @@ internal IAssemblySymbol LoadFile(string path) internal ITypeSymbol GetTypeForMapXml(RuntimeClassLoader loader, string name) { - return GetType(loader, name) ?? throw new FatalCompilerErrorException(DiagnosticEvent.MapFileTypeNotFound(name)); + return GetType(loader, name) ?? throw new DiagnosticEventException(DiagnosticEvent.MapFileTypeNotFound(name)); } internal RuntimeJavaType GetClassForMapXml(RuntimeClassLoader loader, string name) { - return loader.TryLoadClassByName(name) ?? throw new FatalCompilerErrorException(DiagnosticEvent.MapFileClassNotFound(name)); + return loader.TryLoadClassByName(name) ?? throw new DiagnosticEventException(DiagnosticEvent.MapFileClassNotFound(name)); } internal RuntimeJavaField GetFieldForMapXml(RuntimeClassLoader loader, string clazz, string name, string sig) { var fw = GetClassForMapXml(loader, clazz).GetFieldWrapper(name, sig); if (fw == null) - throw new FatalCompilerErrorException(DiagnosticEvent.MapFileFieldNotFound(name, clazz)); + throw new DiagnosticEventException(DiagnosticEvent.MapFileFieldNotFound(name, clazz)); fw.Link(); return fw; @@ -116,7 +116,7 @@ internal static void LinkageError(string msg, RuntimeJavaType actualType, Runtim str += string.Format("\n\t(Please add a reference to {0})", expectedType.TypeAsBaseType.Assembly.Location); } - throw new FatalCompilerErrorException(DiagnosticEvent.LinkageError(str)); + throw new DiagnosticEventException(DiagnosticEvent.LinkageError(str)); } static string AssemblyQualifiedName(RuntimeJavaType javaType) diff --git a/src/ikvmc/Properties/launchSettings.json b/src/ikvmc/Properties/launchSettings.json index a472b2cda..31d9cf801 100644 --- a/src/ikvmc/Properties/launchSettings.json +++ b/src/ikvmc/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "ikvmc": { "commandName": "Project", - "commandLineArgs": "@D:\\ikvm\\src\\IKVM.Java\\obj\\Debug\\net472\\IKVM.Java.ikvmc.rsp" + "commandLineArgs": "@D:\\ikvm\\src\\IKVM.Java\\obj\\Debug\\net8.0\\IKVM.Java.ikvmc.rsp" } } } diff --git a/src/ikvmc/ikvmc.csproj b/src/ikvmc/ikvmc.csproj index 2be36ac43..ae6f133e1 100644 --- a/src/ikvmc/ikvmc.csproj +++ b/src/ikvmc/ikvmc.csproj @@ -1,7 +1,7 @@  Exe - net472;net8.0;;net6.0; + net8.0;net472;;net6.0; $(_SupportedToolRuntimes) true true diff --git a/src/ikvmstub/Properties/launchSettings.json b/src/ikvmstub/Properties/launchSettings.json index c08101f8e..64fa8dc5e 100644 --- a/src/ikvmstub/Properties/launchSettings.json +++ b/src/ikvmstub/Properties/launchSettings.json @@ -1,8 +1,8 @@ { "profiles": { "ikvmstub": { - "commandName": "Project", - "commandLineArgs": "--bootstrap --skiperror --nostdlib --parameters --lib:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\" --reference:\"D:\\ikvm\\src\\IKVM.Java-ref\\obj\\Debug\\net8.0\\ref\\IKVM.Java.dll\" --reference:\"D:\\ikvm\\src\\IKVM.Runtime-ref\\obj\\Debug\\net8.0\\ref\\IKVM.Runtime.dll\" --out:\"C:\\Users\\jhaltom\\System.Threading.jar\" \"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Threading.dll\"" + "commandName": "Project", + "commandLineArgs": "--bootstrap --nostdlib --skiperror --parameters --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\Microsoft.Win32.Primitives.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Collections.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Net.Primitives.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Runtime.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Runtime.InteropServices.dll\" --reference:\"D:\\ikvm\\src\\IKVM.Java\\bin\\Debug\\net8.0\\IKVM.Java.dll\" --reference:\"D:\\ikvm\\src\\IKVM.Runtime-ref\\obj\\Debug\\net8.0\\ref\\IKVM.Runtime.dll\" --out:\"C:\\Users\\jhaltom\\System.Net.Primitives.jar\" \"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Net.Primitives.dll\"" } } } \ No newline at end of file From 1e14f735db527eeacfcae9dc25b119d52af86f98 Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Fri, 27 Sep 2024 19:55:03 -0500 Subject: [PATCH 16/51] More. --- .../IkvmReflection/IkvmReflectionSymbol.cs | 1 + src/IKVM.Runtime/Accessors/FieldAccessor.cs | 28 ++++---- src/IKVM.Runtime/Accessors/MethodAccessor.cs | 19 +++--- .../Accessors/PropertyAccessor.cs | 12 ++-- src/IKVM.Runtime/AttributeHelper.cs | 3 +- src/IKVM.Runtime/ExceptionHelper.cs | 2 +- .../Java/Externs/ikvm/internal/CallerID.cs | 6 +- .../runtime/AppDomainAssemblyClassLoader.cs | 4 +- .../ikvm/runtime/AssemblyClassLoader.cs | 10 +-- .../Java/Externs/ikvm/runtime/Launcher.cs | 2 +- .../Java/Externs/ikvm/runtime/Startup.cs | 2 +- .../Java/Externs/ikvm/runtime/Util.cs | 4 +- .../Java/Externs/java/lang/SecurityManager.cs | 2 +- .../java/lang/invoke/MethodHandleNatives.cs | 9 +-- .../Java/Externs/java/lang/reflect/Array.cs | 65 ++++++++++--------- .../Externs/java/security/AccessController.cs | 2 +- .../Java/Externs/sun/misc/MiscHelper.cs | 4 +- .../Java/Externs/sun/misc/Unsafe.cs | 8 +-- src/IKVM.Runtime/Java/Externs/sun/misc/VM.cs | 6 +- .../sun/net/www/protocol/ikvmres/Handler.cs | 2 +- .../Java/Externs/sun/reflect/Reflection.cs | 4 +- src/IKVM.Runtime/Launcher.cs | 4 +- .../MethodHandleUtil.jniexport.cs | 24 +++---- src/IKVM.Runtime/MethodHandleUtil.root.cs | 8 +-- src/IKVM.Runtime/ReflectUtil.cs | 2 + .../RuntimeAssemblyClassLoaderFactory.cs | 3 +- src/IKVM.Runtime/RuntimeClassLoader.cs | 2 +- ...tionJavaType.MultipleAnnotationJavaType.cs | 2 +- ...ntimeManagedJavaType.EnumWrapJavaMethod.cs | 2 +- .../Vfs/VfsAssemblyClassDirectory.cs | 10 +-- src/ikvmc/ikvmc.csproj | 2 +- src/ikvmstub/Properties/launchSettings.json | 2 +- src/ikvmstub/ikvmstub.csproj | 2 +- 33 files changed, 128 insertions(+), 130 deletions(-) diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs index 68f30b47d..b766fd03e 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs @@ -508,6 +508,7 @@ public CustomAttributeTypedArgument ResolveCustomAttributeTypedArgument(IKVM.Ref { return value switch { + IList aa => ResolveCustomAttributeTypedArguments(aa), Type v => ResolveTypeSymbol(v), _ => value }; diff --git a/src/IKVM.Runtime/Accessors/FieldAccessor.cs b/src/IKVM.Runtime/Accessors/FieldAccessor.cs index 40a44cf98..8b8ab657c 100644 --- a/src/IKVM.Runtime/Accessors/FieldAccessor.cs +++ b/src/IKVM.Runtime/Accessors/FieldAccessor.cs @@ -102,11 +102,10 @@ Func MakeGetter() throw new NotImplementedException(); #else var dm = DynamicMethodUtil.Create($"____{Type.Name.Replace(".", "_")}__{Field.Name}", Type, false, typeof(TField), Array.Empty()); - var il = JVM.Context.CodeEmitterFactory.Create(dm); + var il = dm.GetILGenerator(); il.Emit(OpCodes.Ldsfld, Field); il.Emit(OpCodes.Ret); - il.DoEmit(); return (Func)dm.CreateDelegate(typeof(Func)); #endif @@ -123,12 +122,11 @@ Action MakeSetter() throw new NotImplementedException(); #else var dm = DynamicMethodUtil.Create($"____{Type.Name.Replace(".", "_")}__{Field.Name}", Type, false, typeof(void), new[] { typeof(TField) }); - var il = JVM.Context.CodeEmitterFactory.Create(dm); + var il = dm.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Stsfld, Field); il.Emit(OpCodes.Ret); - il.DoEmit(); return (Action)dm.CreateDelegate(typeof(Action)); #endif @@ -231,13 +229,12 @@ GetterDelegate MakeGetter() throw new NotImplementedException(); #else var dm = DynamicMethodUtil.Create($"____{Field.DeclaringType.Name.Replace(".", "_")}__{Field.Name}", Type, false, typeof(TField), new[] { typeof(TObject) }); - var il = JVM.Context.CodeEmitterFactory.Create(dm); + var il = dm.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Castclass, Type); il.Emit(OpCodes.Ldfld, Field); il.Emit(OpCodes.Ret); - il.DoEmit(); return (GetterDelegate)dm.CreateDelegate(typeof(GetterDelegate)); #endif @@ -253,14 +250,13 @@ SetterDelegate MakeSetter() throw new NotImplementedException(); #else var dm = DynamicMethodUtil.Create($"____{Field.DeclaringType.Name.Replace(".", "_")}__{Field.Name}", Type, false, typeof(void), new[] { typeof(TObject), typeof(TField) }); - var il = JVM.Context.CodeEmitterFactory.Create(dm); + var il = dm.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Castclass, Type); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Stfld, Field); il.Emit(OpCodes.Ret); - il.DoEmit(); return (SetterDelegate)dm.CreateDelegate(typeof(SetterDelegate)); #endif @@ -276,12 +272,12 @@ ExchangeDelegate MakeExchange() throw new NotImplementedException(); #else var dm = DynamicMethodUtil.Create($"____{Field.DeclaringType.Name.Replace(".", "_")}__{Field.Name}", Type, false, typeof(TField), new[] { typeof(TObject), typeof(TField) }); - var il = JVM.Context.CodeEmitterFactory.Create(dm); + var il = dm.GetILGenerator(); - il.EmitLdarg(0); + il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Castclass, Type); il.Emit(Field.IsStatic ? OpCodes.Ldsflda: OpCodes.Ldflda, Field); - il.EmitLdarg(1); + il.Emit(OpCodes.Ldarg_1); switch (typeof(TField)) { @@ -305,7 +301,6 @@ ExchangeDelegate MakeExchange() } il.Emit(OpCodes.Ret); - il.DoEmit(); return (ExchangeDelegate)dm.CreateDelegate(typeof(ExchangeDelegate)); #endif @@ -321,13 +316,13 @@ CompareExchangeDelegate MakeCompareExchange() throw new NotImplementedException(); #else var dm = DynamicMethodUtil.Create($"____{Field.DeclaringType.Name.Replace(".", "_")}__{Field.Name}", Type, false, typeof(TField), new[] { typeof(TObject), typeof(TField), typeof(TField) }); - var il = JVM.Context.CodeEmitterFactory.Create(dm); + var il = dm.GetILGenerator(); - il.EmitLdarg(0); + il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Castclass, Type); il.Emit(Field.IsStatic ? OpCodes.Ldsflda : OpCodes.Ldflda, Field); - il.EmitLdarg(1); - il.EmitLdarg(2); + il.Emit(OpCodes.Ldarg_1); + il.Emit(OpCodes.Ldarg_2); switch (typeof(TField)) { @@ -351,7 +346,6 @@ CompareExchangeDelegate MakeCompareExchange() } il.Emit(OpCodes.Ret); - il.DoEmit(); return (CompareExchangeDelegate)dm.CreateDelegate(typeof(CompareExchangeDelegate)); #endif diff --git a/src/IKVM.Runtime/Accessors/MethodAccessor.cs b/src/IKVM.Runtime/Accessors/MethodAccessor.cs index 0e0088ab1..09446acec 100644 --- a/src/IKVM.Runtime/Accessors/MethodAccessor.cs +++ b/src/IKVM.Runtime/Accessors/MethodAccessor.cs @@ -139,7 +139,7 @@ TDelegate MakeInvoker() // generate new dynamic method var dm = DynamicMethodUtil.Create($"____{Type.Name.Replace(".", "_")}__{Method.Name}", Type, false, delegateReturnType, delegateParameterTypes); - var il = JVM.Context.CodeEmitterFactory.Create(dm); + var il = dm.GetILGenerator(); // advance through each argument var n = 0; @@ -147,34 +147,33 @@ TDelegate MakeInvoker() // load first argument, which is the instance if non-static if (Method.IsStatic == false && Method.IsConstructor == false) { - il.EmitLdarg(n++); + il.Emit(OpCodes.Ldarg, n++); if (delegateParameterTypes[0] != Type) - il.EmitCastclass(Type); + il.Emit(OpCodes.Castclass, Type); } // emit conversion code for the remainder of the arguments for (var i = 0; i < parameters.Length; i++) { var delegateParameterType = delegateParameterTypes[n]; - il.EmitLdarg(n++); + il.Emit(OpCodes.Ldarg, n++); if (parameters[i].ParameterType != delegateParameterType) - il.EmitCastclass(parameters[i].ParameterType); + il.Emit(OpCodes.Castclass, parameters[i].ParameterType); } if (Method.IsConstructor) - il.Emit(OpCodes.Newobj, Method); + il.Emit(OpCodes.Newobj, (ConstructorInfo)Method); else if (Method.IsStatic || Method.IsVirtual == false) - il.Emit(OpCodes.Call, Method); + il.Emit(OpCodes.Call, (MethodInfo)Method); else - il.Emit(OpCodes.Callvirt, Method); + il.Emit(OpCodes.Callvirt, (MethodInfo)Method); // convert to delegate value if (delegateReturnType != typeof(void)) if (Method.IsConstructor && delegateReturnType != Type || Method.IsConstructor == false && delegateReturnType != ((MethodInfo)Method).ReturnType) - il.EmitCastclass(delegateReturnType); + il.Emit(OpCodes.Castclass, delegateReturnType); il.Emit(OpCodes.Ret); - il.DoEmit(); return (TDelegate)dm.CreateDelegate(typeof(TDelegate)); #endif diff --git a/src/IKVM.Runtime/Accessors/PropertyAccessor.cs b/src/IKVM.Runtime/Accessors/PropertyAccessor.cs index 88aee410d..c078d1ae5 100644 --- a/src/IKVM.Runtime/Accessors/PropertyAccessor.cs +++ b/src/IKVM.Runtime/Accessors/PropertyAccessor.cs @@ -101,11 +101,10 @@ Func MakeGetter() throw new NotImplementedException(); #else var dm = DynamicMethodUtil.Create($"____{Type.Name.Replace(".", "_")}__{Property.Name}", Type, false, typeof(TProperty), Array.Empty()); - var il = JVM.Context.CodeEmitterFactory.Create(dm); + var il = dm.GetILGenerator(); il.Emit(Property.GetMethod.IsVirtual ? OpCodes.Callvirt : OpCodes.Call, Property.GetMethod); il.Emit(OpCodes.Ret); - il.DoEmit(); return (Func)dm.CreateDelegate(typeof(Func)); #endif @@ -122,12 +121,11 @@ Action MakeSetter() throw new NotImplementedException(); #else var dm = DynamicMethodUtil.Create($"____{Type.Name.Replace(".", "_")}__{Property.Name}", Type, false, typeof(void), new[] { typeof(TProperty) }); - var il = JVM.Context.CodeEmitterFactory.Create(dm); + var il = dm.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(Property.SetMethod.IsVirtual ? OpCodes.Callvirt : OpCodes.Call, Property.SetMethod); il.Emit(OpCodes.Ret); - il.DoEmit(); return (Action)dm.CreateDelegate(typeof(Action)); #endif @@ -204,13 +202,12 @@ Func MakeGetter() throw new InternalException($"Property {Property.Name} cannot be read."); var dm = DynamicMethodUtil.Create($"____{Property.DeclaringType.Name.Replace(".", "_")}__{Property.Name}", Type, false, typeof(TProperty), new[] { typeof(TObject) }); - var il = JVM.Context.CodeEmitterFactory.Create(dm); + var il = dm.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Castclass, Type); il.Emit(Property.GetMethod.IsVirtual ? OpCodes.Callvirt : OpCodes.Call, Property.GetMethod); il.Emit(OpCodes.Ret); - il.DoEmit(); return (Func)dm.CreateDelegate(typeof(Func)); #endif @@ -229,14 +226,13 @@ Action MakeSetter() throw new InternalException($"Property {Property.Name} cannot be written."); var dm = DynamicMethodUtil.Create($"____{Property.DeclaringType.Name.Replace(".", "_")}__{Property.Name}", Type, false, typeof(void), new[] { typeof(TObject), typeof(TProperty) }); - var il = JVM.Context.CodeEmitterFactory.Create(dm); + var il = dm.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Castclass, Type); il.Emit(OpCodes.Ldarg_1); il.Emit(Property.SetMethod.IsVirtual ? OpCodes.Callvirt : OpCodes.Call, Property.SetMethod); il.Emit(OpCodes.Ret); - il.DoEmit(); return (Action)dm.CreateDelegate(typeof(Action)); #endif diff --git a/src/IKVM.Runtime/AttributeHelper.cs b/src/IKVM.Runtime/AttributeHelper.cs index 09ab28241..ebdec4ceb 100644 --- a/src/IKVM.Runtime/AttributeHelper.cs +++ b/src/IKVM.Runtime/AttributeHelper.cs @@ -23,6 +23,7 @@ Jeroen Frijters */ using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.ComponentModel; using System.Diagnostics; using System.Reflection; @@ -876,7 +877,7 @@ internal NameSigAttribute GetNameSig(IMemberSymbol member) internal T[] DecodeArray(IKVM.CoreLib.Symbols.CustomAttributeTypedArgument arg) { - var elems = (IKVM.CoreLib.Symbols.CustomAttributeTypedArgument[])arg.Value; + var elems = (ImmutableArray)arg.Value; var arr = new T[elems.Length]; for (int i = 0; i < arr.Length; i++) arr[i] = (T)elems[i].Value; diff --git a/src/IKVM.Runtime/ExceptionHelper.cs b/src/IKVM.Runtime/ExceptionHelper.cs index 0cbf5dc62..01ce0199e 100644 --- a/src/IKVM.Runtime/ExceptionHelper.cs +++ b/src/IKVM.Runtime/ExceptionHelper.cs @@ -256,7 +256,7 @@ internal static void Append(ExceptionHelper exceptionHelper, List /// /// - static global::java.util.jar.Manifest GetManifestForAssemblyJar(Assembly assembly, string resourceName) + static global::java.util.jar.Manifest GetManifestForAssemblyJar(IAssemblySymbol assembly, string resourceName) { if (assembly is null) throw new ArgumentNullException(nameof(assembly)); @@ -262,7 +262,7 @@ public static string toString(global::java.lang.ClassLoader _this) #else // note that we don't do a security check here, because if you have the Assembly object, // you can already get at all the types in it. - return JVM.Context.AssemblyClassLoaderFactory.FromAssembly(asm).GetJavaClassLoader(); + return JVM.Context.AssemblyClassLoaderFactory.FromAssembly(JVM.Context.Resolver.GetSymbol(asm)).GetJavaClassLoader(); #endif } diff --git a/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Launcher.cs b/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Launcher.cs index 1b1271ea5..20c6267e5 100644 --- a/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Launcher.cs +++ b/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Launcher.cs @@ -32,7 +32,7 @@ public static int run(Type main, string[] args, string jvmArgPrefix, global::jav // statically compiled entry points need to be explicitly added to the classpath // this is sort of a hack and should be removed with a better class loader hierarchy if (main != null && main.Assembly.IsDynamic == false) - JVM.Context.ClassLoaderFactory.GetBootstrapClassLoader().AddDelegate(JVM.Context.AssemblyClassLoaderFactory.FromAssembly(main.Assembly)); + JVM.Context.ClassLoaderFactory.GetBootstrapClassLoader().AddDelegate(JVM.Context.AssemblyClassLoaderFactory.FromAssembly(JVM.Context.Resolver.GetSymbol(main.Assembly))); // copy properties to a CLR type var p = new Dictionary(); diff --git a/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Startup.cs b/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Startup.cs index f8a297f71..2a710d59e 100644 --- a/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Startup.cs +++ b/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Startup.cs @@ -17,7 +17,7 @@ public static void addBootClassPathAssembly(Assembly asm) #if FIRST_PASS throw new NotImplementedException(); #else - JVM.Context.ClassLoaderFactory.GetBootstrapClassLoader().AddDelegate(JVM.Context.AssemblyClassLoaderFactory.FromAssembly(asm)); + JVM.Context.ClassLoaderFactory.GetBootstrapClassLoader().AddDelegate(JVM.Context.AssemblyClassLoaderFactory.FromAssembly(JVM.Context.Resolver.GetSymbol(asm))); #endif } diff --git a/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Util.cs b/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Util.cs index 6dc9ffc64..f765da0e7 100644 --- a/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Util.cs +++ b/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Util.cs @@ -77,7 +77,7 @@ internal static RuntimeJavaType GetTypeWrapperFromObject(RuntimeContext context, if (t.IsPrimitive || JVM.Context.ClassLoaderFactory.IsRemappedType(ts) || t == typeof(void)) return JVM.Context.ManagedJavaTypeFactory.GetJavaTypeFromManagedType(ts).ClassObject; - if (!IsVisibleAsClass(ts)) + if (!IsVisibleAsClass(t)) return null; var tw = JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(ts); @@ -140,7 +140,7 @@ internal static RuntimeJavaType GetTypeWrapperFromObject(RuntimeContext context, #endif } - private static bool IsVisibleAsClass(ITypeSymbol type) + private static bool IsVisibleAsClass(Type type) { while (type.HasElementType) { diff --git a/src/IKVM.Runtime/Java/Externs/java/lang/SecurityManager.cs b/src/IKVM.Runtime/Java/Externs/java/lang/SecurityManager.cs index 36c28392f..0a2a4180c 100644 --- a/src/IKVM.Runtime/Java/Externs/java/lang/SecurityManager.cs +++ b/src/IKVM.Runtime/Java/Externs/java/lang/SecurityManager.cs @@ -53,7 +53,7 @@ static class SecurityManager if (type == typeof(global::java.lang.SecurityManager)) continue; - stack.Add(JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(type).ClassObject); + stack.Add(JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(JVM.Context.Resolver.GetSymbol(type)).ClassObject); } return stack.ToArray(); diff --git a/src/IKVM.Runtime/Java/Externs/java/lang/invoke/MethodHandleNatives.cs b/src/IKVM.Runtime/Java/Externs/java/lang/invoke/MethodHandleNatives.cs index 18a662b40..db53ee23a 100644 --- a/src/IKVM.Runtime/Java/Externs/java/lang/invoke/MethodHandleNatives.cs +++ b/src/IKVM.Runtime/Java/Externs/java/lang/invoke/MethodHandleNatives.cs @@ -366,18 +366,19 @@ static Delegate CreateMemberNameDelegate(RuntimeJavaMethod mw, global::java.lang mw = thisType.Context.JavaBase.TypeOfjavaLangThrowable.GetMethodWrapper(mw.Name, mw.Signature, true); } } - RuntimeJavaType tw = mw.DeclaringType; + + var tw = mw.DeclaringType; tw.Finish(); mw.Link(); mw.ResolveMethod(); - MethodInfo mi = mw.GetMethod() as MethodInfo; + var mi = mw.GetMethod() as MethodInfo; if (mi != null && !mw.HasCallerID && mw.IsStatic && tw.Context.MethodHandleUtil.HasOnlyBasicTypes(mw.GetParameters(), mw.ReturnType) && type.parameterCount() <= MethodHandleUtil.MaxArity) { - return Delegate.CreateDelegate(tw.Context.MethodHandleUtil.CreateMemberWrapperDelegateType(mw.GetParameters(), mw.ReturnType), mi); + return Delegate.CreateDelegate(tw.Context.MethodHandleUtil.CreateMemberWrapperDelegateType(mw.GetParameters(), mw.ReturnType).AsReflection(), mi); } else { @@ -465,7 +466,7 @@ public static object staticFieldBase(global::java.lang.invoke.MemberName self) internal static void InitializeCallSite(global::java.lang.invoke.CallSite site) { - var type = typeof(IKVM.Runtime.IndyCallSite<>).MakeGenericType(JVM.Context.MethodHandleUtil.GetDelegateTypeForInvokeExact(site.type())); + var type = typeof(IKVM.Runtime.IndyCallSite<>).MakeGenericType(JVM.Context.MethodHandleUtil.GetDelegateTypeForInvokeExact(site.type()).AsReflection()); var ics = (IKVM.Runtime.IIndyCallSite)Activator.CreateInstance(type, true); Interlocked.CompareExchange(ref site.ics, ics, null); } diff --git a/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Array.cs b/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Array.cs index 4f4f70548..90d288d49 100644 --- a/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Array.cs +++ b/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Array.cs @@ -23,6 +23,7 @@ Jeroen Frijters */ using System; +using IKVM.CoreLib.Reflection; using IKVM.Runtime; namespace IKVM.Java.Externs.java.lang.reflect @@ -353,52 +354,60 @@ public static void set(object arrayObj, int index, object value) { throw new global::java.lang.NullPointerException(); } - Type type = arrayObj.GetType(); - if (ReflectUtil.IsVector(type) && JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(type.GetElementType()).IsPrimitive) + + var type = arrayObj.GetType(); + if (type.IsSZArray() && JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(JVM.Context.Resolver.GetSymbol(type).GetElementType()).IsPrimitive) { - global::java.lang.Boolean booleanValue = value as global::java.lang.Boolean; + var booleanValue = value as global::java.lang.Boolean; if (booleanValue != null) { setBoolean(arrayObj, index, booleanValue.booleanValue()); return; } - global::java.lang.Byte byteValue = value as global::java.lang.Byte; + + var byteValue = value as global::java.lang.Byte; if (byteValue != null) { setByte(arrayObj, index, byteValue.byteValue()); return; } - global::java.lang.Character charValue = value as global::java.lang.Character; + + var charValue = value as global::java.lang.Character; if (charValue != null) { setChar(arrayObj, index, charValue.charValue()); return; } - global::java.lang.Short shortValue = value as global::java.lang.Short; + + var shortValue = value as global::java.lang.Short; if (shortValue != null) { setShort(arrayObj, index, shortValue.shortValue()); return; } - global::java.lang.Integer intValue = value as global::java.lang.Integer; + + var intValue = value as global::java.lang.Integer; if (intValue != null) { setInt(arrayObj, index, intValue.intValue()); return; } - global::java.lang.Float floatValue = value as global::java.lang.Float; + + var floatValue = value as global::java.lang.Float; if (floatValue != null) { setFloat(arrayObj, index, floatValue.floatValue()); return; } - global::java.lang.Long longValue = value as global::java.lang.Long; + + var longValue = value as global::java.lang.Long; if (longValue != null) { setLong(arrayObj, index, longValue.longValue()); return; } - global::java.lang.Double doubleValue = value as global::java.lang.Double; + + var doubleValue = value as global::java.lang.Double; if (doubleValue != null) { setDouble(arrayObj, index, doubleValue.doubleValue()); @@ -422,16 +431,14 @@ public static void set(object arrayObj, int index, object value) public static void setBoolean(object arrayObj, int index, bool value) { if (arrayObj == null) - { throw new global::java.lang.NullPointerException(); - } - bool[] arr = arrayObj as bool[]; + + var arr = arrayObj as bool[]; if (arr != null) { if (index < 0 || index >= arr.Length) - { throw new global::java.lang.ArrayIndexOutOfBoundsException(); - } + arr[index] = value; } else @@ -443,16 +450,14 @@ public static void setBoolean(object arrayObj, int index, bool value) public static void setByte(object arrayObj, int index, byte value) { if (arrayObj == null) - { throw new global::java.lang.NullPointerException(); - } - byte[] arr = arrayObj as byte[]; + + var arr = arrayObj as byte[]; if (arr != null) { if (index < 0 || index >= arr.Length) - { throw new global::java.lang.ArrayIndexOutOfBoundsException(); - } + arr[index] = value; } else @@ -464,16 +469,14 @@ public static void setByte(object arrayObj, int index, byte value) public static void setChar(object arrayObj, int index, char value) { if (arrayObj == null) - { throw new global::java.lang.NullPointerException(); - } - char[] arr = arrayObj as char[]; + + var arr = arrayObj as char[]; if (arr != null) { if (index < 0 || index >= arr.Length) - { throw new global::java.lang.ArrayIndexOutOfBoundsException(); - } + arr[index] = value; } else @@ -603,9 +606,9 @@ public static object newArray(global::java.lang.Class componentType, int length) } try { - RuntimeJavaType wrapper = RuntimeJavaType.FromClass(componentType); + var wrapper = RuntimeJavaType.FromClass(componentType); wrapper.Finish(); - object obj = global::System.Array.CreateInstance(wrapper.TypeAsArrayType, length); + object obj = global::System.Array.CreateInstance(wrapper.TypeAsArrayType.AsReflection(), length); if (wrapper.IsGhost || wrapper.IsGhostArray) { IKVM.Runtime.GhostTag.SetTag(obj, wrapper.MakeArrayType(1)); @@ -640,13 +643,13 @@ public static object multiNewArray(global::java.lang.Class componentType, int[] } try { - RuntimeJavaType wrapper = RuntimeJavaType.FromClass(componentType).MakeArrayType(dimensions.Length); + var wrapper = RuntimeJavaType.FromClass(componentType).MakeArrayType(dimensions.Length); wrapper.Finish(); - object obj = IKVM.Runtime.ByteCodeHelper.multianewarray(wrapper.TypeAsArrayType.TypeHandle, dimensions); + + var obj = IKVM.Runtime.ByteCodeHelper.multianewarray(wrapper.TypeAsArrayType.AsReflection().TypeHandle, dimensions); if (wrapper.IsGhostArray) - { IKVM.Runtime.GhostTag.SetTag(obj, wrapper); - } + return obj; } catch (RetargetableJavaException x) diff --git a/src/IKVM.Runtime/Java/Externs/java/security/AccessController.cs b/src/IKVM.Runtime/Java/Externs/java/security/AccessController.cs index 99d89c98f..3001f8784 100644 --- a/src/IKVM.Runtime/Java/Externs/java/security/AccessController.cs +++ b/src/IKVM.Runtime/Java/Externs/java/security/AccessController.cs @@ -117,7 +117,7 @@ static object CreateAccessControlContext(List)arrayRefCache.GetValue(JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(array.GetType().GetElementType()), _ => new ArrayDelegateRef(_)).VolatileGetter)(array, offset); + return ((Func)arrayRefCache.GetValue(JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(JVM.Context.Resolver.GetSymbol(array.GetType()).GetElementType()), _ => new ArrayDelegateRef(_)).VolatileGetter)(array, offset); } catch (Exception e) { @@ -1957,7 +1957,7 @@ static void PutArrayObjectVolatile(object[] array, long offset, object value) #else try { - ((Action)arrayRefCache.GetValue(JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(array.GetType().GetElementType()), _ => new ArrayDelegateRef(_)).VolatilePutter)(array, offset, value); + ((Action)arrayRefCache.GetValue(JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(JVM.Context.Resolver.GetSymbol(array.GetType()).GetElementType()), _ => new ArrayDelegateRef(_)).VolatilePutter)(array, offset, value); } catch (Exception e) { @@ -2499,7 +2499,7 @@ static object CompareAndSwapArray(T[] o, long offset, T value, T comparand) #if FIRST_PASS throw new NotImplementedException(); #else - return Interlocked.CompareExchange(ref o[offset / ArrayIndexScale(JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(o.GetType()))], value, comparand); + return Interlocked.CompareExchange(ref o[offset / ArrayIndexScale(JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(JVM.Context.Resolver.GetSymbol(o.GetType())))], value, comparand); #endif } @@ -2520,7 +2520,7 @@ static object CompareAndSwapObjectArray(object[] o, long offset, object value, o #else try { - return ((Func)arrayRefCache.GetValue(JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(o.GetType().GetElementType()), _ => new ArrayDelegateRef(_)).CompareExchange)(o, offset, value, expected); + return ((Func)arrayRefCache.GetValue(JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(JVM.Context.Resolver.GetSymbol(o.GetType()).GetElementType()), _ => new ArrayDelegateRef(_)).CompareExchange)(o, offset, value, expected); } catch (Exception e) { diff --git a/src/IKVM.Runtime/Java/Externs/sun/misc/VM.cs b/src/IKVM.Runtime/Java/Externs/sun/misc/VM.cs index ad2eaaef5..02e611e84 100644 --- a/src/IKVM.Runtime/Java/Externs/sun/misc/VM.cs +++ b/src/IKVM.Runtime/Java/Externs/sun/misc/VM.cs @@ -59,12 +59,12 @@ public static void initialize() if (global::IKVM.Java.Externs.sun.reflect.Reflection.IsHideFromStackWalk(m)) continue; - if (m.DeclaringType != null && JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(m.DeclaringType) is RuntimeJavaType tw and not null) + if (m.DeclaringType != null && JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(JVM.Context.Resolver.GetSymbol(m.DeclaringType)) is { } tw) { - // check that the assembly isn't java.base or the IKVM runtime + // check that the assembly isn't the .NET corelib or the IKVM runtime var clw = tw.ClassLoader; if (clw is RuntimeAssemblyClassLoader acl) - if (acl.GetAssembly(tw) == typeof(object).Assembly || acl.GetAssembly(tw) == typeof(VM).Assembly) + if (acl.GetAssembly(tw) == JVM.Context.Types.Object.Assembly || acl.GetAssembly(tw).AsReflection() == typeof(VM).Assembly) continue; // associated Java class loader is our nearest diff --git a/src/IKVM.Runtime/Java/Externs/sun/net/www/protocol/ikvmres/Handler.cs b/src/IKVM.Runtime/Java/Externs/sun/net/www/protocol/ikvmres/Handler.cs index 8a726ac70..673d6fb33 100644 --- a/src/IKVM.Runtime/Java/Externs/sun/net/www/protocol/ikvmres/Handler.cs +++ b/src/IKVM.Runtime/Java/Externs/sun/net/www/protocol/ikvmres/Handler.cs @@ -87,7 +87,7 @@ public static object LoadClassFromAssembly(Assembly asm, string className) #if FIRST_PASS throw new NotImplementedException(); #else - var tw = JVM.Context.AssemblyClassLoaderFactory.FromAssembly(asm).TryLoadClassByName(className); + var tw = JVM.Context.AssemblyClassLoaderFactory.FromAssembly(JVM.Context.Resolver.GetSymbol(asm)).TryLoadClassByName(className); if (tw != null) return tw.ClassObject; diff --git a/src/IKVM.Runtime/Java/Externs/sun/reflect/Reflection.cs b/src/IKVM.Runtime/Java/Externs/sun/reflect/Reflection.cs index ad244fe42..c555bc66a 100644 --- a/src/IKVM.Runtime/Java/Externs/sun/reflect/Reflection.cs +++ b/src/IKVM.Runtime/Java/Externs/sun/reflect/Reflection.cs @@ -61,7 +61,7 @@ static HideFromJavaFlags GetHideFromJavaFlagsImpl(MethodBase mb) #if FIRST_PASS throw new NotImplementedException(); #else - return mb.Name.StartsWith("__<", StringComparison.Ordinal) ? HideFromJavaFlags.All : JVM.Context.AttributeHelper.GetHideFromJavaFlags(mb); + return mb.Name.StartsWith("__<", StringComparison.Ordinal) ? HideFromJavaFlags.All : JVM.Context.AttributeHelper.GetHideFromJavaFlags(JVM.Context.Resolver.GetSymbol(mb)); #endif } @@ -118,7 +118,7 @@ internal static bool IsHideFromStackWalk(MethodBase mb) continue; if (--realFramesToSkip == 0) - return JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(method.DeclaringType).ClassObject; + return JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(JVM.Context.Resolver.GetSymbol(method.DeclaringType)).ClassObject; } #endif } diff --git a/src/IKVM.Runtime/Launcher.cs b/src/IKVM.Runtime/Launcher.cs index 18bfbc828..12618d949 100644 --- a/src/IKVM.Runtime/Launcher.cs +++ b/src/IKVM.Runtime/Launcher.cs @@ -240,7 +240,7 @@ static void AddBootClassPathAssembly(Assembly assembly) #if FIRST_PASS || IMPORTER throw new NotImplementedException(); #else - JVM.Context.ClassLoaderFactory.GetBootstrapClassLoader().AddDelegate(JVM.Context.AssemblyClassLoaderFactory.FromAssembly(assembly)); + JVM.Context.ClassLoaderFactory.GetBootstrapClassLoader().AddDelegate(JVM.Context.AssemblyClassLoaderFactory.FromAssembly(JVM.Context.Resolver.GetSymbol(assembly))); #endif } @@ -518,7 +518,7 @@ public static int Run(Assembly assembly, string main, bool jar, string[] args, s SystemAccessor.InvokeSetProperty("sun.java.command", initialize["sun.java.command"]); // find the main method and ensure it is accessible - var method = ClassAccessor.InvokeGetMethod(clazz, "main", ClassAccessor.InitArray(JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(typeof(string[])).ClassObject), CallerIDAccessor.InvokeCreate(typeof(Launcher).TypeHandle)); + var method = ClassAccessor.InvokeGetMethod(clazz, "main", ClassAccessor.InitArray(JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(JVM.Context.Types.String.MakeArrayType()).ClassObject), CallerIDAccessor.InvokeCreate(typeof(Launcher).TypeHandle)); MethodAccessor.InvokeSetAccessible(method, true); try diff --git a/src/IKVM.Runtime/MethodHandleUtil.jniexport.cs b/src/IKVM.Runtime/MethodHandleUtil.jniexport.cs index d3fd060a5..9a6044702 100644 --- a/src/IKVM.Runtime/MethodHandleUtil.jniexport.cs +++ b/src/IKVM.Runtime/MethodHandleUtil.jniexport.cs @@ -22,6 +22,7 @@ Jeroen Frijters */ #if IMPORTER == false + using System; using System.Diagnostics; using System.Reflection; @@ -47,7 +48,7 @@ internal ITypeSymbol GetMemberWrapperDelegateType(global::java.lang.invoke.Metho #if FIRST_PASS == false - ITypeSymbol CreateMethodHandleDelegateType(java.lang.invoke.MethodType type) + Type CreateMethodHandleDelegateType(java.lang.invoke.MethodType type) { var args = new RuntimeJavaType[type.parameterCount()]; for (int i = 0; i < args.Length; i++) @@ -57,7 +58,8 @@ ITypeSymbol CreateMethodHandleDelegateType(java.lang.invoke.MethodType type) } var ret = RuntimeJavaType.FromClass(type.returnType()); ret.Finish(); - return CreateMethodHandleDelegateType(args, ret); + + return CreateMethodHandleDelegateType(args, ret).AsReflection(); } static ITypeSymbol[] GetParameterTypes(IMethodBaseSymbol mb) @@ -81,10 +83,10 @@ internal static ITypeSymbol[] GetParameterTypes(ITypeSymbol thisType, IMethodBas return args; } - internal java.lang.invoke.MethodType GetDelegateMethodType(ITypeSymbol type) + internal java.lang.invoke.MethodType GetDelegateMethodType(Type type) { java.lang.Class[] types; - var mi = GetDelegateInvokeMethod(type); + var mi = GetDelegateInvokeMethod(context.Resolver.GetSymbol(type)); var pi = mi.GetParameters(); if (pi.Length > 0 && IsPackedArgsContainer(pi[pi.Length - 1].ParameterType)) { @@ -161,7 +163,7 @@ public Container(T1 target, T2 value) /// /// /// - DynamicMethodBuilder(RuntimeContext context, string name, java.lang.invoke.MethodType type, ITypeSymbol container, object target, object value, ITypeSymbol owner, bool useBasicTypes) + DynamicMethodBuilder(RuntimeContext context, string name, java.lang.invoke.MethodType type, ITypeSymbol container, object target, object value, Type owner, bool useBasicTypes) { this.context = context ?? throw new ArgumentNullException(nameof(context)); this.type = type; @@ -189,10 +191,10 @@ public Container(T1 target, T2 value) paramTypes = GetParameterTypes(mi); } - if (!ReflectUtil.CanOwnDynamicMethod(owner.AsReflection())) - owner = context.Resolver.GetSymbol(typeof(DynamicMethodBuilder)); + if (!ReflectUtil.CanOwnDynamicMethod(owner)) + owner = typeof(DynamicMethodBuilder); - dm = new DynamicMethod(name, mi.ReturnType.AsReflection(), paramTypes.AsReflection(), owner.AsReflection(), true); + dm = new DynamicMethod(name, mi.ReturnType.AsReflection(), paramTypes.AsReflection(), owner, true); ilgen = context.CodeEmitterFactory.Create(dm); if (type.parameterCount() > MaxArity) @@ -346,7 +348,7 @@ internal static Delegate CreateMemberName(RuntimeContext context, RuntimeJavaMet FinishTypes(type); var tw = mw.DeclaringType; - var owner = tw.TypeAsBaseType; + var owner = tw.TypeAsBaseType.AsReflection(); var dm = new DynamicMethodBuilder(context, "MemberName:" + mw.DeclaringType.Name + "::" + mw.Name + mw.Signature, type, null, mw.HasCallerID ? DynamicCallerIDProvider.Instance : null, null, owner, true); for (int i = 0, count = type.parameterCount(); i < count; i++) { @@ -631,7 +633,7 @@ static Delegate ValidateDelegate(Delegate d) internal ITypeSymbol GetDelegateTypeForInvokeExact(global::java.lang.invoke.MethodType type) { - type._invokeExactDelegateType ??= CreateMethodHandleDelegateType(type).AsReflection(); + type._invokeExactDelegateType ??= CreateMethodHandleDelegateType(type); return context.Resolver.GetSymbol(type._invokeExactDelegateType); } @@ -648,7 +650,7 @@ internal T GetDelegateForInvokeExact(global::java.lang.invoke.MethodHandle mh return del; } - throw java.lang.invoke.Invokers.newWrongMethodTypeException(GetDelegateMethodType(context.Resolver.GetSymbol(typeof(T))), type); + throw java.lang.invoke.Invokers.newWrongMethodTypeException(GetDelegateMethodType(typeof(T)), type); } /// diff --git a/src/IKVM.Runtime/MethodHandleUtil.root.cs b/src/IKVM.Runtime/MethodHandleUtil.root.cs index 414420e07..5cd878bb5 100644 --- a/src/IKVM.Runtime/MethodHandleUtil.root.cs +++ b/src/IKVM.Runtime/MethodHandleUtil.root.cs @@ -47,7 +47,7 @@ public MethodHandleUtil(RuntimeContext context) this.context = context ?? throw new ArgumentNullException(nameof(context)); typeofMHA = context.Resolver.ResolveRuntimeType("IKVM.Runtime.MHA`8"); - typeofMHV = new[] { + typeofMHV = [ context.Resolver.ResolveRuntimeType("IKVM.Runtime.MHV"), context.Resolver.ResolveRuntimeType("IKVM.Runtime.MHV`1"), context.Resolver.ResolveRuntimeType("IKVM.Runtime.MHV`2"), @@ -57,8 +57,8 @@ public MethodHandleUtil(RuntimeContext context) context.Resolver.ResolveRuntimeType("IKVM.Runtime.MHV`6"), context.Resolver.ResolveRuntimeType("IKVM.Runtime.MHV`7"), context.Resolver.ResolveRuntimeType("IKVM.Runtime.MHV`8"), - }; - typeofMH = new[] { + ]; + typeofMH = [ null, context.Resolver.ResolveRuntimeType("IKVM.Runtime.MH`1"), context.Resolver.ResolveRuntimeType("IKVM.Runtime.MH`2"), @@ -69,7 +69,7 @@ public MethodHandleUtil(RuntimeContext context) context.Resolver.ResolveRuntimeType("IKVM.Runtime.MH`7"), context.Resolver.ResolveRuntimeType("IKVM.Runtime.MH`8"), context.Resolver.ResolveRuntimeType("IKVM.Runtime.MH`9"), - }; + ]; } internal bool IsPackedArgsContainer(ITypeSymbol type) diff --git a/src/IKVM.Runtime/ReflectUtil.cs b/src/IKVM.Runtime/ReflectUtil.cs index 96cce87e5..beca070d4 100644 --- a/src/IKVM.Runtime/ReflectUtil.cs +++ b/src/IKVM.Runtime/ReflectUtil.cs @@ -27,6 +27,8 @@ Jeroen Frijters using IKVM.CoreLib.Symbols.Emit; using System.Collections.Immutable; +using IKVM.CoreLib.Reflection; + #if IMPORTER || EXPORTER diff --git a/src/IKVM.Runtime/RuntimeAssemblyClassLoaderFactory.cs b/src/IKVM.Runtime/RuntimeAssemblyClassLoaderFactory.cs index c0b9bf728..d64bfe159 100644 --- a/src/IKVM.Runtime/RuntimeAssemblyClassLoaderFactory.cs +++ b/src/IKVM.Runtime/RuntimeAssemblyClassLoaderFactory.cs @@ -112,7 +112,8 @@ RuntimeAssemblyClassLoader Create(IAssemblySymbol assembly) context.ClassLoaderFactory.LoadRemappedTypes(); #endif - if (assembly.IsDefined(context.Resolver.ResolveRuntimeType("IKVM.Attributes.RemappedClassAttribute"), false)) + var baseAssembly = context.Resolver.GetBaseAssembly(); + if (baseAssembly == assembly) { // This cast is necessary for ikvmc and a no-op for the runtime. // Note that the cast cannot fail, because ikvmc will only return a non AssemblyClassLoader diff --git a/src/IKVM.Runtime/RuntimeClassLoader.cs b/src/IKVM.Runtime/RuntimeClassLoader.cs index e2d095ec1..faa45eb10 100644 --- a/src/IKVM.Runtime/RuntimeClassLoader.cs +++ b/src/IKVM.Runtime/RuntimeClassLoader.cs @@ -910,7 +910,7 @@ public override string ToString() if (javaClassLoader == null) return "null"; else - return string.Format("{0}@{1:X}", Context.ClassLoaderFactory.GetJavaTypeFromType(javaClassLoader.GetType()).Name, javaClassLoader.GetHashCode()); + return string.Format("{0}@{1:X}", Context.ClassLoaderFactory.GetJavaTypeFromType(Context.Resolver.GetSymbol(javaClassLoader.GetType())).Name, javaClassLoader.GetHashCode()); } #endif diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.MultipleAnnotationJavaType.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.MultipleAnnotationJavaType.cs index c288ba1d3..cc600578c 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.MultipleAnnotationJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.MultipleAnnotationJavaType.cs @@ -55,7 +55,7 @@ internal MultipleAnnotationJavaType(RuntimeContext context, AttributeAnnotationJ #if IMPORTER || EXPORTER this.annotationType = context.FakeTypes.GetAttributeMultipleType(declaringType.attributeType); #elif !FIRST_PASS - this.annotationType = typeof(ikvm.@internal.AttributeAnnotationMultiple<>).MakeGenericType(declaringType.attributeType); + this.annotationType = context.Resolver.GetSymbol(typeof(ikvm.@internal.AttributeAnnotationMultiple<>)).MakeGenericType(declaringType.attributeType); #endif this.declaringType = declaringType; } diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.EnumWrapJavaMethod.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.EnumWrapJavaMethod.cs index a35042952..b412e502e 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.EnumWrapJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.EnumWrapJavaMethod.cs @@ -67,7 +67,7 @@ internal override void EmitCall(CodeEmitter ilgen) internal override object Invoke(object obj, object[] args) { - return Enum.ToObject(DeclaringType.TypeAsTBD, args[0]); + return Enum.ToObject(DeclaringType.TypeAsTBD.AsReflection(), args[0]); } #endif diff --git a/src/IKVM.Runtime/Vfs/VfsAssemblyClassDirectory.cs b/src/IKVM.Runtime/Vfs/VfsAssemblyClassDirectory.cs index 5e8cb20fc..60599a5ca 100644 --- a/src/IKVM.Runtime/Vfs/VfsAssemblyClassDirectory.cs +++ b/src/IKVM.Runtime/Vfs/VfsAssemblyClassDirectory.cs @@ -67,7 +67,7 @@ RuntimeJavaType TryLoadType(JavaTypeName className) #if FIRST_PASS || IMPORTER || EXPORTER throw new NotImplementedException(); #else - var acl = Context.Context.AssemblyClassLoaderFactory.FromAssembly(assembly); + var acl = Context.Context.AssemblyClassLoaderFactory.FromAssembly(Context.Context.Resolver.GetSymbol(assembly)); try { @@ -124,7 +124,7 @@ VfsEntry GetPackageEntry(JavaPackageName packageName) #if FIRST_PASS || IMPORTER || EXPORTER throw new PlatformNotSupportedException(); #else - var acl = Context.Context.AssemblyClassLoaderFactory.FromAssembly(assembly); + var acl = Context.Context.AssemblyClassLoaderFactory.FromAssembly(Context.Context.Resolver.GetSymbol(assembly)); if (acl == null) throw new InvalidOperationException("Could not locate assembly loader."); @@ -132,7 +132,7 @@ VfsEntry GetPackageEntry(JavaPackageName packageName) foreach (var type in GetAssemblyTypes()) { // attempt to find Java type name - var name = acl.GetTypeNameAndType(type, out var isJavaType); + var name = acl.GetTypeNameAndType(Context.Context.Resolver.GetSymbol(type), out var isJavaType); if (name is null) continue; @@ -162,14 +162,14 @@ public override string[] List() #else var lst = new HashSet(); - var acl = Context.Context.AssemblyClassLoaderFactory.FromAssembly(assembly); + var acl = Context.Context.AssemblyClassLoaderFactory.FromAssembly(Context.Context.Resolver.GetSymbol(assembly)); if (acl == null) throw new InvalidOperationException("Could not locate assembly loader."); // search for any type that would be within the package foreach (var type in GetAssemblyTypes()) { - var name = acl.GetTypeNameAndType(type, out var isJavaType); + var name = acl.GetTypeNameAndType(Context.Context.Resolver.GetSymbol(type), out var isJavaType); if (name is null) continue; diff --git a/src/ikvmc/ikvmc.csproj b/src/ikvmc/ikvmc.csproj index ae6f133e1..042fb47ce 100644 --- a/src/ikvmc/ikvmc.csproj +++ b/src/ikvmc/ikvmc.csproj @@ -1,7 +1,7 @@  Exe - net8.0;net472;;net6.0; + net472;net6.0;net8.0 $(_SupportedToolRuntimes) true true diff --git a/src/ikvmstub/Properties/launchSettings.json b/src/ikvmstub/Properties/launchSettings.json index 64fa8dc5e..c0011c600 100644 --- a/src/ikvmstub/Properties/launchSettings.json +++ b/src/ikvmstub/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "ikvmstub": { "commandName": "Project", - "commandLineArgs": "--bootstrap --nostdlib --skiperror --parameters --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\Microsoft.Win32.Primitives.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Collections.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Net.Primitives.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Runtime.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Runtime.InteropServices.dll\" --reference:\"D:\\ikvm\\src\\IKVM.Java\\bin\\Debug\\net8.0\\IKVM.Java.dll\" --reference:\"D:\\ikvm\\src\\IKVM.Runtime-ref\\obj\\Debug\\net8.0\\ref\\IKVM.Runtime.dll\" --out:\"C:\\Users\\jhaltom\\System.Net.Primitives.jar\" \"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Net.Primitives.dll\"" + "commandLineArgs": "--bootstrap --nostdlib --skiperror --non-public-types --parameters --reference:\"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\mscorlib.dll\" --reference:\"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\System.Configuration.dll\" --reference:\"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\System.Core.dll\" --reference:\"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\System.dll\" --reference:\"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\System.Numerics.dll\" --reference:\"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\System.Security.dll\" --reference:\"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\System.Xml.dll\" --reference:\"C:\\Program Files\\dotnet\\sdk\\NuGetFallbackFolder\\system.numerics.vectors\\4.5.0\\ref\\net46\\System.Numerics.Vectors.dll\" --reference:\"C:\\Program Files\\dotnet\\sdk\\NuGetFallbackFolder\\system.valuetuple\\4.5.0\\ref\\net47\\System.ValueTuple.dll\" --reference:\"D:\\ikvm\\src\\IKVM.CoreLib\\bin\\Debug\\net472\\IKVM.CoreLib.dll\" --reference:\"D:\\ikvm\\src\\IKVM.Java\\bin\\Debug\\net472\\IKVM.Java.dll\" --reference:\"D:\\ikvm\\src\\IKVM.Reflection\\obj\\Debug\\net472\\ref\\IKVM.Reflection.dll\" --reference:\"D:\\ikvm\\src\\IKVM.Runtime-ref\\obj\\Debug\\net472\\ref\\IKVM.Runtime.dll\" --reference:\"D:\\packages\\NuGet\\cache\\ikvm.bytecode\\9.1.3\\lib\\net472\\IKVM.ByteCode.dll\" --reference:\"D:\\packages\\NuGet\\cache\\microsoft.bcl.asyncinterfaces\\8.0.0\\lib\\net462\\Microsoft.Bcl.AsyncInterfaces.dll\" --reference:\"D:\\packages\\NuGet\\cache\\system.buffers\\4.5.1\\ref\\net45\\System.Buffers.dll\" --reference:\"D:\\packages\\NuGet\\cache\\system.collections.immutable\\8.0.0\\lib\\net462\\System.Collections.Immutable.dll\" --reference:\"D:\\packages\\NuGet\\cache\\system.io.pipelines\\8.0.0\\lib\\net462\\System.IO.Pipelines.dll\" --reference:\"D:\\packages\\NuGet\\cache\\system.memory\\4.5.5\\lib\\net461\\System.Memory.dll\" --reference:\"D:\\packages\\NuGet\\cache\\system.reflection.metadata\\8.0.0\\lib\\net462\\System.Reflection.Metadata.dll\" --reference:\"D:\\packages\\NuGet\\cache\\system.reflection.typeextensions\\4.7.0\\ref\\net472\\System.Reflection.TypeExtensions.dll\" --reference:\"D:\\packages\\NuGet\\cache\\system.runtime.compilerservices.unsafe\\6.0.0\\lib\\net461\\System.Runtime.CompilerServices.Unsafe.dll\" --reference:\"D:\\packages\\NuGet\\cache\\system.text.encodings.web\\8.0.0\\lib\\net462\\System.Text.Encodings.Web.dll\" --reference:\"D:\\packages\\NuGet\\cache\\system.text.json\\8.0.4\\lib\\net462\\System.Text.Json.dll\" --reference:\"D:\\packages\\NuGet\\cache\\system.threading.tasks.extensions\\4.5.4\\lib\\net461\\System.Threading.Tasks.Extensions.dll\" --out:\"IKVM.Runtime.jar\" \"D:\\ikvm\\src\\IKVM.Runtime-ref\\obj\\Debug\\net472\\ref\\IKVM.Runtime.dll\"" } } } \ No newline at end of file diff --git a/src/ikvmstub/ikvmstub.csproj b/src/ikvmstub/ikvmstub.csproj index 15e796a6b..1d89f5a4d 100644 --- a/src/ikvmstub/ikvmstub.csproj +++ b/src/ikvmstub/ikvmstub.csproj @@ -1,7 +1,7 @@  Exe - net8.0;net472;net6.0 + net472;net6.0;net8.0 $(_SupportedToolRuntimes) true true From a9a3232734da8cbe520ea7fe80cb28c68b58e45d Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Fri, 27 Sep 2024 21:10:51 -0500 Subject: [PATCH 17/51] 111 --- src/IKVM.Runtime/IRuntimeSymbolResolver.cs | 8 +- src/IKVM.Runtime/InstructionState.cs | 1 + .../Java/Externs/java/lang/reflect/Array.cs | 6 +- src/IKVM.Runtime/RuntimeJavaType.cs | 9 +- .../RuntimeManagedByteCodeJavaType.cs | 4 +- ...tionJavaType.MultipleAnnotationJavaType.cs | 2 +- src/IKVM.Tools.Exporter/ExportImpl.cs | 4 +- .../ExportRuntimeSymbolResolver.cs | 110 +++++++++--------- src/IKVM.Tools.Importer/ImportClassLoader.cs | 2 +- .../ImportRuntimeSymbolResolver.cs | 36 ++---- 10 files changed, 86 insertions(+), 96 deletions(-) diff --git a/src/IKVM.Runtime/IRuntimeSymbolResolver.cs b/src/IKVM.Runtime/IRuntimeSymbolResolver.cs index 7a5874bc9..3d89c7c9a 100644 --- a/src/IKVM.Runtime/IRuntimeSymbolResolver.cs +++ b/src/IKVM.Runtime/IRuntimeSymbolResolver.cs @@ -34,20 +34,20 @@ interface IRuntimeSymbolResolver : ISymbolResolver /// /// /// - ITypeSymbol? ResolveSystemType(string typeName); + ITypeSymbol ResolveSystemType(string typeName); /// /// Gets the known runtime assembly. /// /// - IAssemblySymbol? GetRuntimeAssembly(); + IAssemblySymbol GetRuntimeAssembly(); /// /// Resolves the named type from the IKVM runtime assembly. /// /// /// - ITypeSymbol? ResolveRuntimeType(string typeName); + ITypeSymbol ResolveRuntimeType(string typeName); /// /// Resolves the known Java base assembly. @@ -60,7 +60,7 @@ interface IRuntimeSymbolResolver : ISymbolResolver /// /// /// - ITypeSymbol? ResolveBaseType(string typeName); + ITypeSymbol ResolveBaseType(string typeName); /// /// Gets the associated with the specified assembly. diff --git a/src/IKVM.Runtime/InstructionState.cs b/src/IKVM.Runtime/InstructionState.cs index 27312c3af..6c0b043e2 100644 --- a/src/IKVM.Runtime/InstructionState.cs +++ b/src/IKVM.Runtime/InstructionState.cs @@ -382,6 +382,7 @@ internal static RuntimeJavaType FindCommonBaseType(RuntimeContext context, Runti { baseType = FindCommonBaseTypeHelper(context, elem1, elem2); } + return baseType.MakeArrayType(rank); } return FindCommonBaseTypeHelper(context, type1, type2); diff --git a/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Array.cs b/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Array.cs index 90d288d49..f19c102fe 100644 --- a/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Array.cs +++ b/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Array.cs @@ -608,11 +608,11 @@ public static object newArray(global::java.lang.Class componentType, int length) { var wrapper = RuntimeJavaType.FromClass(componentType); wrapper.Finish(); - object obj = global::System.Array.CreateInstance(wrapper.TypeAsArrayType.AsReflection(), length); + + var obj = global::System.Array.CreateInstance(wrapper.TypeAsArrayType.AsReflection(), length); if (wrapper.IsGhost || wrapper.IsGhostArray) - { IKVM.Runtime.GhostTag.SetTag(obj, wrapper.MakeArrayType(1)); - } + return obj; } catch (RetargetableJavaException x) diff --git a/src/IKVM.Runtime/RuntimeJavaType.cs b/src/IKVM.Runtime/RuntimeJavaType.cs index c127cf360..4b5e96745 100644 --- a/src/IKVM.Runtime/RuntimeJavaType.cs +++ b/src/IKVM.Runtime/RuntimeJavaType.cs @@ -137,7 +137,7 @@ ITypeSymbol GetClassLiteralType() while (tw.IsArray) tw = tw.ElementTypeWrapper; - return tw.TypeAsTBD.MakeArrayType(rank); + return rank == 1 ? tw.TypeAsTBD.MakeArrayType() : tw.TypeAsTBD.MakeArrayType(rank); } else { @@ -1029,16 +1029,17 @@ internal RuntimeJavaType ElementTypeWrapper internal RuntimeJavaType MakeArrayType(int rank) { Debug.Assert(rank != 0); + // NOTE this call to LoadClassByDottedNameFast can never fail and will not trigger a class load - return ClassLoader.TryLoadClassByName(new String('[', rank) + this.SigName); + return ClassLoader.TryLoadClassByName(new string('[', rank) + SigName); } internal bool ImplementsInterface(RuntimeJavaType interfaceWrapper) { - RuntimeJavaType typeWrapper = this; + var typeWrapper = this; while (typeWrapper != null) { - RuntimeJavaType[] interfaces = typeWrapper.Interfaces; + var interfaces = typeWrapper.Interfaces; for (int i = 0; i < interfaces.Length; i++) { if (interfaces[i] == interfaceWrapper) diff --git a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs index 840ebdc54..b78906140 100644 --- a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs @@ -953,10 +953,10 @@ static RuntimeJavaType TypeWrapperFromModOpt(RuntimeContext context, ITypeSymbol tw = context.ClassLoaderFactory.GetJavaTypeFromType(type); } } + if (rank != 0) - { tw = tw.MakeArrayType(rank); - } + return tw; } diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.MultipleAnnotationJavaType.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.MultipleAnnotationJavaType.cs index cc600578c..4b33a804d 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.MultipleAnnotationJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.MultipleAnnotationJavaType.cs @@ -62,7 +62,7 @@ internal MultipleAnnotationJavaType(RuntimeContext context, AttributeAnnotationJ protected override void LazyPublishMembers() { - RuntimeJavaType tw = declaringType.MakeArrayType(1); + var tw = declaringType.MakeArrayType(1); SetMethods([new DynamicOnlyJavaMethod(this, "value", "()" + tw.SigName, tw, [], MemberFlags.None)]); SetFields([]); } diff --git a/src/IKVM.Tools.Exporter/ExportImpl.cs b/src/IKVM.Tools.Exporter/ExportImpl.cs index 09494ee74..1c506da3a 100644 --- a/src/IKVM.Tools.Exporter/ExportImpl.cs +++ b/src/IKVM.Tools.Exporter/ExportImpl.cs @@ -146,7 +146,7 @@ public int Execute() } compiler = new StaticCompiler(universe, assemblyResolver, runtimeAssembly); - context = new RuntimeContext(new RuntimeContextOptions(true), diagnostics, new ExportRuntimeSymbolResolver(diagnostics, universe, symbols), compiler); + context = new RuntimeContext(new RuntimeContextOptions(true), diagnostics, new ExportRuntimeSymbolResolver(diagnostics, universe, symbols, options.Bootstrap), compiler); context.ClassLoaderFactory.SetBootstrapClassLoader(new RuntimeBootstrapClassLoader(context)); } else @@ -172,7 +172,7 @@ public int Execute() } compiler = new StaticCompiler(universe, assemblyResolver, runtimeAssembly); - context = new RuntimeContext(new RuntimeContextOptions(), diagnostics, new ExportRuntimeSymbolResolver(diagnostics, universe, symbols), compiler); + context = new RuntimeContext(new RuntimeContextOptions(), diagnostics, new ExportRuntimeSymbolResolver(diagnostics, universe, symbols, options.Bootstrap), compiler); } if (context.AttributeHelper.IsJavaModule(context.Resolver.GetSymbol(assembly.ManifestModule))) diff --git a/src/IKVM.Tools.Exporter/ExportRuntimeSymbolResolver.cs b/src/IKVM.Tools.Exporter/ExportRuntimeSymbolResolver.cs index cb41963e3..d99416986 100644 --- a/src/IKVM.Tools.Exporter/ExportRuntimeSymbolResolver.cs +++ b/src/IKVM.Tools.Exporter/ExportRuntimeSymbolResolver.cs @@ -1,27 +1,4 @@ -/* - Copyright (C) 2002-2014 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -#nullable enable +#nullable enable using System; using System.Collections.Concurrent; @@ -63,6 +40,7 @@ static IEnumerable GetSystemTypeNames() readonly IDiagnosticHandler _diagnostics; readonly Universe _universe; readonly IkvmReflectionSymbolContext _symbols; + readonly bool _bootstrap; IAssemblySymbol? _coreAssembly; readonly ConcurrentDictionary _coreTypeCache = new(); @@ -82,12 +60,14 @@ static IEnumerable GetSystemTypeNames() /// /// /// + /// /// - public ExportRuntimeSymbolResolver(IDiagnosticHandler diagnostics, Universe universe, IkvmReflectionSymbolContext symbols) + public ExportRuntimeSymbolResolver(IDiagnosticHandler diagnostics, Universe universe, IkvmReflectionSymbolContext symbols, bool bootstrap) { _diagnostics = diagnostics ?? throw new ArgumentNullException(nameof(diagnostics)); _universe = universe ?? throw new ArgumentNullException(nameof(universe)); _symbols = symbols ?? throw new ArgumentNullException(nameof(symbols)); + _bootstrap = bootstrap; } /// @@ -99,6 +79,27 @@ public IAssemblySymbol GetCoreAssembly() return (_coreAssembly ??= GetSymbol(_universe.CoreLib)) ?? throw new DiagnosticEventException(DiagnosticEvent.CoreClassesMissing()); } + /// + /// Resolves the set of system assemblies. + /// + /// + IAssemblySymbol[] FindSystemAssemblies() + { + return _systemAssemblies ??= ResolveSystemAssembliesIter().Distinct().ToArray(); + } + + /// + /// Resolves the set of system assemblies that contain the system types. + /// + /// + IEnumerable ResolveSystemAssembliesIter() + { + foreach (var assembly in _universe.GetAssemblies()) + foreach (var typeName in GetSystemTypeNames()) + if (assembly.GetType(typeName) is Type t) + yield return GetSymbol(assembly); + } + /// public IAssemblySymbol GetRuntimeAssembly() { @@ -118,8 +119,12 @@ public IAssemblySymbol GetRuntimeAssembly() } /// - public IAssemblySymbol GetBaseAssembly() + public IAssemblySymbol? GetBaseAssembly() { + // bootstrap mode is used for builing the main assembly, and thus should not return the existing base assembly + if (_bootstrap) + return null; + return (_baseAssembly ??= FindBaseAssembly()) ?? throw new DiagnosticEventException(DiagnosticEvent.BootstrapClassesMissing()); } @@ -138,60 +143,59 @@ public IAssemblySymbol GetBaseAssembly() /// public ITypeSymbol ResolveCoreType(string typeName) { - return _coreTypeCache.GetOrAdd(typeName, _ => GetCoreAssembly().GetType(_)) ?? throw new DiagnosticEventException(DiagnosticEvent.CoreClassesMissing()); + return _coreTypeCache.GetOrAdd(typeName, _ => GetCoreAssembly().GetType(_)) ?? throw new DiagnosticEventException(DiagnosticEvent.CriticalClassNotFound(typeName)); } - /// - /// Resolves the set of system assemblies. - /// - /// - IAssemblySymbol[] ResolveSystemAssemblies() + /// + public ITypeSymbol ResolveSystemType(string typeName) { - return _systemAssemblies ??= ResolveSystemAssembliesIter().Distinct().ToArray(); + return _systemTypeCache.GetOrAdd(typeName, FindSystemType) ?? throw new DiagnosticEventException(DiagnosticEvent.CriticalClassNotFound(typeName)); } /// - /// Resolves the set of system assemblies that contain the system types. + /// Attempts to load the specified system type. /// + /// /// - IEnumerable ResolveSystemAssembliesIter() + ITypeSymbol? FindSystemType(string typeName) { - foreach (var assembly in _universe.GetAssemblies()) - foreach (var typeName in GetSystemTypeNames()) - if (assembly.GetType(typeName) is Type t) - yield return GetSymbol(assembly); + foreach (var assembly in FindSystemAssemblies()) + if (assembly.GetType(typeName) is { } t) + return t; + + return null; } /// - public ITypeSymbol ResolveSystemType(string typeName) + public ITypeSymbol ResolveRuntimeType(string typeName) { - return _systemTypeCache.GetOrAdd(typeName, FindSystemType) ?? throw new DiagnosticEventException(DiagnosticEvent.ClassNotFound(typeName)); + return _runtimeTypeCache.GetOrAdd(typeName, FindRuntimeType) ?? throw new DiagnosticEventException(DiagnosticEvent.CriticalClassNotFound(typeName)); } /// - /// Attempts to load the specified system type. + /// Attempts to load the specified runtime type. /// /// /// - ITypeSymbol? FindSystemType(string typeName) + ITypeSymbol? FindRuntimeType(string typeName) { - foreach (var assembly in ResolveSystemAssemblies()) - if (assembly.GetType(typeName) is { } t) - return t; - - return null; + return GetRuntimeAssembly()?.GetType(typeName); } /// - public ITypeSymbol? ResolveRuntimeType(string typeName) + public ITypeSymbol ResolveBaseType(string typeName) { - return GetRuntimeAssembly().GetType(typeName); + return _baseTypeCache.GetOrAdd(typeName, FindBaseType) ?? throw new DiagnosticEventException(DiagnosticEvent.CriticalClassNotFound(typeName)); } - /// - public ITypeSymbol? ResolveBaseType(string typeName) + /// + /// Attempts to find the base type. + /// + /// + /// + ITypeSymbol? FindBaseType(string typeName) { - return GetBaseAssembly().GetType(typeName); + return GetBaseAssembly()?.GetType(typeName); } /// diff --git a/src/IKVM.Tools.Importer/ImportClassLoader.cs b/src/IKVM.Tools.Importer/ImportClassLoader.cs index 908069f17..56a8c26c7 100644 --- a/src/IKVM.Tools.Importer/ImportClassLoader.cs +++ b/src/IKVM.Tools.Importer/ImportClassLoader.cs @@ -517,7 +517,7 @@ void SetMain(RuntimeJavaType type, IKVM.CoreLib.Symbols.Emit.PEFileKinds target, throw new ArgumentNullException(nameof(properties)); // global main method decorated with appropriate apartment type - var mainMethodProxy = GetTypeWrapperFactory().ModuleBuilder.DefineGlobalMethod("Main", System.Reflection.MethodAttributes.Public | System.Reflection.MethodAttributes.Static, Context.Types.Int32, new[] { Context.Types.String.MakeArrayType() }); + var mainMethodProxy = GetTypeWrapperFactory().ModuleBuilder.DefineGlobalMethod("Main", System.Reflection.MethodAttributes.Public | System.Reflection.MethodAttributes.Static, Context.Types.Int32, [Context.Types.String.MakeArrayType()]); if (apartmentAttributeType != null) mainMethodProxy.SetCustomAttribute(Context.Resolver.Symbols.CreateCustomAttribute(apartmentAttributeType.GetConstructor([]), [])); diff --git a/src/IKVM.Tools.Importer/ImportRuntimeSymbolResolver.cs b/src/IKVM.Tools.Importer/ImportRuntimeSymbolResolver.cs index 87799b064..321178fef 100644 --- a/src/IKVM.Tools.Importer/ImportRuntimeSymbolResolver.cs +++ b/src/IKVM.Tools.Importer/ImportRuntimeSymbolResolver.cs @@ -1,27 +1,4 @@ -/* - Copyright (C) 2002-2014 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -#nullable enable +#nullable enable using System; using System.Collections.Concurrent; @@ -63,6 +40,7 @@ static IEnumerable GetSystemTypeNames() readonly IDiagnosticHandler _diagnostics; readonly Universe _universe; readonly IkvmReflectionSymbolContext _symbols; + readonly bool _bootstrap; IAssemblySymbol? _coreAssembly; readonly ConcurrentDictionary _coreTypeCache = new(); @@ -82,12 +60,14 @@ static IEnumerable GetSystemTypeNames() /// /// /// + /// /// - public ImportRuntimeSymbolResolver(IDiagnosticHandler diagnostics, Universe universe, IkvmReflectionSymbolContext symbols) + public ImportRuntimeSymbolResolver(IDiagnosticHandler diagnostics, Universe universe, IkvmReflectionSymbolContext symbols, bool bootstrap) { _diagnostics = diagnostics ?? throw new ArgumentNullException(nameof(diagnostics)); _universe = universe ?? throw new ArgumentNullException(nameof(universe)); _symbols = symbols ?? throw new ArgumentNullException(nameof(symbols)); + _bootstrap = bootstrap; } /// @@ -118,8 +98,12 @@ public IAssemblySymbol GetRuntimeAssembly() } /// - public IAssemblySymbol GetBaseAssembly() + public IAssemblySymbol? GetBaseAssembly() { + // bootstrap mode is used for builing the main assembly, and thus should not return the existing base assembly + if (_bootstrap) + return null; + return (_baseAssembly ??= FindBaseAssembly()) ?? throw new DiagnosticEventException(DiagnosticEvent.BootstrapClassesMissing()); } From 28f1c037aaaea2c4eff40b326887fe8a9711d722 Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Sat, 28 Sep 2024 10:54:11 -0500 Subject: [PATCH 18/51] Restore MakeArray, since it doesn't do multidims. --- src/IKVM.Runtime/ByteCodeHelper.cs | 2 +- src/IKVM.Runtime/MethodHandleUtil.compiler.cs | 5 +--- src/IKVM.Runtime/RuntimeArrayJavaType.cs | 24 +++++++++++++++++++ src/IKVM.Runtime/RuntimeByteCodeJavaType.cs | 5 +--- src/IKVM.Runtime/RuntimeJavaType.cs | 2 +- src/IKVM.Runtime/compiler.cs | 4 ++-- .../ImportRuntimeSymbolResolver.cs | 6 ++--- .../RuntimeImportByteCodeJavaType.cs | 2 +- src/ikvmstub/Properties/launchSettings.json | 2 +- src/ikvmstub/ikvmstub.csproj | 2 +- 10 files changed, 36 insertions(+), 18 deletions(-) diff --git a/src/IKVM.Runtime/ByteCodeHelper.cs b/src/IKVM.Runtime/ByteCodeHelper.cs index 07730acea..942f28550 100644 --- a/src/IKVM.Runtime/ByteCodeHelper.cs +++ b/src/IKVM.Runtime/ByteCodeHelper.cs @@ -106,7 +106,7 @@ public static object multianewarray_ghost(RuntimeTypeHandle typeHandle, int[] le type = type.GetElementType(); } - var obj = multianewarray(typeof(object).MakeArrayType(rank).TypeHandle, lengths); + var obj = multianewarray(RuntimeArrayJavaType.MakeArrayType(typeof(object), rank).TypeHandle, lengths); GhostTag.SetTag(obj, typeHandle); return obj; } diff --git a/src/IKVM.Runtime/MethodHandleUtil.compiler.cs b/src/IKVM.Runtime/MethodHandleUtil.compiler.cs index 5015c8972..606793ebf 100644 --- a/src/IKVM.Runtime/MethodHandleUtil.compiler.cs +++ b/src/IKVM.Runtime/MethodHandleUtil.compiler.cs @@ -84,10 +84,7 @@ ITypeSymbol TypeWrapperToTypeForLoadConstant(RuntimeJavaType tw) while (tw.IsArray) tw = tw.ElementTypeWrapper; - if (dims == 1) - return tw.TypeAsSignatureType.MakeArrayType(); - else - return tw.TypeAsSignatureType.MakeArrayType(dims); + return RuntimeArrayJavaType.MakeArrayType(tw.TypeAsSignatureType, dims); } else { diff --git a/src/IKVM.Runtime/RuntimeArrayJavaType.cs b/src/IKVM.Runtime/RuntimeArrayJavaType.cs index 4d681af32..4ee9687a9 100644 --- a/src/IKVM.Runtime/RuntimeArrayJavaType.cs +++ b/src/IKVM.Runtime/RuntimeArrayJavaType.cs @@ -180,6 +180,30 @@ internal override RuntimeJavaType GetUltimateElementTypeWrapper() return ultimateElementTypeWrapper; } + internal static ITypeSymbol MakeArrayType(ITypeSymbol type, int dims) + { + // NOTE this is not just an optimization, but it is also required to + // make sure that ReflectionOnly types stay ReflectionOnly types + // (in particular instantiations of generic types from mscorlib that + // have ReflectionOnly type parameters). + for (int i = 0; i < dims; i++) + type = type.MakeArrayType(); + + return type; + } + + internal static Type MakeArrayType(Type type, int dims) + { + // NOTE this is not just an optimization, but it is also required to + // make sure that ReflectionOnly types stay ReflectionOnly types + // (in particular instantiations of generic types from mscorlib that + // have ReflectionOnly type parameters). + for (int i = 0; i < dims; i++) + type = type.MakeArrayType(); + + return type; + } + } } diff --git a/src/IKVM.Runtime/RuntimeByteCodeJavaType.cs b/src/IKVM.Runtime/RuntimeByteCodeJavaType.cs index 3c960048f..05d752cd0 100644 --- a/src/IKVM.Runtime/RuntimeByteCodeJavaType.cs +++ b/src/IKVM.Runtime/RuntimeByteCodeJavaType.cs @@ -933,10 +933,7 @@ static ITypeSymbol GetModOptHelper(RuntimeJavaType tw) if (tw.IsArray) { - if (tw.ArrayRank == 1) - return GetModOptHelper(tw.GetUltimateElementTypeWrapper()).MakeArrayType(); - else - return GetModOptHelper(tw.GetUltimateElementTypeWrapper()).MakeArrayType(tw.ArrayRank); + return RuntimeArrayJavaType.MakeArrayType(GetModOptHelper(tw.GetUltimateElementTypeWrapper()), tw.ArrayRank); } else if (tw.IsGhost) { diff --git a/src/IKVM.Runtime/RuntimeJavaType.cs b/src/IKVM.Runtime/RuntimeJavaType.cs index 4b5e96745..197ad18ce 100644 --- a/src/IKVM.Runtime/RuntimeJavaType.cs +++ b/src/IKVM.Runtime/RuntimeJavaType.cs @@ -137,7 +137,7 @@ ITypeSymbol GetClassLiteralType() while (tw.IsArray) tw = tw.ElementTypeWrapper; - return rank == 1 ? tw.TypeAsTBD.MakeArrayType() : tw.TypeAsTBD.MakeArrayType(rank); + return RuntimeArrayJavaType.MakeArrayType(tw.TypeAsTBD, rank); } else { diff --git a/src/IKVM.Runtime/compiler.cs b/src/IKVM.Runtime/compiler.cs index bc17ee9d9..4bb8d9c88 100644 --- a/src/IKVM.Runtime/compiler.cs +++ b/src/IKVM.Runtime/compiler.cs @@ -1770,7 +1770,7 @@ void Compile(Block block, int startIndex) while (tw.IsArray) tw = tw.ElementTypeWrapper; - ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldtoken, wrapper.ArrayRank == 1 ? tw.TypeAsTBD.MakeArrayType() : tw.TypeAsTBD.MakeArrayType(wrapper.ArrayRank)); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldtoken, RuntimeArrayJavaType.MakeArrayType(tw.TypeAsTBD, wrapper.ArrayRank)); ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldloc, localArray); ilGenerator.Emit(System.Reflection.Emit.OpCodes.Call, finish.Context.ByteCodeHelperMethods.multianewarray_ghost); ilGenerator.Emit(System.Reflection.Emit.OpCodes.Castclass, wrapper.TypeAsArrayType); @@ -1811,7 +1811,7 @@ void Compile(Block block, int startIndex) tw = tw.ElementTypeWrapper; var rank = wrapper.ArrayRank + 1; - ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldtoken, rank == 1 ? tw.TypeAsTBD.MakeArrayType() : tw.TypeAsTBD.MakeArrayType(rank)); + ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldtoken, RuntimeArrayJavaType.MakeArrayType(tw.TypeAsTBD, wrapper.ArrayRank + 1)); ilGenerator.Emit(System.Reflection.Emit.OpCodes.Call, finish.Context.ByteCodeHelperMethods.anewarray_ghost.MakeGenericMethod(wrapper.TypeAsArrayType)); } else diff --git a/src/IKVM.Tools.Importer/ImportRuntimeSymbolResolver.cs b/src/IKVM.Tools.Importer/ImportRuntimeSymbolResolver.cs index 321178fef..eed653511 100644 --- a/src/IKVM.Tools.Importer/ImportRuntimeSymbolResolver.cs +++ b/src/IKVM.Tools.Importer/ImportRuntimeSymbolResolver.cs @@ -60,14 +60,14 @@ static IEnumerable GetSystemTypeNames() /// /// /// - /// + /// /// - public ImportRuntimeSymbolResolver(IDiagnosticHandler diagnostics, Universe universe, IkvmReflectionSymbolContext symbols, bool bootstrap) + public ImportRuntimeSymbolResolver(IDiagnosticHandler diagnostics, Universe universe, IkvmReflectionSymbolContext symbols, ImportOptions options) { _diagnostics = diagnostics ?? throw new ArgumentNullException(nameof(diagnostics)); _universe = universe ?? throw new ArgumentNullException(nameof(universe)); _symbols = symbols ?? throw new ArgumentNullException(nameof(symbols)); - _bootstrap = bootstrap; + _bootstrap = options.Bootstrap; } /// diff --git a/src/IKVM.Tools.Importer/RuntimeImportByteCodeJavaType.cs b/src/IKVM.Tools.Importer/RuntimeImportByteCodeJavaType.cs index 13b650c2e..0915471e3 100644 --- a/src/IKVM.Tools.Importer/RuntimeImportByteCodeJavaType.cs +++ b/src/IKVM.Tools.Importer/RuntimeImportByteCodeJavaType.cs @@ -995,7 +995,7 @@ internal override void EmitCheckcast(CodeEmitter ilgen) } ilgen.EmitLdc_I4(rank); ilgen.Emit(System.Reflection.Emit.OpCodes.Call, ghostCastArrayMethod); - ilgen.Emit(System.Reflection.Emit.OpCodes.Castclass, rank == 1 ? Context.Types.Object.MakeArrayType() : Context.Types.Object.MakeArrayType(rank)); + ilgen.Emit(System.Reflection.Emit.OpCodes.Castclass, RuntimeArrayJavaType.MakeArrayType(Context.Types.Object, rank)); } else { diff --git a/src/ikvmstub/Properties/launchSettings.json b/src/ikvmstub/Properties/launchSettings.json index c0011c600..338a877ef 100644 --- a/src/ikvmstub/Properties/launchSettings.json +++ b/src/ikvmstub/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "ikvmstub": { "commandName": "Project", - "commandLineArgs": "--bootstrap --nostdlib --skiperror --non-public-types --parameters --reference:\"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\mscorlib.dll\" --reference:\"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\System.Configuration.dll\" --reference:\"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\System.Core.dll\" --reference:\"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\System.dll\" --reference:\"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\System.Numerics.dll\" --reference:\"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\System.Security.dll\" --reference:\"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\System.Xml.dll\" --reference:\"C:\\Program Files\\dotnet\\sdk\\NuGetFallbackFolder\\system.numerics.vectors\\4.5.0\\ref\\net46\\System.Numerics.Vectors.dll\" --reference:\"C:\\Program Files\\dotnet\\sdk\\NuGetFallbackFolder\\system.valuetuple\\4.5.0\\ref\\net47\\System.ValueTuple.dll\" --reference:\"D:\\ikvm\\src\\IKVM.CoreLib\\bin\\Debug\\net472\\IKVM.CoreLib.dll\" --reference:\"D:\\ikvm\\src\\IKVM.Java\\bin\\Debug\\net472\\IKVM.Java.dll\" --reference:\"D:\\ikvm\\src\\IKVM.Reflection\\obj\\Debug\\net472\\ref\\IKVM.Reflection.dll\" --reference:\"D:\\ikvm\\src\\IKVM.Runtime-ref\\obj\\Debug\\net472\\ref\\IKVM.Runtime.dll\" --reference:\"D:\\packages\\NuGet\\cache\\ikvm.bytecode\\9.1.3\\lib\\net472\\IKVM.ByteCode.dll\" --reference:\"D:\\packages\\NuGet\\cache\\microsoft.bcl.asyncinterfaces\\8.0.0\\lib\\net462\\Microsoft.Bcl.AsyncInterfaces.dll\" --reference:\"D:\\packages\\NuGet\\cache\\system.buffers\\4.5.1\\ref\\net45\\System.Buffers.dll\" --reference:\"D:\\packages\\NuGet\\cache\\system.collections.immutable\\8.0.0\\lib\\net462\\System.Collections.Immutable.dll\" --reference:\"D:\\packages\\NuGet\\cache\\system.io.pipelines\\8.0.0\\lib\\net462\\System.IO.Pipelines.dll\" --reference:\"D:\\packages\\NuGet\\cache\\system.memory\\4.5.5\\lib\\net461\\System.Memory.dll\" --reference:\"D:\\packages\\NuGet\\cache\\system.reflection.metadata\\8.0.0\\lib\\net462\\System.Reflection.Metadata.dll\" --reference:\"D:\\packages\\NuGet\\cache\\system.reflection.typeextensions\\4.7.0\\ref\\net472\\System.Reflection.TypeExtensions.dll\" --reference:\"D:\\packages\\NuGet\\cache\\system.runtime.compilerservices.unsafe\\6.0.0\\lib\\net461\\System.Runtime.CompilerServices.Unsafe.dll\" --reference:\"D:\\packages\\NuGet\\cache\\system.text.encodings.web\\8.0.0\\lib\\net462\\System.Text.Encodings.Web.dll\" --reference:\"D:\\packages\\NuGet\\cache\\system.text.json\\8.0.4\\lib\\net462\\System.Text.Json.dll\" --reference:\"D:\\packages\\NuGet\\cache\\system.threading.tasks.extensions\\4.5.4\\lib\\net461\\System.Threading.Tasks.Extensions.dll\" --out:\"IKVM.Runtime.jar\" \"D:\\ikvm\\src\\IKVM.Runtime-ref\\obj\\Debug\\net472\\ref\\IKVM.Runtime.dll\"" + "commandLineArgs": "--bootstrap --nostdlib --skiperror --parameters --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\Microsoft.Win32.Primitives.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Collections.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Net.NameResolution.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Net.Primitives.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Runtime.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Runtime.InteropServices.dll\" --reference:\"D:\\ikvm\\src\\IKVM.Java\\bin\\Debug\\net8.0\\IKVM.Java.dll\" --reference:\"D:\\ikvm\\src\\IKVM.Runtime-ref\\obj\\Debug\\net8.0\\ref\\IKVM.Runtime.dll\" --out:\"System.Net.NameResolution.jar\" \"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Net.NameResolution.dll\"" } } } \ No newline at end of file diff --git a/src/ikvmstub/ikvmstub.csproj b/src/ikvmstub/ikvmstub.csproj index 1d89f5a4d..4b9e31015 100644 --- a/src/ikvmstub/ikvmstub.csproj +++ b/src/ikvmstub/ikvmstub.csproj @@ -1,7 +1,7 @@  Exe - net472;net6.0;net8.0 + net8.0;net472;net6.0; $(_SupportedToolRuntimes) true true From a0331c90e77ff8f7b003e6baa4d466fa62079328 Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Sat, 28 Sep 2024 16:46:27 -0500 Subject: [PATCH 19/51] Turn off skiperrors. Fix resolver. --- .../targets/IKVM.Java.Core.NoTasks.targets | 1 - src/IKVM.Runtime/JVM.Resolver.cs | 4 +++- src/IKVM.Runtime/JVM.cs | 1 - .../Java/Externs/ikvm/runtime/Util.cs | 2 +- .../Diagnostics/DiagnosticOptions.cs | 4 ++-- src/IKVM.Tools.Importer/ImportClassLoader.cs | 20 +++++++++---------- src/ikvmc/Properties/launchSettings.json | 2 +- src/ikvmc/ikvmc.csproj | 2 +- src/ikvmstub/Properties/launchSettings.json | 2 +- src/ikvmstub/ikvmstub.csproj | 2 +- src/javac-ref/Properties/launchSettings.json | 2 +- src/javac-ref/javac-ref.csproj | 2 +- 12 files changed, 21 insertions(+), 23 deletions(-) diff --git a/src/IKVM.NET.Sdk/targets/IKVM.Java.Core.NoTasks.targets b/src/IKVM.NET.Sdk/targets/IKVM.Java.Core.NoTasks.targets index 5d2016920..15b39348c 100644 --- a/src/IKVM.NET.Sdk/targets/IKVM.Java.Core.NoTasks.targets +++ b/src/IKVM.NET.Sdk/targets/IKVM.Java.Core.NoTasks.targets @@ -137,7 +137,6 @@ Value = b.ToString(); <_IkvmExporterArgs Remove="@(_IkvmExporterArgs)" /> <_IkvmExporterArgs Include="--bootstrap" Condition=" '%(ReferenceExport.Bootstrap)' == 'true' " /> <_IkvmExporterArgs Include="--nostdlib" Condition=" '%(ReferenceExport.NoStdLib)' == 'true' " /> - <_IkvmExporterArgs Include="--skiperror" /> <_IkvmExporterArgs Include="--non-public-types" Condition=" '%(ReferenceExport.IncludeNonPublicTypes)' == 'true' " /> <_IkvmExporterArgs Include="--non-public-interfaces" Condition=" '%(ReferenceExport.IncludeNonPublicInterfaces)' == 'true' " /> <_IkvmExporterArgs Include="--non-public-members" Condition=" '%(ReferenceExport.IncludeNonPublicMembers)' == 'true' " /> diff --git a/src/IKVM.Runtime/JVM.Resolver.cs b/src/IKVM.Runtime/JVM.Resolver.cs index 188121ae7..83d23d67b 100644 --- a/src/IKVM.Runtime/JVM.Resolver.cs +++ b/src/IKVM.Runtime/JVM.Resolver.cs @@ -60,8 +60,10 @@ static IEnumerable GetSystemAssemblies() /// public Resolver() { + _coreAssembly = GetSymbol(typeof(object).Assembly); _systemAssemblies = GetSystemAssemblies().Distinct().ToArray().Select(GetSymbol).ToArray(); _runtimeAssembly = GetSymbol(typeof(JVM).Assembly); + _baseAssembly = GetSymbol(typeof(java.lang.Object).Assembly); } /// @@ -76,7 +78,7 @@ public IAssemblySymbol ResolveAssembly(string assemblyName) /// public IAssemblySymbol GetCoreAssembly() { - return _coreAssembly ??= GetSymbol(typeof(object).Assembly); + return _coreAssembly; } /// diff --git a/src/IKVM.Runtime/JVM.cs b/src/IKVM.Runtime/JVM.cs index f287af1c9..159f7aadf 100644 --- a/src/IKVM.Runtime/JVM.cs +++ b/src/IKVM.Runtime/JVM.cs @@ -6,7 +6,6 @@ using System.Text; using System.Threading; -using IKVM.CoreLib.Diagnostics.Tracing; using IKVM.Runtime.Vfs; namespace IKVM.Runtime diff --git a/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Util.cs b/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Util.cs index f765da0e7..5d50f9c5b 100644 --- a/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Util.cs +++ b/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Util.cs @@ -95,7 +95,7 @@ internal static RuntimeJavaType GetTypeWrapperFromObject(RuntimeContext context, #else var t = Type.GetTypeFromHandle(handle); var ts = JVM.Context.Resolver.GetSymbol(t); - if (ts.IsPrimitive || JVM.Context.ClassLoaderFactory.IsRemappedType(ts) || ts == typeof(void)) + if (ts.IsPrimitive || JVM.Context.ClassLoaderFactory.IsRemappedType(ts) || ts == JVM.Context.Types.Void) return JVM.Context.ManagedJavaTypeFactory.GetJavaTypeFromManagedType(ts).MakeArrayType(rank).ClassObject; if (!IsVisibleAsClass(t)) diff --git a/src/IKVM.Tools.Core/Diagnostics/DiagnosticOptions.cs b/src/IKVM.Tools.Core/Diagnostics/DiagnosticOptions.cs index 9870c9356..7f804f637 100644 --- a/src/IKVM.Tools.Core/Diagnostics/DiagnosticOptions.cs +++ b/src/IKVM.Tools.Core/Diagnostics/DiagnosticOptions.cs @@ -16,7 +16,7 @@ class DiagnosticOptions /// /// Gets or sets whether the specified diagnostics should be suppressed. /// - public ImmutableArray NoWarnDiagnostics { get; set; } + public ImmutableArray NoWarnDiagnostics { get; set; } = []; /// /// Gets or sets whether all warnings should be promoted to errors. @@ -26,7 +26,7 @@ class DiagnosticOptions /// /// Gets or sets whether the specified diagnostics should be promoted to errors. /// - public ImmutableArray WarnAsErrorDiagnostics { get; set; } + public ImmutableArray WarnAsErrorDiagnostics { get; set; } = []; } diff --git a/src/IKVM.Tools.Importer/ImportClassLoader.cs b/src/IKVM.Tools.Importer/ImportClassLoader.cs index 56a8c26c7..f7894b03c 100644 --- a/src/IKVM.Tools.Importer/ImportClassLoader.cs +++ b/src/IKVM.Tools.Importer/ImportClassLoader.cs @@ -1131,11 +1131,11 @@ internal override void Finish() var paramTypes = this.GetParametersForDefineMethod(); - var cbCore = GetMethod() as IMethodSymbolBuilder; - + var cbCore = GetMethod() as IConstructorSymbolBuilder; if (cbCore != null) { - CodeEmitter ilgen = DeclaringType.Context.CodeEmitterFactory.Create(cbCore); + var ilgen = DeclaringType.Context.CodeEmitterFactory.Create(cbCore); + // TODO we need to support ghost (and other funky?) parameter types if (m.Body != null) { @@ -1146,9 +1146,8 @@ internal override void Finish() { ilgen.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); for (int i = 0; i < paramTypes.Length; i++) - { ilgen.EmitLdarg(i + 1); - } + if (m.Redirect != null) { throw new NotImplementedException(); @@ -1157,19 +1156,18 @@ internal override void Finish() { var baseCon = DeclaringType.TypeAsTBD.GetConstructor(paramTypes); if (baseCon == null) - { - // TODO better error handling throw new InvalidOperationException("base class constructor not found: " + DeclaringType.Name + "." + m.Sig); - } + ilgen.Emit(System.Reflection.Emit.OpCodes.Call, baseCon); } + ilgen.Emit(System.Reflection.Emit.OpCodes.Ret); } + ilgen.DoEmit(); - if (this.DeclaringType.ClassLoader.EmitStackTraceInfo) - { + + if (DeclaringType.ClassLoader.EmitStackTraceInfo) ilgen.EmitLineNumberTable(cbCore); - } } if (mbHelper != null) diff --git a/src/ikvmc/Properties/launchSettings.json b/src/ikvmc/Properties/launchSettings.json index 31d9cf801..02b8e637e 100644 --- a/src/ikvmc/Properties/launchSettings.json +++ b/src/ikvmc/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "ikvmc": { "commandName": "Project", - "commandLineArgs": "@D:\\ikvm\\src\\IKVM.Java\\obj\\Debug\\net8.0\\IKVM.Java.ikvmc.rsp" + "commandLineArgs": "@D:\\ikvm\\src\\IKVM.Java.runtime.win\\obj\\Debug\\net8.0\\IKVM.Java.runtime.win.ikvmc.rsp" } } } diff --git a/src/ikvmc/ikvmc.csproj b/src/ikvmc/ikvmc.csproj index 042fb47ce..939ff4bbc 100644 --- a/src/ikvmc/ikvmc.csproj +++ b/src/ikvmc/ikvmc.csproj @@ -1,7 +1,7 @@  Exe - net472;net6.0;net8.0 + net8.0;net472;net6.0 $(_SupportedToolRuntimes) true true diff --git a/src/ikvmstub/Properties/launchSettings.json b/src/ikvmstub/Properties/launchSettings.json index 338a877ef..7b5a3610e 100644 --- a/src/ikvmstub/Properties/launchSettings.json +++ b/src/ikvmstub/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "ikvmstub": { "commandName": "Project", - "commandLineArgs": "--bootstrap --nostdlib --skiperror --parameters --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\Microsoft.Win32.Primitives.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Collections.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Net.NameResolution.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Net.Primitives.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Runtime.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Runtime.InteropServices.dll\" --reference:\"D:\\ikvm\\src\\IKVM.Java\\bin\\Debug\\net8.0\\IKVM.Java.dll\" --reference:\"D:\\ikvm\\src\\IKVM.Runtime-ref\\obj\\Debug\\net8.0\\ref\\IKVM.Runtime.dll\" --out:\"System.Net.NameResolution.jar\" \"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Net.NameResolution.dll\"" + "commandLineArgs": "--bootstrap --nostdlib --parameters --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Numerics.Vectors.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Runtime.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Runtime.Intrinsics.dll\" --reference:\"D:\\ikvm\\src\\IKVM.Java-ref\\obj\\Debug\\net8.0\\ref\\IKVM.Java.dll\" --reference:\"D:\\ikvm\\src\\IKVM.Runtime-ref\\obj\\Debug\\net8.0\\ref\\IKVM.Runtime.dll\" --out:\"System.Runtime.Intrinsics.jar\" \"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Runtime.Intrinsics.dll\"" } } } \ No newline at end of file diff --git a/src/ikvmstub/ikvmstub.csproj b/src/ikvmstub/ikvmstub.csproj index 4b9e31015..e66f94dc4 100644 --- a/src/ikvmstub/ikvmstub.csproj +++ b/src/ikvmstub/ikvmstub.csproj @@ -1,7 +1,7 @@  Exe - net8.0;net472;net6.0; + net8.0;net6.0;net472; $(_SupportedToolRuntimes) true true diff --git a/src/javac-ref/Properties/launchSettings.json b/src/javac-ref/Properties/launchSettings.json index 889072b99..1118a9076 100644 --- a/src/javac-ref/Properties/launchSettings.json +++ b/src/javac-ref/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "javac": { "commandName": "Project", - "commandLineArgs": "@C:\\dev\\ikvm\\src\\javadoc\\obj\\Debug\\net8.0\\osx-arm64\\javadoc.javac.rsp", + "commandLineArgs": "", "environmentVariables": { } diff --git a/src/javac-ref/javac-ref.csproj b/src/javac-ref/javac-ref.csproj index 4b232be5d..105dc9c6b 100644 --- a/src/javac-ref/javac-ref.csproj +++ b/src/javac-ref/javac-ref.csproj @@ -6,7 +6,7 @@ Exe javac - net8.0;net472;net6.0; + net472;net8.0;;net6.0; $(_SupportedImageRuntimes) true true From 1cbbd1139ffe5fd983ecd3797bdce14c3991cbba Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Tue, 1 Oct 2024 16:42:35 -0500 Subject: [PATCH 20/51] Unify System.Reflection version. --- .../IkvmReflectionSymbolTests.cs | 4 + .../Reflection/TypeListEqualityComparer.cs | 50 ++ .../Symbols/Emit/IModuleSymbolBuilder.cs | 4 +- .../IIkvmReflectionPropertySymbolBuilder.cs | 1 - .../IkvmReflectionAssemblySymbolBuilder.cs | 10 +- .../Emit/IkvmReflectionMemberSymbolBuilder.cs | 10 +- .../Emit/IkvmReflectionModuleSymbolBuilder.cs | 35 +- .../IkvmReflectionParameterSymbolBuilder.cs | 10 +- .../IIkvmReflectionModuleSymbol.cs | 4 +- .../IkvmReflection/IIkvmReflectionSymbol.cs | 2 - .../IkvmReflectionAssemblySymbol.cs | 10 +- .../IkvmReflectionMemberSymbol.cs | 10 +- .../IkvmReflectionMethodTable.cs | 22 +- .../IkvmReflectionModuleSymbol.cs | 10 +- .../IkvmReflectionParameterSymbol.cs | 10 +- .../IkvmReflection/IkvmReflectionSymbol.cs | 28 +- .../IkvmReflectionTypeSymbol.cs | 2 +- .../IkvmReflection/IkvmReflectionUtil.cs | 6 +- .../Emit/IReflectionAssemblySymbolBuilder.cs | 9 +- .../IReflectionConstructorSymbolBuilder.cs | 5 +- .../Emit/IReflectionEventSymbolBuilder.cs | 5 +- .../Emit/IReflectionFieldSymbolBuilder.cs | 2 +- ...ectionGenericTypeParameterSymbolBuilder.cs | 2 +- .../Emit/IReflectionMemberSymbolBuilder.cs | 7 +- .../IReflectionMethodBaseSymbolBuilder.cs | 13 +- .../Emit/IReflectionMethodSymbolBuilder.cs | 9 +- .../Emit/IReflectionModuleSymbolBuilder.cs | 59 +- .../Emit/IReflectionParameterSymbolBuilder.cs | 2 +- .../Emit/IReflectionPropertySymbolBuilder.cs | 12 +- .../Emit/IReflectionSymbolBuilder.cs | 77 ++- .../Emit/IReflectionTypeSymbolBuilder.cs | 44 +- .../Emit/ReflectionAssemblySymbolBuilder.cs | 83 +-- .../ReflectionConstructorSymbolBuilder.cs | 13 +- .../Emit/ReflectionEventSymbolBuilder.cs | 4 +- .../Emit/ReflectionFieldSymbolBuilder.cs | 4 +- ...ectionGenericTypeParameterSymbolBuilder.cs | 485 +++++++++----- .../Emit/ReflectionMemberSymbolBuilder.cs | 352 +++++----- .../Emit/ReflectionMethodBaseSymbolBuilder.cs | 31 +- .../Emit/ReflectionMethodSymbolBuilder.cs | 52 +- .../Emit/ReflectionModuleSymbolBuilder.cs | 381 ++++++----- .../Emit/ReflectionParameterBuilderInfo.cs | 3 +- .../Emit/ReflectionParameterSymbolBuilder.cs | 35 +- .../Emit/ReflectionPropertySymbolBuilder.cs | 31 +- .../Emit/ReflectionSymbolBuilder.cs | 12 +- .../Emit/ReflectionTypeSymbolBuilder.cs | 589 ++++++++++------ .../Reflection/IReflectionAssemblySymbol.cs | 10 - .../Reflection/IReflectionEventSymbol.cs | 8 +- .../Reflection/IReflectionMethodBaseSymbol.cs | 7 + .../Reflection/IReflectionMethodSymbol.cs | 17 +- .../Reflection/IReflectionModuleSymbol.cs | 51 +- .../Reflection/IReflectionParameterSymbol.cs | 4 +- .../Reflection/IReflectionPropertySymbol.cs | 7 + .../Symbols/Reflection/IReflectionSymbol.cs | 75 --- .../Reflection/IReflectionTypeSymbol.cs | 82 +++ .../Reflection/ReflectionAssemblySymbol.cs | 89 ++- .../Reflection/ReflectionConstructorSymbol.cs | 5 +- .../Reflection/ReflectionEventSymbol.cs | 11 +- .../Reflection/ReflectionEventTable.cs | 95 +++ .../Reflection/ReflectionFieldSymbol.cs | 9 +- .../Reflection/ReflectionFieldTable.cs | 81 +++ .../ReflectionGenericTypeParameterSymbol.cs | 465 ++++++++----- .../ReflectionGenericTypeParameterTable.cs | 78 +++ .../Reflection/ReflectionMemberSymbol.cs | 307 +++------ .../Reflection/ReflectionMethodBaseSymbol.cs | 42 +- .../Reflection/ReflectionMethodSpecTable.cs | 64 ++ .../Reflection/ReflectionMethodSymbol.cs | 30 +- .../Reflection/ReflectionMethodTable.cs | 143 ++++ .../Reflection/ReflectionModuleMetadata.cs | 488 -------------- .../Reflection/ReflectionModuleSymbol.cs | 103 +-- ...lyMetadata.cs => ReflectionModuleTable.cs} | 39 +- .../Reflection/ReflectionParameterSymbol.cs | 35 +- .../Reflection/ReflectionParameterTable.cs | 102 +++ .../Reflection/ReflectionPropertySymbol.cs | 24 +- .../Reflection/ReflectionPropertyTable.cs | 81 +++ .../Symbols/Reflection/ReflectionSymbol.cs | 69 +- .../Reflection/ReflectionSymbolContext.cs | 157 +++-- .../Symbols/Reflection/ReflectionTypeImpl.cs | 633 ------------------ .../Reflection/ReflectionTypeSpecTable.cs | 127 ++++ .../Reflection/ReflectionTypeSymbol.cs | 460 ++++++++----- .../Symbols/Reflection/ReflectionTypeTable.cs | 75 +++ .../Symbols/Reflection/ReflectionUtil.cs | 91 ++- src/IKVM.Reflection/Emit/MethodBuilder.cs | 3 +- src/IKVM.Runtime/RuntimeArrayJavaType.cs | 2 +- .../RuntimeAssemblyClassLoader.cs | 2 +- src/IKVM.Runtime/RuntimeJavaType.cs | 10 +- .../RuntimeManagedByteCodeJavaType.cs | 5 +- src/IKVM.Runtime/StubGen/StubGenerator.cs | 2 +- src/IKVM.Tools.Importer/ImportClassLoader.cs | 5 +- src/ikvmstub/Properties/launchSettings.json | 2 +- src/ikvmstub/ikvmstub.csproj | 2 +- 90 files changed, 3747 insertions(+), 2999 deletions(-) create mode 100644 src/IKVM.CoreLib/Reflection/TypeListEqualityComparer.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/ReflectionEventTable.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/ReflectionFieldTable.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericTypeParameterTable.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSpecTable.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodTable.cs delete mode 100644 src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleMetadata.cs rename src/IKVM.CoreLib/Symbols/Reflection/{ReflectionAssemblyMetadata.cs => ReflectionModuleTable.cs} (55%) create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterTable.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/ReflectionPropertyTable.cs delete mode 100644 src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeImpl.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSpecTable.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeTable.cs diff --git a/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs b/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs index 0147fea23..ab284d995 100644 --- a/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs +++ b/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs @@ -97,6 +97,8 @@ public void ArrayTypeShouldBeSame() var c = new IkvmReflectionSymbolContext(universe); var s1 = c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.Object").MakeArrayType(2)); var s2 = c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.Object").MakeArrayType(2)); + s1.IsSZArray.Should().BeFalse(); + s2.IsSZArray.Should().BeFalse(); s1.Should().BeSameAs(s2); } @@ -106,6 +108,8 @@ public void SZArrayTypeShouldBeSame() var c = new IkvmReflectionSymbolContext(universe); var s1 = c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.Int32").MakeArrayType()); var s2 = c.GetOrCreateTypeSymbol(coreAssembly.GetType("System.Int32").MakeArrayType()); + s1.IsSZArray.Should().BeTrue(); + s2.IsSZArray.Should().BeTrue(); s1.Should().BeSameAs(s2); } diff --git a/src/IKVM.CoreLib/Reflection/TypeListEqualityComparer.cs b/src/IKVM.CoreLib/Reflection/TypeListEqualityComparer.cs new file mode 100644 index 000000000..c7349923b --- /dev/null +++ b/src/IKVM.CoreLib/Reflection/TypeListEqualityComparer.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; + +namespace IKVM.CoreLib.Symbols +{ + + /// + /// Compares two array instances for equality. + /// + class TypeListEqualityComparer : IEqualityComparer + { + + public static readonly TypeListEqualityComparer Instance = new(); + + public bool Equals(Type[]? x, Type[]? y) + { + if (x == y) + return true; + + if (x == null || y == null) + return false; + + if (x.Length != y.Length) + return false; + + for (int i = 0; i < x.Length; i++) + if (x[i] != y[i]) + return false; + + return true; + } + + public int GetHashCode(Type[] obj) + { + int result = 17; + + for (int i = 0; i < obj.Length; i++) + { + unchecked + { + result = result * 41 + obj[i].GetHashCode(); + } + } + + return result; + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Emit/IModuleSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IModuleSymbolBuilder.cs index f030d9e2e..1ad74cf09 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/IModuleSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/IModuleSymbolBuilder.cs @@ -183,12 +183,12 @@ interface IModuleSymbolBuilder : ISymbolBuilder, IModuleSymbol void AddReference(IAssemblySymbol assembly); /// - /// Finishes the module. + /// Finishes the module and all types. Required before save. /// void Complete(); /// - /// Saves this module assembly to disk. + /// Saves this module assembly to disk. Module must first be completed. /// /// /// diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionPropertySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionPropertySymbolBuilder.cs index a4fc28e00..b28ea70a4 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionPropertySymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionPropertySymbolBuilder.cs @@ -1,5 +1,4 @@ using IKVM.CoreLib.Symbols.Emit; -using IKVM.Reflection; using IKVM.Reflection.Emit; namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionAssemblySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionAssemblySymbolBuilder.cs index 73594ea8c..0d876aa82 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionAssemblySymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionAssemblySymbolBuilder.cs @@ -240,7 +240,12 @@ public CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inh /// public CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) { - return ResolveCustomAttribute(UnderlyingAssembly.__GetCustomAttributes(attributeType.Unpack(), inherit).FirstOrDefault()); + var _attributeType = attributeType.Unpack(); + var a = UnderlyingAssembly.__GetCustomAttributes(_attributeType, inherit); + if (a.Count > 0) + return ResolveCustomAttribute(a[0]); + + return null; } /// @@ -269,6 +274,9 @@ public bool IsDefined(ITypeSymbol attributeType, bool inherit = false) #endregion + /// + public override string ToString() => UnderlyingAssembly.ToString()!; + } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMemberSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMemberSymbolBuilder.cs index 456507620..b174dd069 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMemberSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMemberSymbolBuilder.cs @@ -319,7 +319,12 @@ public virtual CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, /// public virtual CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) { - return ResolveCustomAttribute(UnderlyingMember.__GetCustomAttributes(attributeType.Unpack(), inherit).FirstOrDefault()); + var _attributeType = attributeType.Unpack(); + var a = UnderlyingMember.__GetCustomAttributes(_attributeType, inherit); + if (a.Count > 0) + return ResolveCustomAttribute(a[0]); + + return null; } /// @@ -336,6 +341,9 @@ public virtual void OnComplete() } + /// + public override string ToString() => UnderlyingMember.ToString()!; + } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionModuleSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionModuleSymbolBuilder.cs index 752ef4f3e..339bb88c2 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionModuleSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionModuleSymbolBuilder.cs @@ -17,7 +17,8 @@ class IkvmReflectionModuleSymbolBuilder : IkvmReflectionSymbolBuilder, IIkvmRefl { readonly IIkvmReflectionAssemblySymbol _resolvingAssembly; - readonly ModuleBuilder _module; + Module _module; + ModuleBuilder? _builder; IkvmReflectionTypeTable _typeTable; IkvmReflectionMethodTable _methodTable; @@ -28,13 +29,14 @@ class IkvmReflectionModuleSymbolBuilder : IkvmReflectionSymbolBuilder, IIkvmRefl /// /// /// - /// + /// /// - public IkvmReflectionModuleSymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionAssemblySymbol resolvingAssembly, ModuleBuilder module) : + public IkvmReflectionModuleSymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionAssemblySymbol resolvingAssembly, ModuleBuilder builder) : base(context) { _resolvingAssembly = resolvingAssembly ?? throw new ArgumentNullException(nameof(resolvingAssembly)); - _module = module ?? throw new ArgumentNullException(nameof(module)); + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + _module = _builder; _typeTable = new IkvmReflectionTypeTable(context, this, null); _methodTable = new IkvmReflectionMethodTable(context, this, null); @@ -42,10 +44,10 @@ public IkvmReflectionModuleSymbolBuilder(IkvmReflectionSymbolContext context, II } /// - public Module UnderlyingModule => UnderlyingModuleBuilder; + public Module UnderlyingModule => _module; /// - public ModuleBuilder UnderlyingModuleBuilder => _module; + public ModuleBuilder UnderlyingModuleBuilder => _builder ?? throw new InvalidOperationException(); /// public IIkvmReflectionAssemblySymbol ResolvingAssembly => _resolvingAssembly; @@ -305,11 +307,20 @@ public void AddReference(IAssemblySymbol assembly) public void Complete() { UnderlyingModuleBuilder.CreateGlobalFunctions(); + + foreach (var type in GetTypes()) + if (type is IIkvmReflectionTypeSymbolBuilder t) + t.Complete(); + + _builder = null; } /// public void Save(System.Reflection.PortableExecutableKinds portableExecutableKind, IKVM.CoreLib.Symbols.ImageFileMachine imageFileMachine) { + if (IsComplete == false) + throw new InvalidOperationException("Module must be completed before Save."); + UnderlyingModuleBuilder.__Save((PortableExecutableKinds)portableExecutableKind, (IKVM.Reflection.ImageFileMachine)imageFileMachine); } @@ -336,7 +347,7 @@ public void Save(System.Reflection.PortableExecutableKinds portableExecutableKin public string ScopeName => UnderlyingModule.ScopeName; /// - public override bool IsComplete => _module == null; + public override bool IsComplete => _builder == null; /// public ulong ImageBase @@ -518,7 +529,12 @@ public virtual CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, /// public virtual CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) { - return ResolveCustomAttribute(UnderlyingModule.__GetCustomAttributes(attributeType.Unpack(), inherit).FirstOrDefault()); + var _attributeType = attributeType.Unpack(); + var a = UnderlyingModule.__GetCustomAttributes(_attributeType, inherit); + if (a.Count > 0) + return ResolveCustomAttribute(a[0]); + + return null; } /// @@ -529,6 +545,9 @@ public bool IsDefined(ITypeSymbol attributeType, bool inherit = false) #endregion + /// + public override string ToString() => UnderlyingModule.ToString()!; + } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterSymbolBuilder.cs index 461d75db7..f0e7aed50 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterSymbolBuilder.cs @@ -128,7 +128,12 @@ public virtual CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, /// public virtual CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) { - return ResolveCustomAttribute(UnderlyingParameter.__GetCustomAttributes(attributeType.Unpack(), inherit).FirstOrDefault()); + var _attributeType = attributeType.Unpack(); + var a = UnderlyingParameter.__GetCustomAttributes(_attributeType, inherit); + if (a.Count > 0) + return ResolveCustomAttribute(a[0]); + + return null; } /// @@ -163,6 +168,9 @@ public void OnComplete() _builder = null; } + /// + public override string ToString() => UnderlyingParameter.ToString()!; + } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionModuleSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionModuleSymbol.cs index 41a1252f2..1111312ef 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionModuleSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionModuleSymbol.cs @@ -1,6 +1,4 @@ -using IKVM.CoreLib.Symbols.IkvmReflection.Emit; -using IKVM.Reflection; -using IKVM.Reflection.Emit; +using IKVM.Reflection; using Type = IKVM.Reflection.Type; diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionSymbol.cs index af3369996..d09e074b9 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionSymbol.cs @@ -2,9 +2,7 @@ using System.Collections.Immutable; using System.Diagnostics.CodeAnalysis; -using IKVM.CoreLib.Symbols.IkvmReflection.Emit; using IKVM.Reflection; -using IKVM.Reflection.Emit; using Type = IKVM.Reflection.Type; diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs index db6ef47b7..b5c1d3dd1 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs @@ -146,7 +146,12 @@ public CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inh /// public CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) { - return ResolveCustomAttribute(UnderlyingAssembly.__GetCustomAttributes(attributeType.Unpack(), inherit).FirstOrDefault()); + var _attributeType = attributeType.Unpack(); + var a = UnderlyingAssembly.__GetCustomAttributes(_attributeType, inherit); + if (a.Count > 0) + return ResolveCustomAttribute(a[0]); + + return null; } /// @@ -175,6 +180,9 @@ public bool IsDefined(ITypeSymbol attributeType, bool inherit = false) #endregion + /// + public override string ToString() => UnderlyingAssembly.ToString(); + } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs index 7da4302ba..b9d322232 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs @@ -192,7 +192,12 @@ public virtual CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, /// public virtual CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) { - return ResolveCustomAttribute(UnderlyingMember.__GetCustomAttributes(attributeType.Unpack(), inherit).FirstOrDefault()); + var _attributeType = attributeType.Unpack(); + var a = UnderlyingMember.__GetCustomAttributes(_attributeType, inherit); + if (a.Count > 0) + return ResolveCustomAttribute(a[0]); + + return null; } /// @@ -203,6 +208,9 @@ public virtual bool IsDefined(ITypeSymbol attributeType, bool inherit = false) #endregion + /// + public override string ToString() => UnderlyingMember.ToString()!; + } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodTable.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodTable.cs index 479dda6ac..ec6a02017 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodTable.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodTable.cs @@ -23,7 +23,7 @@ struct IkvmReflectionMethodTable IndexRangeDictionary _table = new(); ReaderWriterLockSlim? _lock; - ConcurrentDictionary? _byName; + ConcurrentDictionary? _byToken; /// /// Initializes a new instance. @@ -54,17 +54,19 @@ public IIkvmReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase me throw new ArgumentException(nameof(method)); var token = method.MetadataToken; - if (token <= 0) + if (token == 0) + throw new InvalidOperationException(); + + // pseudo tokens: since IKVM.Reflection does not remove pseudo tokens after creation, we can keep using these + // but they are non-sequential per-type, so we need to use a real dictionary + if (token < 0) { // we fall back to lookup by name if there is no valid metadata token - if (_byName == null) - Interlocked.CompareExchange(ref _byName, new(), null); - - var context_ = _context; - var module_ = _module; - var type_ = _type; - var method_ = method; - return _byName.GetOrAdd(method.ToString() ?? throw new InvalidOperationException(), _ => CreateMethodBaseSymbol(context_, module_, type_, method_)); + if (_byToken == null) + Interlocked.CompareExchange(ref _byToken, new(), null); + + var value = (_context, _module, _type, method); + return _byToken.GetOrAdd(token, _ => CreateMethodBaseSymbol(value._context, value._module, value._type, value.method)); } // create lock on demand diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs index e1e699c84..806f0cb7c 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs @@ -227,7 +227,12 @@ public virtual CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, /// public virtual CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) { - return ResolveCustomAttribute(UnderlyingModule.__GetCustomAttributes(attributeType.Unpack(), inherit).FirstOrDefault()); + var _attributeType = attributeType.Unpack(); + var a = UnderlyingModule.__GetCustomAttributes(_attributeType, inherit); + if (a.Count > 0) + return ResolveCustomAttribute(a[0]); + + return null; } /// @@ -321,6 +326,9 @@ public IIkvmReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo p #endregion + /// + public override string ToString() => UnderlyingModule.ToString()!; + } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterSymbol.cs index d23d83939..98fb45d39 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterSymbol.cs @@ -93,7 +93,12 @@ public virtual CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, /// public virtual CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) { - return ResolveCustomAttribute(UnderlyingParameter.__GetCustomAttributes(attributeType.Unpack(), inherit).FirstOrDefault()); + var _attributeType = attributeType.Unpack(); + var a = UnderlyingParameter.__GetCustomAttributes(_attributeType, inherit); + if (a.Count > 0) + return ResolveCustomAttribute(a[0]); + + return null; } /// @@ -116,6 +121,9 @@ public ITypeSymbol[] GetRequiredCustomModifiers() #endregion + /// + public override string ToString() => UnderlyingParameter.ToString()!; + } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs index b766fd03e..fb4f446f2 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs @@ -62,7 +62,7 @@ public virtual IIkvmReflectionAssemblySymbolBuilder ResolveAssemblySymbol(Assemb /// [return: NotNullIfNotNull(nameof(assemblies))] - public virtual IIkvmReflectionAssemblySymbol[]? ResolveAssemblySymbols(Assembly[]? assemblies) + public IIkvmReflectionAssemblySymbol[]? ResolveAssemblySymbols(Assembly[]? assemblies) { if (assemblies == null) return null; @@ -96,7 +96,7 @@ public virtual IIkvmReflectionModuleSymbolBuilder ResolveModuleSymbol(ModuleBuil /// [return: NotNullIfNotNull(nameof(modules))] - public virtual IIkvmReflectionModuleSymbol[]? ResolveModuleSymbols(Module[]? modules) + public IIkvmReflectionModuleSymbol[]? ResolveModuleSymbols(Module[]? modules) { if (modules == null) return null; @@ -112,7 +112,7 @@ public virtual IIkvmReflectionModuleSymbolBuilder ResolveModuleSymbol(ModuleBuil } /// - public virtual IEnumerable ResolveModuleSymbols(IEnumerable modules) + public IEnumerable ResolveModuleSymbols(IEnumerable modules) { foreach (var module in modules) if (ResolveModuleSymbol(module) is { } symbol) @@ -140,7 +140,7 @@ public virtual IEnumerable ResolveModuleSymbols(IEn /// [return: NotNullIfNotNull(nameof(members))] - public virtual IIkvmReflectionMemberSymbol[]? ResolveMemberSymbols(MemberInfo[]? members) + public IIkvmReflectionMemberSymbol[]? ResolveMemberSymbols(MemberInfo[]? members) { if (members == null) return null; @@ -174,7 +174,7 @@ public virtual IIkvmReflectionTypeSymbolBuilder ResolveTypeSymbol(TypeBuilder ty /// [return: NotNullIfNotNull(nameof(types))] - public virtual IIkvmReflectionTypeSymbol[]? ResolveTypeSymbols(Type[]? types) + public IIkvmReflectionTypeSymbol[]? ResolveTypeSymbols(Type[]? types) { if (types == null) return null; @@ -228,7 +228,7 @@ public virtual IIkvmReflectionConstructorSymbolBuilder ResolveConstructorSymbol( /// [return: NotNullIfNotNull(nameof(ctors))] - public virtual IIkvmReflectionConstructorSymbol[]? ResolveConstructorSymbols(ConstructorInfo[]? ctors) + public IIkvmReflectionConstructorSymbol[]? ResolveConstructorSymbols(ConstructorInfo[]? ctors) { if (ctors == null) return null; @@ -262,7 +262,7 @@ public virtual IIkvmReflectionMethodSymbolBuilder ResolveMethodSymbol(MethodBuil /// [return: NotNullIfNotNull(nameof(methods))] - public virtual IIkvmReflectionMethodSymbol[]? ResolveMethodSymbols(MethodInfo[]? methods) + public IIkvmReflectionMethodSymbol[]? ResolveMethodSymbols(MethodInfo[]? methods) { if (methods == null) return null; @@ -296,7 +296,7 @@ public virtual IIkvmReflectionFieldSymbolBuilder ResolveFieldSymbol(FieldBuilder /// [return: NotNullIfNotNull(nameof(fields))] - public virtual IIkvmReflectionFieldSymbol[]? ResolveFieldSymbols(FieldInfo[]? fields) + public IIkvmReflectionFieldSymbol[]? ResolveFieldSymbols(FieldInfo[]? fields) { if (fields == null) return null; @@ -330,7 +330,7 @@ public virtual IIkvmReflectionPropertySymbolBuilder ResolvePropertySymbol(Proper /// [return: NotNullIfNotNull(nameof(properties))] - public virtual IIkvmReflectionPropertySymbol[]? ResolvePropertySymbols(PropertyInfo[]? properties) + public IIkvmReflectionPropertySymbol[]? ResolvePropertySymbols(PropertyInfo[]? properties) { if (properties == null) return null; @@ -367,7 +367,7 @@ public virtual IIkvmReflectionPropertySymbolBuilder ResolvePropertySymbol(Proper /// [return: NotNullIfNotNull(nameof(events))] - public virtual IIkvmReflectionEventSymbol[]? ResolveEventSymbols(EventInfo[]? events) + public IIkvmReflectionEventSymbol[]? ResolveEventSymbols(EventInfo[]? events) { if (@events == null) return null; @@ -420,7 +420,7 @@ public virtual IIkvmReflectionPropertySymbolBuilder ResolvePropertySymbol(Proper /// [return: NotNullIfNotNull(nameof(parameters))] - public virtual IIkvmReflectionParameterSymbol[]? ResolveParameterSymbols(ParameterInfo[]? parameters) + public IIkvmReflectionParameterSymbol[]? ResolveParameterSymbols(ParameterInfo[]? parameters) { if (parameters == null) return null; @@ -437,7 +437,7 @@ public virtual IIkvmReflectionPropertySymbolBuilder ResolvePropertySymbol(Proper /// [return: NotNullIfNotNull(nameof(attributes))] - public virtual CustomAttribute[]? ResolveCustomAttributes(IList? attributes) + public CustomAttribute[]? ResolveCustomAttributes(IList? attributes) { if (attributes == null) return null; @@ -453,7 +453,7 @@ public virtual IIkvmReflectionPropertySymbolBuilder ResolvePropertySymbol(Proper } /// - public virtual IEnumerable ResolveCustomAttributes(IEnumerable attributes) + public IEnumerable ResolveCustomAttributes(IEnumerable attributes) { if (attributes is null) throw new ArgumentNullException(nameof(attributes)); @@ -468,7 +468,7 @@ public virtual IEnumerable ResolveCustomAttributes(IEnumerable< /// [return: NotNullIfNotNull(nameof(customAttributeData))] - public virtual CustomAttribute? ResolveCustomAttribute(CustomAttributeData? customAttributeData) + public CustomAttribute? ResolveCustomAttribute(CustomAttributeData? customAttributeData) { if (customAttributeData == null) return null; diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs index 405b59f23..7a984642f 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs @@ -42,7 +42,7 @@ public IkvmReflectionTypeSymbol(IkvmReflectionSymbolContext context, IIkvmReflec public Type UnderlyingType => _type; /// - public override IKVM.Reflection.MemberInfo UnderlyingMember => UnderlyingType; + public override MemberInfo UnderlyingMember => UnderlyingType; #region IIkvmReflectionTypeSymbol diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionUtil.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionUtil.cs index 7239bb3f3..5898b55e8 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionUtil.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionUtil.cs @@ -15,7 +15,7 @@ static class IkvmReflectionUtil { /// - /// Converts a to a . + /// Converts a to a . /// /// /// @@ -25,7 +25,7 @@ public static AssemblyNameInfo Pack(this AssemblyName n) } /// - /// Converts a set of to a set of . + /// Converts a set of to a set of . /// /// /// @@ -58,7 +58,7 @@ public static AssemblyName Unpack(this AssemblyNameInfo n) } /// - /// Converts a set of to a set of . + /// Converts a set of to a set of . /// /// /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionAssemblySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionAssemblySymbolBuilder.cs index 6652e1af1..af8639e04 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionAssemblySymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionAssemblySymbolBuilder.cs @@ -5,7 +5,7 @@ namespace IKVM.CoreLib.Symbols.Reflection.Emit { - interface IReflectionAssemblySymbolBuilder : IReflectionSymbolBuilder, IAssemblySymbolBuilder, IReflectionAssemblySymbol + interface IReflectionAssemblySymbolBuilder : IReflectionSymbolBuilder, IAssemblySymbolBuilder, IReflectionAssemblySymbol { /// @@ -13,6 +13,13 @@ interface IReflectionAssemblySymbolBuilder : IReflectionSymbolBuilder AssemblyBuilder UnderlyingAssemblyBuilder { get; } + /// + /// Gets or creates a for the specified . + /// + /// + /// + IReflectionModuleSymbolBuilder GetOrCreateModuleSymbol(ModuleBuilder module); + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionConstructorSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionConstructorSymbolBuilder.cs index 0572b3bdf..d9a2a0265 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionConstructorSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionConstructorSymbolBuilder.cs @@ -5,9 +5,12 @@ namespace IKVM.CoreLib.Symbols.Reflection.Emit { - interface IReflectionConstructorSymbolBuilder : IReflectionSymbolBuilder, IReflectionMethodBaseSymbolBuilder, IConstructorSymbolBuilder, IReflectionConstructorSymbol + interface IReflectionConstructorSymbolBuilder : IReflectionSymbolBuilder, IReflectionMethodBaseSymbolBuilder, IConstructorSymbolBuilder, IReflectionConstructorSymbol { + /// + /// Gets the underlying . + /// ConstructorBuilder UnderlyingConstructorBuilder { get; } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionEventSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionEventSymbolBuilder.cs index f9c48d0be..d90955a8c 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionEventSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionEventSymbolBuilder.cs @@ -5,9 +5,12 @@ namespace IKVM.CoreLib.Symbols.Reflection.Emit { - interface IReflectionEventSymbolBuilder : IReflectionSymbolBuilder, IReflectionMemberSymbolBuilder, IEventSymbolBuilder, IReflectionEventSymbol + interface IReflectionEventSymbolBuilder : IReflectionSymbolBuilder, IReflectionMemberSymbolBuilder, IEventSymbolBuilder, IReflectionEventSymbol { + /// + /// Gets the underlying . + /// EventBuilder UnderlyingEventBuilder { get; } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionFieldSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionFieldSymbolBuilder.cs index ecd263c1b..6463e8716 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionFieldSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionFieldSymbolBuilder.cs @@ -5,7 +5,7 @@ namespace IKVM.CoreLib.Symbols.Reflection.Emit { - interface IReflectionFieldSymbolBuilder : IReflectionSymbolBuilder, IReflectionMemberSymbolBuilder, IFieldSymbolBuilder, IReflectionFieldSymbol + interface IReflectionFieldSymbolBuilder : IReflectionSymbolBuilder, IReflectionMemberSymbolBuilder, IFieldSymbolBuilder, IReflectionFieldSymbol { FieldBuilder UnderlyingFieldBuilder { get; } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionGenericTypeParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionGenericTypeParameterSymbolBuilder.cs index a9cc7500f..c02f275dd 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionGenericTypeParameterSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionGenericTypeParameterSymbolBuilder.cs @@ -5,7 +5,7 @@ namespace IKVM.CoreLib.Symbols.Reflection.Emit { - interface IReflectionGenericTypeParameterSymbolBuilder : IReflectionSymbolBuilder, IGenericTypeParameterSymbolBuilder, IReflectionTypeSymbol + interface IReflectionGenericTypeParameterSymbolBuilder : IReflectionSymbolBuilder, IGenericTypeParameterSymbolBuilder, IReflectionTypeSymbol { /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionMemberSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionMemberSymbolBuilder.cs index 4eb323b30..f324730eb 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionMemberSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionMemberSymbolBuilder.cs @@ -3,9 +3,14 @@ namespace IKVM.CoreLib.Symbols.Reflection.Emit { - interface IReflectionMemberSymbolBuilder : IReflectionSymbolBuilder, IMemberSymbolBuilder, IReflectionMemberSymbol + interface IReflectionMemberSymbolBuilder : IReflectionSymbolBuilder, IMemberSymbolBuilder, IReflectionMemberSymbol { + /// + /// Gets the resolving . + /// + public IReflectionModuleSymbolBuilder ResolvingModuleBuilder { get; } + /// /// Invoked when the type responsible for this builder is completed. Implementations should update their /// underlying type, and optionally dispatch the OnComplete invocation to downstream elements. diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionMethodBaseSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionMethodBaseSymbolBuilder.cs index 0d757111d..bdc1c996f 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionMethodBaseSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionMethodBaseSymbolBuilder.cs @@ -1,12 +1,19 @@ -using IKVM.CoreLib.Symbols.Emit; +using System.Reflection.Emit; + +using IKVM.CoreLib.Symbols.Emit; namespace IKVM.CoreLib.Symbols.Reflection.Emit { - interface IReflectionMethodBaseSymbolBuilder : IReflectionSymbolBuilder, IReflectionMemberSymbolBuilder, IMethodBaseSymbolBuilder, IReflectionMethodBaseSymbol + interface IReflectionMethodBaseSymbolBuilder : IReflectionSymbolBuilder, IReflectionMemberSymbolBuilder, IMethodBaseSymbolBuilder, IReflectionMethodBaseSymbol { - + /// + /// Gets or creates a for the given . + /// + /// + /// + public IReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionMethodSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionMethodSymbolBuilder.cs index cc19efa3d..76cbe97c5 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionMethodSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionMethodSymbolBuilder.cs @@ -5,7 +5,7 @@ namespace IKVM.CoreLib.Symbols.Reflection.Emit { - interface IReflectionMethodSymbolBuilder : IReflectionSymbolBuilder, IReflectionMethodBaseSymbolBuilder, IMethodSymbolBuilder, IReflectionMethodSymbol + interface IReflectionMethodSymbolBuilder : IReflectionSymbolBuilder, IReflectionMethodBaseSymbolBuilder, IMethodSymbolBuilder, IReflectionMethodSymbol { /// @@ -13,6 +13,13 @@ interface IReflectionMethodSymbolBuilder : IReflectionSymbolBuilder MethodBuilder UnderlyingMethodBuilder { get; } + /// + /// Gets or creates a for the given . + /// + /// + /// + IReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeParameterSymbol(GenericTypeParameterBuilder genericTypeParameter); + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionModuleSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionModuleSymbolBuilder.cs index 9fbd1c7c1..695568f4f 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionModuleSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionModuleSymbolBuilder.cs @@ -5,7 +5,7 @@ namespace IKVM.CoreLib.Symbols.Reflection.Emit { - interface IReflectionModuleSymbolBuilder : IReflectionSymbolBuilder, IModuleSymbolBuilder, IReflectionModuleSymbol + interface IReflectionModuleSymbolBuilder : IReflectionSymbolBuilder, IModuleSymbolBuilder, IReflectionModuleSymbol { /// @@ -13,6 +13,63 @@ interface IReflectionModuleSymbolBuilder : IReflectionSymbolBuilder ModuleBuilder UnderlyingModuleBuilder { get; } + /// + /// Gets or creates a for the specified . + /// + /// + /// + IReflectionTypeSymbolBuilder GetOrCreateTypeSymbol(TypeBuilder type); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + /// + IReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(IReflectionMemberSymbolBuilder member, ParameterBuilder parameter); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeParameterSymbol(GenericTypeParameterBuilder genericTypeParameter); + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionParameterSymbolBuilder.cs index 679ac8429..17f6fb75e 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionParameterSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionParameterSymbolBuilder.cs @@ -5,7 +5,7 @@ namespace IKVM.CoreLib.Symbols.Reflection.Emit { - interface IReflectionParameterSymbolBuilder : IReflectionSymbolBuilder, IParameterSymbolBuilder, IReflectionParameterSymbol + interface IReflectionParameterSymbolBuilder : IReflectionSymbolBuilder, IParameterSymbolBuilder, IReflectionParameterSymbol { /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionPropertySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionPropertySymbolBuilder.cs index 1a10c8c6c..c010b0196 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionPropertySymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionPropertySymbolBuilder.cs @@ -5,11 +5,21 @@ namespace IKVM.CoreLib.Symbols.Reflection.Emit { - interface IReflectionPropertySymbolBuilder : IReflectionSymbolBuilder, IReflectionMemberSymbolBuilder, IPropertySymbolBuilder, IReflectionPropertySymbol + interface IReflectionPropertySymbolBuilder : IReflectionSymbolBuilder, IReflectionMemberSymbolBuilder, IPropertySymbolBuilder, IReflectionPropertySymbol { + /// + /// Gets the underlying . + /// PropertyBuilder UnderlyingPropertyBuilder { get; } + /// + /// Gets or creates a for the given . + /// + /// + /// + public IReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter); + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionSymbolBuilder.cs index 45123999f..b7795a7d3 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionSymbolBuilder.cs @@ -1,4 +1,7 @@ -using IKVM.CoreLib.Symbols.Emit; +using System.Diagnostics.CodeAnalysis; +using System.Reflection.Emit; + +using IKVM.CoreLib.Symbols.Emit; namespace IKVM.CoreLib.Symbols.Reflection.Emit { @@ -6,13 +9,77 @@ namespace IKVM.CoreLib.Symbols.Reflection.Emit interface IReflectionSymbolBuilder : ISymbolBuilder { - } + /// + /// Resolves the symbol for the specified assembly builder. + /// + /// + /// + [return: NotNullIfNotNull(nameof(assembly))] + IReflectionAssemblySymbolBuilder ResolveAssemblySymbol(AssemblyBuilder assembly); - interface IReflectionSymbolBuilder : IReflectionSymbolBuilder, ISymbolBuilder - where TSymbol : IReflectionSymbol - { + /// + /// Resolves the symbol for the specified module. + /// + /// + /// + [return: NotNullIfNotNull(nameof(module))] + IReflectionModuleSymbolBuilder ResolveModuleSymbol(ModuleBuilder module); + + /// + /// Resolves the symbol for the specified type. + /// + /// + /// + [return: NotNullIfNotNull(nameof(type))] + IReflectionTypeSymbolBuilder ResolveTypeSymbol(TypeBuilder type); + + /// + /// Resolves the symbol for the specified constructor. + /// + /// + /// + [return: NotNullIfNotNull(nameof(ctor))] + IReflectionConstructorSymbolBuilder ResolveConstructorSymbol(ConstructorBuilder ctor); + + /// + /// Resolves the symbol for the specified method. + /// + /// + /// + [return: NotNullIfNotNull(nameof(method))] + IReflectionMethodSymbolBuilder ResolveMethodSymbol(MethodBuilder method); + + /// + /// Resolves the symbol for the specified field. + /// + /// + /// + [return: NotNullIfNotNull(nameof(field))] + IReflectionFieldSymbolBuilder ResolveFieldSymbol(FieldBuilder field); + + /// + /// Resolves the symbol for the specified property. + /// + /// + /// + [return: NotNullIfNotNull(nameof(property))] + IReflectionPropertySymbolBuilder ResolvePropertySymbol(PropertyBuilder property); + /// + /// Resolves the symbol for the specified event. + /// + /// + /// + [return: NotNullIfNotNull(nameof(@event))] + IReflectionEventSymbolBuilder ResolveEventSymbol(EventBuilder @event); + /// + /// Resolves the symbol for the specified generic type parameter. + /// + /// + /// + [return: NotNullIfNotNull(nameof(genericTypeParameter))] + IReflectionGenericTypeParameterSymbolBuilder? ResolveGenericTypeParameterSymbol(GenericTypeParameterBuilder genericTypeParameter); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionTypeSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionTypeSymbolBuilder.cs index ee86b9734..d5ed37b22 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionTypeSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionTypeSymbolBuilder.cs @@ -5,7 +5,7 @@ namespace IKVM.CoreLib.Symbols.Reflection.Emit { - interface IReflectionTypeSymbolBuilder : IReflectionSymbolBuilder, IReflectionMemberSymbolBuilder, ITypeSymbolBuilder, IReflectionTypeSymbol + interface IReflectionTypeSymbolBuilder : IReflectionMemberSymbolBuilder, ITypeSymbolBuilder, IReflectionTypeSymbol { /// @@ -13,6 +13,48 @@ interface IReflectionTypeSymbolBuilder : IReflectionSymbolBuilder TypeBuilder UnderlyingTypeBuilder { get; } + /// + /// Gets or creates a for the given . + /// + /// + /// + IReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor); + + /// + /// Gets or creates a for the given . + /// + /// + /// + IReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method); + + /// + /// Gets or creates a for the given . + /// + /// + /// + IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field); + + /// + /// Gets or creates a for the given . + /// + /// + /// + IReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property); + + /// + /// Gets or creates a for the given . + /// + /// + /// + IReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event); + + /// + /// Gets or creates a for the given . + /// + /// + /// + IReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeParameterSymbol(GenericTypeParameterBuilder genericTypeParameter); + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs index b421a94c6..1ae5eba59 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Collections.Immutable; using System.IO; using System.Linq; using System.Reflection; @@ -15,7 +14,8 @@ class ReflectionAssemblySymbolBuilder : ReflectionSymbolBuilder, IReflectionAsse { readonly AssemblyBuilder _builder; - ReflectionAssemblyMetadata _metadata; + + ReflectionModuleTable _moduleTable; /// /// Initializes a new instance. @@ -26,7 +26,7 @@ public ReflectionAssemblySymbolBuilder(ReflectionSymbolContext context, Assembly base(context) { _builder = builder ?? throw new ArgumentNullException(nameof(builder)); - _metadata = new ReflectionAssemblyMetadata(this); + _moduleTable = new ReflectionModuleTable(context, this); } /// @@ -35,6 +35,26 @@ public ReflectionAssemblySymbolBuilder(ReflectionSymbolContext context, Assembly /// public AssemblyBuilder UnderlyingAssemblyBuilder => _builder; + #region IReflectionAssemblySymbolBuilder + + /// + public IReflectionModuleSymbolBuilder GetOrCreateModuleSymbol(ModuleBuilder module) + { + return _moduleTable.GetOrCreateModuleSymbol(module); + } + + #endregion + + #region IReflectionAssemblySymbol + + /// + public IReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) + { + return _moduleTable.GetOrCreateModuleSymbol(module); + } + + #endregion + #region IAssemblySymbolBuilder /// @@ -66,23 +86,13 @@ public IModuleSymbolBuilder DefineModule(string name, string fileName, bool emit /// public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) { - _builder.SetCustomAttribute(con.Unpack(), binaryAttribute); + UnderlyingAssemblyBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); } /// public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) { - _builder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); - } - - public void SetEntryPoint(IMethodSymbolBuilder mainMethodProxy) - { - throw new NotImplementedException(); - } - - public void SetEntryPoint(IMethodSymbolBuilder mainMethodProxy, Symbols.Emit.PEFileKinds target) - { - throw new NotImplementedException(); + UnderlyingAssemblyBuilder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); } /// @@ -107,6 +117,18 @@ public void DefineVersionInfoResource() #endif } + /// + public void SetEntryPoint(IMethodSymbolBuilder mainMethodProxy) + { + throw new NotImplementedException(); + } + + /// + public void SetEntryPoint(IMethodSymbolBuilder mainMethodProxy, IKVM.CoreLib.Symbols.Emit.PEFileKinds target) + { + throw new NotImplementedException(); + } + /// public void AddTypeForwarder(ITypeSymbol type) { @@ -124,7 +146,7 @@ public void AddResourceFile(string name, string fileName) } /// - public void Save(string assemblyFileName, PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine) + public void Save(string assemblyFileName, System.Reflection.PortableExecutableKinds portableExecutableKind, IKVM.CoreLib.Symbols.ImageFileMachine imageFileMachine) { #if NETFRAMEWORK UnderlyingAssemblyBuilder.Save(assemblyFileName, portableExecutableKind, (System.Reflection.ImageFileMachine)imageFileMachine); @@ -190,24 +212,13 @@ public IModuleSymbol[] GetModules(bool getResourceModules) /// public AssemblyNameInfo GetName() { - return ToAssemblyName(UnderlyingAssembly.GetName()); + return UnderlyingAssembly.GetName().Pack(); } /// public AssemblyNameInfo[] GetReferencedAssemblies() { - return UnderlyingAssembly.GetReferencedAssemblies().Select(i => ToAssemblyName(i)).ToArray(); - } - - /// - /// Transforms the to a . - /// - /// - /// - /// - AssemblyNameInfo ToAssemblyName(AssemblyName n) - { - return new AssemblyNameInfo(n.Name ?? throw new InvalidOperationException(), n.Version, n.CultureName, n.Flags, n.GetPublicKeyToken()?.ToImmutableArray() ?? []); + return UnderlyingAssembly.GetReferencedAssemblies().Pack(); } /// @@ -250,7 +261,8 @@ public CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inh /// public CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) { - return GetCustomAttributes(attributeType, inherit).FirstOrDefault(); + var _attributeType = attributeType.Unpack(); + return ResolveCustomAttribute(UnderlyingAssembly.GetCustomAttributesData().Where(i => i.AttributeType == _attributeType).FirstOrDefault()); } /// @@ -279,17 +291,6 @@ public bool IsDefined(ITypeSymbol attributeType, bool inherit = false) #endregion - /// - public IReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) - { - return _metadata.GetOrCreateModuleSymbol(module); - } - - /// - public IReflectionModuleSymbolBuilder GetOrCreateModuleSymbol(ModuleBuilder module) - { - return (IReflectionModuleSymbolBuilder)_metadata.GetOrCreateModuleSymbol(module); - } } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionConstructorSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionConstructorSymbolBuilder.cs index a80569f59..ba6d7c8b8 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionConstructorSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionConstructorSymbolBuilder.cs @@ -23,7 +23,7 @@ class ReflectionConstructorSymbolBuilder : ReflectionMethodBaseSymbolBuilder, IR /// /// /// - public ReflectionConstructorSymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol resolvingType, ConstructorBuilder builder) : + public ReflectionConstructorSymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbolBuilder resolvingModule, IReflectionTypeSymbolBuilder resolvingType, ConstructorBuilder builder) : base(context, resolvingModule, resolvingType) { _builder = builder ?? throw new ArgumentNullException(nameof(builder)); @@ -39,7 +39,7 @@ public ReflectionConstructorSymbolBuilder(ReflectionSymbolContext context, IRefl /// public ConstructorBuilder UnderlyingConstructorBuilder => _builder ?? throw new InvalidOperationException(); - #region IMethodBaseSymbolBuilder + #region IConstructorSymbolBuilder /// public override void SetImplementationFlags(MethodImplAttributes attributes) @@ -50,7 +50,10 @@ public override void SetImplementationFlags(MethodImplAttributes attributes) /// public override IParameterSymbolBuilder DefineParameter(int iSequence, ParameterAttributes attributes, string? strParamName) { - return ResolveParameterSymbol(UnderlyingConstructorBuilder.DefineParameter(iSequence, attributes, strParamName)); + if (iSequence <= 0) + throw new ArgumentOutOfRangeException(nameof(iSequence)); + + return ResolveParameterSymbol(this, UnderlyingConstructorBuilder.DefineParameter(iSequence, attributes, strParamName)); } /// @@ -79,10 +82,6 @@ public override void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAtt #endregion - #region IConstructorSymbolBuilder - - #endregion - #region IConstructorSymbol /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionEventSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionEventSymbolBuilder.cs index d583458d9..024141801 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionEventSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionEventSymbolBuilder.cs @@ -21,7 +21,7 @@ class ReflectionEventSymbolBuilder : ReflectionMemberSymbolBuilder, IReflectionE /// /// /// - public ReflectionEventSymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol resolvingType, EventBuilder builder) : + public ReflectionEventSymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbolBuilder resolvingModule, IReflectionTypeSymbolBuilder resolvingType, EventBuilder builder) : base(context, resolvingModule, resolvingType) { _builder = builder ?? throw new ArgumentNullException(nameof(builder)); @@ -80,7 +80,7 @@ public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) #region IEventSymbol /// - public EventAttributes Attributes => UnderlyingEvent.Attributes; + public System.Reflection.EventAttributes Attributes => UnderlyingEvent.Attributes; /// public ITypeSymbol? EventHandlerType => ResolveTypeSymbol(UnderlyingEvent.EventHandlerType); diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionFieldSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionFieldSymbolBuilder.cs index 5aa337c85..1c96e8bd8 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionFieldSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionFieldSymbolBuilder.cs @@ -21,7 +21,7 @@ class ReflectionFieldSymbolBuilder : ReflectionMemberSymbolBuilder, IReflectionF /// /// /// - public ReflectionFieldSymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol? resolvingType, FieldBuilder builder) : + public ReflectionFieldSymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbolBuilder resolvingModule, IReflectionTypeSymbolBuilder? resolvingType, FieldBuilder builder) : base(context, resolvingModule, resolvingType) { _builder = builder ?? throw new ArgumentNullException(nameof(builder)); @@ -94,10 +94,8 @@ public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) /// public bool IsLiteral => UnderlyingField.IsLiteral; -#pragma warning disable SYSLIB0050 // Type or member is obsolete /// public bool IsNotSerialized => UnderlyingField.IsNotSerialized; -#pragma warning restore SYSLIB0050 // Type or member is obsolete /// public bool IsPinvokeImpl => UnderlyingField.IsPinvokeImpl; diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionGenericTypeParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionGenericTypeParameterSymbolBuilder.cs index 2ea570755..17651ec77 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionGenericTypeParameterSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionGenericTypeParameterSymbolBuilder.cs @@ -2,7 +2,7 @@ using System.Reflection; using System.Reflection.Emit; -using IKVM.CoreLib.Symbols.Emit; +using IKVM.CoreLib.Reflection; namespace IKVM.CoreLib.Symbols.Reflection.Emit { @@ -10,28 +10,28 @@ namespace IKVM.CoreLib.Symbols.Reflection.Emit class ReflectionGenericTypeParameterSymbolBuilder : ReflectionMemberSymbolBuilder, IReflectionGenericTypeParameterSymbolBuilder { - readonly IReflectionMethodSymbol? _resolvingMethod; + readonly IReflectionMemberSymbol? _resolvingMember; GenericTypeParameterBuilder? _builder; Type _type; - ReflectionTypeImpl _impl; + + ReflectionTypeSpecTable _specTable; /// /// Initializes a new instance. /// /// /// - /// - /// + /// /// /// - public ReflectionGenericTypeParameterSymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol? resolvingType, IReflectionMethodSymbol? resolvingMethod, GenericTypeParameterBuilder builder) : - base(context, resolvingModule, resolvingType) + public ReflectionGenericTypeParameterSymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbolBuilder resolvingModule, IReflectionMemberSymbolBuilder resolvingMember, GenericTypeParameterBuilder builder) : + base(context, resolvingModule, resolvingMember as IReflectionTypeSymbolBuilder) { - _resolvingMethod = resolvingMethod; + _resolvingMember = resolvingMember ?? throw new ArgumentNullException(nameof(resolvingMember)); _builder = builder ?? throw new ArgumentNullException(nameof(builder)); _type = _builder; - _impl = new ReflectionTypeImpl(this); + _specTable = new ReflectionTypeSpecTable(); } /// @@ -40,9 +40,125 @@ public ReflectionGenericTypeParameterSymbolBuilder(ReflectionSymbolContext conte /// public override MemberInfo UnderlyingMember => UnderlyingType; + #region IReflectionGenericTypeParameterSymbolBuilder + /// public GenericTypeParameterBuilder UnderlyingGenericTypeParameterBuilder => _builder ?? throw new InvalidOperationException(); + #endregion + + #region IReflectionTypeSymbol + + /// + public IReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method) + { + throw new NotSupportedException(); + } + + /// + public IReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) + { + throw new NotSupportedException(); + } + + /// + public IReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor) + { + throw new NotSupportedException(); + } + + /// + public IReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) + { + throw new NotSupportedException(); + } + + /// + public IReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method) + { + throw new NotSupportedException(); + } + + /// + public IReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) + { + throw new NotSupportedException(); + } + + /// + public IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field) + { + throw new NotSupportedException(); + } + + /// + public IReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) + { + throw new NotSupportedException(); + } + + /// + public IReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property) + { + throw new NotSupportedException(); + } + + /// + public IReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) + { + throw new NotSupportedException(); + } + + /// + public IReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event) + { + throw new NotSupportedException(); + } + + /// + public IReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type type) + { + throw new NotSupportedException(); + } + + /// + public IReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeSymbol(GenericTypeParameterBuilder genericType) + { + throw new NotSupportedException(); + } + + /// + public IReflectionTypeSymbol GetOrCreateSZArrayTypeSymbol() + { + return _specTable.GetOrCreateSZArrayTypeSymbol(); + } + + /// + public IReflectionTypeSymbol GetOrCreateArrayTypeSymbol(int rank) + { + return _specTable.GetOrCreateArrayTypeSymbol(rank); + } + + /// + public IReflectionTypeSymbol GetOrCreatePointerTypeSymbol() + { + return _specTable.GetOrCreatePointerTypeSymbol(); + } + + /// + public IReflectionTypeSymbol GetOrCreateByRefTypeSymbol() + { + return _specTable.GetOrCreateByRefTypeSymbol(); + } + + /// + public IReflectionTypeSymbol GetOrCreateGenericTypeSymbol(Type[] genericTypeDefinition) + { + return _specTable.GetOrCreateGenericTypeSymbol(genericTypeDefinition); + } + + #endregion + #region ITypeSymbolBuilder /// @@ -52,9 +168,9 @@ public void SetBaseTypeConstraint(ITypeSymbol? baseTypeConstraint) } /// - public void SetGenericParameterAttributes(GenericParameterAttributes genericParameterAttributes) + public void SetGenericParameterAttributes(System.Reflection.GenericParameterAttributes genericParameterAttributes) { - UnderlyingGenericTypeParameterBuilder.SetGenericParameterAttributes(genericParameterAttributes); + UnderlyingGenericTypeParameterBuilder.SetGenericParameterAttributes((GenericParameterAttributes)genericParameterAttributes); } /// @@ -68,506 +184,525 @@ public void SetInterfaceConstraints(params ITypeSymbol[]? interfaceConstraints) #region ITypeSymbol /// - public TypeAttributes Attributes => _impl.Attributes; + public IAssemblySymbol Assembly => ResolveAssemblySymbol(UnderlyingType.Assembly); + + /// + public string? AssemblyQualifiedName => UnderlyingType.AssemblyQualifiedName; /// - public IAssemblySymbol Assembly => _impl.Assembly; + public System.Reflection.TypeAttributes Attributes => (System.Reflection.TypeAttributes)UnderlyingType.Attributes; /// - public IMethodBaseSymbol? DeclaringMethod => _impl.DeclaringMethod; + public ITypeSymbol? BaseType => ResolveTypeSymbol(UnderlyingType.BaseType); /// - public string? AssemblyQualifiedName => _impl.AssemblyQualifiedName; + public bool ContainsGenericParameters => UnderlyingType.ContainsGenericParameters; /// - public string? FullName => _impl.FullName; + public IMethodBaseSymbol? DeclaringMethod => ResolveMethodBaseSymbol(UnderlyingType.DeclaringMethod); /// - public string? Namespace => _impl.Namespace; + public string? FullName => UnderlyingType.FullName; /// - public TypeCode TypeCode => _impl.TypeCode; + public string? Namespace => UnderlyingType.Namespace; /// - public ITypeSymbol? BaseType => _impl.BaseType; + public System.Reflection.GenericParameterAttributes GenericParameterAttributes => (System.Reflection.GenericParameterAttributes)UnderlyingType.GenericParameterAttributes; /// - public bool ContainsGenericParameters => _impl.ContainsGenericParameters; + public int GenericParameterPosition => UnderlyingType.GenericParameterPosition; /// - public GenericParameterAttributes GenericParameterAttributes => _impl.GenericParameterAttributes; + public ITypeSymbol[] GenericTypeArguments => ResolveTypeSymbols(UnderlyingType.GenericTypeArguments); /// - public int GenericParameterPosition => _impl.GenericParameterPosition; + public bool HasElementType => UnderlyingType.HasElementType; /// - public ITypeSymbol[] GenericTypeArguments => _impl.GenericTypeArguments; + public TypeCode TypeCode => Type.GetTypeCode(UnderlyingType); /// - public bool IsConstructedGenericType => _impl.IsConstructedGenericType; + public bool IsAbstract => UnderlyingType.IsAbstract; /// - public bool IsGenericType => _impl.IsGenericType; + public bool IsSZArray => UnderlyingType.IsSZArray(); /// - public bool IsGenericTypeDefinition => _impl.IsGenericTypeDefinition; + public bool IsArray => UnderlyingType.IsArray; /// - public bool IsGenericParameter => _impl.IsGenericParameter; + public bool IsAutoLayout => UnderlyingType.IsAutoLayout; /// - public bool IsAutoLayout => _impl.IsAutoLayout; + public bool IsExplicitLayout => UnderlyingType.IsExplicitLayout; /// - public bool IsExplicitLayout => _impl.IsExplicitLayout; + public bool IsByRef => UnderlyingType.IsByRef; /// - public bool IsLayoutSequential => _impl.IsLayoutSequential; + public bool IsClass => UnderlyingType.IsClass; /// - public bool HasElementType => _impl.HasElementType; + public bool IsEnum => UnderlyingType.IsEnum; /// - public bool IsClass => _impl.IsClass; + public bool IsInterface => UnderlyingType.IsInterface; /// - public bool IsValueType => _impl.IsValueType; + public bool IsConstructedGenericType => UnderlyingType.IsConstructedGenericType; /// - public bool IsInterface => _impl.IsInterface; + public bool IsGenericParameter => UnderlyingType.IsGenericParameter; /// - public bool IsPrimitive => _impl.IsPrimitive; + public bool IsGenericType => UnderlyingType.IsGenericType; /// - public bool IsSZArray => _impl.IsSZArray; + public bool IsGenericTypeDefinition => UnderlyingType.IsGenericTypeDefinition; /// - public bool IsArray => _impl.IsArray; + public bool IsLayoutSequential => UnderlyingType.IsLayoutSequential; /// - public bool IsEnum => _impl.IsEnum; + public bool IsNested => UnderlyingType.IsNested; /// - public bool IsPointer => _impl.IsPointer; + public bool IsNestedAssembly => UnderlyingType.IsNestedAssembly; /// - public bool IsFunctionPointer => _impl.IsFunctionPointer; + public bool IsNestedFamANDAssem => UnderlyingType.IsNestedFamANDAssem; /// - public bool IsUnmanagedFunctionPointer => _impl.IsUnmanagedFunctionPointer; + public bool IsNestedFamORAssem => UnderlyingType.IsNestedFamORAssem; /// - public bool IsByRef => _impl.IsByRef; + public bool IsNestedFamily => UnderlyingType.IsNestedFamily; /// - public bool IsAbstract => _impl.IsAbstract; + public bool IsNestedPrivate => UnderlyingType.IsNestedPrivate; /// - public bool IsSealed => _impl.IsSealed; + public bool IsNestedPublic => UnderlyingType.IsNestedPublic; /// - public bool IsVisible => _impl.IsVisible; + public bool IsNotPublic => UnderlyingType.IsNotPublic; /// - public bool IsPublic => _impl.IsPublic; + public bool IsPointer => UnderlyingType.IsPointer; + +#if NET8_0_OR_GREATER /// - public bool IsNotPublic => _impl.IsNotPublic; + public bool IsFunctionPointer => UnderlyingType.IsFunctionPointer; /// - public bool IsNested => _impl.IsNested; + public bool IsUnmanagedFunctionPointer => UnderlyingType.IsUnmanagedFunctionPointer; + +#else /// - public bool IsNestedAssembly => _impl.IsNestedAssembly; + public bool IsFunctionPointer => throw new NotImplementedException(); /// - public bool IsNestedFamANDAssem => _impl.IsNestedFamANDAssem; + public bool IsUnmanagedFunctionPointer => throw new NotImplementedException(); + +#endif /// - public bool IsNestedFamily => _impl.IsNestedFamily; + public bool IsPrimitive => UnderlyingType.IsPrimitive; /// - public bool IsNestedFamORAssem => _impl.IsNestedFamORAssem; + public bool IsPublic => UnderlyingType.IsPublic; /// - public bool IsNestedPrivate => _impl.IsNestedPrivate; + public bool IsSealed => UnderlyingType.IsSealed; /// - public bool IsNestedPublic => _impl.IsNestedPublic; + public bool IsSerializable => UnderlyingType.IsSerializable; /// - public bool IsSerializable => _impl.IsSerializable; + public bool IsValueType => UnderlyingType.IsValueType; /// - public bool IsSignatureType => _impl.IsSignatureType; + public bool IsVisible => UnderlyingType.IsVisible; /// - public bool IsSpecialName => _impl.IsSpecialName; + public bool IsSignatureType => throw new NotImplementedException(); /// - public IConstructorSymbol? TypeInitializer => _impl.TypeInitializer; + public bool IsSpecialName => UnderlyingType.IsSpecialName; /// - public override bool IsComplete => _builder == null; + public IConstructorSymbol? TypeInitializer => ResolveConstructorSymbol(UnderlyingType.TypeInitializer); /// public int GetArrayRank() { - return _impl.GetArrayRank(); + return UnderlyingType.GetArrayRank(); } /// - public IMemberSymbol[] GetDefaultMembers() + public IConstructorSymbol? GetConstructor(System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) { - return _impl.GetDefaultMembers(); + return ResolveConstructorSymbol(UnderlyingType.GetConstructor((BindingFlags)bindingAttr, binder: null, types.Unpack(), modifiers: null)); } /// - public ITypeSymbol? GetElementType() + public IConstructorSymbol? GetConstructor(ITypeSymbol[] types) { - return _impl.GetElementType(); + return ResolveConstructorSymbol(UnderlyingType.GetConstructor(types.Unpack())); } /// - public string? GetEnumName(object value) + public IConstructorSymbol[] GetConstructors() { - return _impl.GetEnumName(value); + return ResolveConstructorSymbols(UnderlyingType.GetConstructors()); } /// - public string[] GetEnumNames() + public IConstructorSymbol[] GetConstructors(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetEnumNames(); + return ResolveConstructorSymbols(UnderlyingType.GetConstructors((BindingFlags)bindingAttr)); } /// - public ITypeSymbol GetEnumUnderlyingType() + public IMemberSymbol[] GetDefaultMembers() { - return _impl.GetEnumUnderlyingType(); + return ResolveMemberSymbols(UnderlyingType.GetDefaultMembers()); } /// - public ITypeSymbol[] GetGenericArguments() + public ITypeSymbol? GetElementType() { - return _impl.GetGenericArguments(); + return ResolveTypeSymbol(UnderlyingType.GetElementType()); } /// - public ITypeSymbol[] GetGenericParameterConstraints() + public string? GetEnumName(object value) { - return _impl.GetGenericParameterConstraints(); + return UnderlyingType.GetEnumName(value); } /// - public ITypeSymbol GetGenericTypeDefinition() + public string[] GetEnumNames() { - return _impl.GetGenericTypeDefinition(); + return UnderlyingType.GetEnumNames(); } /// - public ITypeSymbol? GetInterface(string name) + public ITypeSymbol GetEnumUnderlyingType() { - return _impl.GetInterface(name); + return ResolveTypeSymbol(UnderlyingType.GetEnumUnderlyingType()); } /// - public ITypeSymbol? GetInterface(string name, bool ignoreCase) + public Array GetEnumValues() { - return _impl.GetInterface(name, ignoreCase); + return UnderlyingType.GetEnumValues(); } /// - public ITypeSymbol[] GetInterfaces(bool inherit = true) + public IEventSymbol? GetEvent(string name) { - return _impl.GetInterfaces(inherit); + return ResolveEventSymbol(UnderlyingType.GetEvent(name)); } /// - public InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) + public IEventSymbol? GetEvent(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetInterfaceMap(interfaceType); + return ResolveEventSymbol(UnderlyingType.GetEvent(name, (BindingFlags)bindingAttr)); } /// - public IMemberSymbol[] GetMember(string name) + public IEventSymbol[] GetEvents() { - return _impl.GetMember(name); + return ResolveEventSymbols(UnderlyingType.GetEvents()); } /// - public IMemberSymbol[] GetMember(string name, BindingFlags bindingAttr) + public IEventSymbol[] GetEvents(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMember(name, bindingAttr); + return ResolveEventSymbols(UnderlyingType.GetEvents((BindingFlags)bindingAttr)); } /// - public IMemberSymbol[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) + public IFieldSymbol? GetField(string name) { - return _impl.GetMember(name, type, bindingAttr); + return ResolveFieldSymbol(UnderlyingType.GetField(name)); } /// - public IMemberSymbol[] GetMembers() + public IFieldSymbol? GetField(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMembers(); + return ResolveFieldSymbol(UnderlyingType.GetField(name, (BindingFlags)bindingAttr)); } /// - public IMemberSymbol[] GetMembers(BindingFlags bindingAttr) + public IFieldSymbol[] GetFields() { - return _impl.GetMembers(bindingAttr); + return ResolveFieldSymbols(UnderlyingType.GetFields()); } - public IConstructorSymbol? GetConstructor(ITypeSymbol[] types) + /// + public IFieldSymbol[] GetFields(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetConstructor(types); + return ResolveFieldSymbols(UnderlyingType.GetFields((BindingFlags)bindingAttr)); } /// - public IConstructorSymbol? GetConstructor(BindingFlags bindingAttr, ITypeSymbol[] types) + public ITypeSymbol[] GetGenericArguments() { - return _impl.GetConstructor(bindingAttr, types); + return ResolveTypeSymbols(UnderlyingType.GetGenericArguments()); } /// - public IConstructorSymbol[] GetConstructors() + public ITypeSymbol[] GetGenericParameterConstraints() { - return _impl.GetConstructors(); + return ResolveTypeSymbols(UnderlyingType.GetGenericParameterConstraints()); } /// - public IConstructorSymbol[] GetConstructors(BindingFlags bindingAttr) + public ITypeSymbol GetGenericTypeDefinition() { - return _impl.GetConstructors(bindingAttr); + return ResolveTypeSymbol(UnderlyingType.GetGenericTypeDefinition()); } /// - public IFieldSymbol? GetField(string name) + public ITypeSymbol? GetInterface(string name) { - return _impl.GetField(name); + return ResolveTypeSymbol(UnderlyingType.GetInterface(name)); } /// - public IFieldSymbol? GetField(string name, BindingFlags bindingAttr) + public ITypeSymbol? GetInterface(string name, bool ignoreCase) { - return _impl.GetField(name, bindingAttr); + return ResolveTypeSymbol(UnderlyingType.GetInterface(name, ignoreCase)); } /// - public IFieldSymbol[] GetFields() + public InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) { - return _impl.GetFields(); + return ResolveInterfaceMapping(UnderlyingType.GetInterfaceMap(interfaceType.Unpack())); } /// - public IFieldSymbol[] GetFields(BindingFlags bindingAttr) + public ITypeSymbol[] GetInterfaces(bool inherit = true) { - return _impl.GetFields(bindingAttr); + if (inherit) + return ResolveTypeSymbols(UnderlyingType.GetInterfaces()); + else + throw new NotImplementedException(); } /// - public IMethodSymbol? GetMethod(string name) + public IMemberSymbol[] GetMember(string name) { - return _impl.GetMethod(name); + return ResolveMemberSymbols(UnderlyingType.GetMember(name)); } /// - public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) + public IMemberSymbol[] GetMember(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMethod(name, types); + return ResolveMemberSymbols(UnderlyingType.GetMember(name, (BindingFlags)bindingAttr)); } /// - public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr) + public IMemberSymbol[] GetMember(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMethod(name, bindingAttr); + return ResolveMemberSymbols(UnderlyingType.GetMember(name, (MemberTypes)type, (BindingFlags)bindingAttr)); } /// - public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types) + public IMemberSymbol[] GetMembers(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMethod(name, bindingAttr, types); + return ResolveMemberSymbols(UnderlyingType.GetMembers((BindingFlags)bindingAttr)); } /// - public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers) + public IMemberSymbol[] GetMembers() { - return _impl.GetMethod(name, bindingAttr, callConvention, types, modifiers); + return ResolveMemberSymbols(UnderlyingType.GetMembers()); } /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMethod(name, genericParameterCount, bindingAttr, callConvention, types, modifiers); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr)); } /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, ITypeSymbol[] types, ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) { - return _impl.GetMethod(name, genericParameterCount, bindingAttr, types, modifiers); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, types.Unpack())); } /// - public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types, ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) { - return _impl.GetMethod(name, bindingAttr, types, modifiers); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), null)); } /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name) { - return _impl.GetMethod(name, genericParameterCount, types, modifiers); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name)); } /// - public IMethodSymbol[] GetMethods() + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return _impl.GetMethods(); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, (CallingConventions)callConvention, types.Unpack(), modifiers?.Unpack())); } /// - public IMethodSymbol[] GetMethods(BindingFlags bindingAttr) + public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return _impl.GetMethods(bindingAttr); + throw new NotImplementedException(); } /// - public IPropertySymbol? GetProperty(string name) + public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return _impl.GetProperty(name); + throw new NotImplementedException(); } /// - public IPropertySymbol? GetProperty(string name, BindingFlags bindingAttr) + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return _impl.GetProperty(name, bindingAttr); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), modifiers?.Unpack())); } /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol[] types) + public IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return _impl.GetProperty(name, types); + throw new NotImplementedException(); } /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types) + public IMethodSymbol[] GetMethods(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetProperty(name, returnType, types); + return ResolveMethodSymbols(UnderlyingType.GetMethods((BindingFlags)bindingAttr)); } /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) + public IMethodSymbol[] GetMethods() { - return _impl.GetProperty(name, returnType); + return ResolveMethodSymbols(UnderlyingType.GetMethods()); } /// - public IPropertySymbol[] GetProperties() + public ITypeSymbol? GetNestedType(string name) { - return _impl.GetProperties(); + return ResolveTypeSymbol(UnderlyingType.GetNestedType(name)); } /// - public IPropertySymbol[] GetProperties(BindingFlags bindingAttr) + public ITypeSymbol? GetNestedType(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetProperties(bindingAttr); + return ResolveTypeSymbol(UnderlyingType.GetNestedType(name, (BindingFlags)bindingAttr)); } /// - public IEventSymbol? GetEvent(string name) + public ITypeSymbol[] GetNestedTypes() { - return _impl.GetEvent(name); + return ResolveTypeSymbols(UnderlyingType.GetNestedTypes()); } /// - public IEventSymbol? GetEvent(string name, BindingFlags bindingAttr) + public ITypeSymbol[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetEvent(name, bindingAttr); + return ResolveTypeSymbols(UnderlyingType.GetNestedTypes((BindingFlags)bindingAttr)); } /// - public IEventSymbol[] GetEvents() + public IPropertySymbol[] GetProperties() { - return _impl.GetEvents(); + return ResolvePropertySymbols(UnderlyingType.GetProperties()); } /// - public IEventSymbol[] GetEvents(BindingFlags bindingAttr) + public IPropertySymbol[] GetProperties(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetEvents(bindingAttr); + return ResolvePropertySymbols(UnderlyingType.GetProperties((BindingFlags)bindingAttr)); } /// - public ITypeSymbol? GetNestedType(string name) + public IPropertySymbol? GetProperty(string name, ITypeSymbol[] types) { - return _impl.GetNestedType(name); + return ResolvePropertySymbol(UnderlyingType.GetProperty(name, types.Unpack())); } /// - public ITypeSymbol? GetNestedType(string name, BindingFlags bindingAttr) + public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types) { - return _impl.GetNestedType(name, bindingAttr); + return ResolvePropertySymbol(UnderlyingType.GetProperty(name, returnType?.Unpack(), types.Unpack())); } /// - public ITypeSymbol[] GetNestedTypes() + public IPropertySymbol? GetProperty(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetNestedTypes(); + return ResolvePropertySymbol(UnderlyingType.GetProperty(name, (BindingFlags)bindingAttr)); } /// - public ITypeSymbol[] GetNestedTypes(BindingFlags bindingAttr) + public IPropertySymbol? GetProperty(string name) { - return _impl.GetNestedTypes(); + return ResolvePropertySymbol(UnderlyingType.GetProperty(name)); } /// - public bool IsAssignableFrom(ITypeSymbol? c) + public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) { - return _impl.IsAssignableFrom(c); + return ResolvePropertySymbol(UnderlyingType.GetProperty(name, returnType?.Unpack())); } /// - public bool IsSubclassOf(ITypeSymbol c) + public bool IsAssignableFrom(ITypeSymbol? c) { - return _impl.IsSubclassOf(c); + return UnderlyingType.IsAssignableFrom(c?.Unpack()); } /// public bool IsEnumDefined(object value) { - return _impl.IsEnumDefined(value); + return UnderlyingType.IsEnumDefined(value); + } + + /// + public bool IsSubclassOf(ITypeSymbol c) + { + return UnderlyingType.IsSubclassOf(c.Unpack()); } /// public ITypeSymbol MakeArrayType() { - return _impl.MakeArrayType(); + return ResolveTypeSymbol(UnderlyingType.MakeArrayType()); } /// public ITypeSymbol MakeArrayType(int rank) { - return _impl.MakeArrayType(rank); + return ResolveTypeSymbol(UnderlyingType.MakeArrayType(rank)); } /// - public ITypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments) + public ITypeSymbol MakeByRefType() { - return _impl.MakeGenericType(typeArguments); + return ResolveTypeSymbol(UnderlyingType.MakeByRefType()); } /// public ITypeSymbol MakePointerType() { - return _impl.MakePointerType(); + return ResolveTypeSymbol(UnderlyingType.MakePointerType()); } /// - public ITypeSymbol MakeByRefType() + public ITypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments) { - return _impl.MakeByRefType(); + return ResolveTypeSymbol(UnderlyingType.MakeGenericType(typeArguments.Unpack())); } #endregion @@ -575,7 +710,7 @@ public ITypeSymbol MakeByRefType() /// public override void OnComplete() { - throw new NotImplementedException(); + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMemberSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMemberSymbolBuilder.cs index 872761376..d3c13c205 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMemberSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMemberSymbolBuilder.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reflection; @@ -13,39 +12,8 @@ namespace IKVM.CoreLib.Symbols.Reflection.Emit abstract class ReflectionMemberSymbolBuilder : ReflectionSymbolBuilder, IReflectionMemberSymbolBuilder { - /// - /// Concatinates the list of arrays. - /// - /// - /// - static T[] Concat(List? list) - { - if (list == null) - return []; - - var c = 0; - foreach (var i in list) - c += i.Length; - - if (c == 0) - return []; - - var t = 0; - var a = new T[c]; - foreach (var i in list) - { - Array.Copy(i, 0, a, t, i.Length); - t += i.Length; - } - - return a; - } - - readonly IReflectionModuleSymbol _resolvingModule; - readonly IReflectionTypeSymbol? _resolvingType; - - CustomAttribute[]? _customAttributes; - CustomAttribute[]? _inheritedCustomAttributes; + readonly IReflectionModuleSymbolBuilder _resolvingModule; + readonly IReflectionTypeSymbolBuilder? _resolvingType; /// /// Initializes a new instance. @@ -53,14 +21,14 @@ static T[] Concat(List? list) /// /// /// - public ReflectionMemberSymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol? resolvingType) : + public ReflectionMemberSymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbolBuilder resolvingModule, IReflectionTypeSymbolBuilder? resolvingType) : base(context) { _resolvingModule = resolvingModule ?? throw new ArgumentNullException(nameof(resolvingModule)); _resolvingType = resolvingType; } - #region IMemberSymbol + #region IReflectionMemberSymbol /// public abstract MemberInfo UnderlyingMember { get; } @@ -69,128 +37,153 @@ public ReflectionMemberSymbolBuilder(ReflectionSymbolContext context, IReflectio public IReflectionModuleSymbol ResolvingModule => _resolvingModule; /// - public IReflectionTypeSymbol? ResolvingType => ResolvingType; + public IReflectionModuleSymbolBuilder ResolvingModuleBuilder => _resolvingModule; /// - public virtual IModuleSymbol Module => ResolveModuleSymbol(UnderlyingMember.Module)!; + public IReflectionTypeSymbol? ResolvingType => _resolvingType; - /// - public virtual ITypeSymbol? DeclaringType => ResolveTypeSymbol(UnderlyingMember.DeclaringType)!; + #endregion - /// - public virtual MemberTypes MemberType => UnderlyingMember.MemberType; + #region IReflectionSymbolBuilder /// - public virtual int MetadataToken => UnderlyingMember.GetMetadataTokenSafe(); + [return: NotNullIfNotNull("type")] + public override IReflectionTypeSymbolBuilder ResolveTypeSymbol(TypeBuilder type) + { + if (type is null) + throw new ArgumentNullException(nameof(type)); - /// - public virtual string Name => UnderlyingMember.Name; + if (UnderlyingMember == type) + return (IReflectionTypeSymbolBuilder)this; + + if (_resolvingType != null && type == _resolvingType.UnderlyingType) + return (IReflectionTypeSymbolBuilder)_resolvingType; + + if (type.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateTypeSymbol(type); + + return base.ResolveTypeSymbol(type); + } /// - public virtual CustomAttribute[] GetCustomAttributes(bool inherit = false) + [return: NotNullIfNotNull(nameof(ctor))] + public override IReflectionConstructorSymbolBuilder ResolveConstructorSymbol(ConstructorBuilder ctor) { - if (inherit) - { - // check that we've already processed this - if (_inheritedCustomAttributes != null) - return _inheritedCustomAttributes; - - var self = UnderlyingMember; - var list = default(List?); - for (; ; ) - { - if (self == null) - throw new InvalidOperationException(); - - // get attribute for current member and append to list - var attr = ResolveMemberSymbol(self)!.GetCustomAttributes(false); - if (attr.Length > 0) - { - list ??= []; - list.Add(attr); - } - - var type = self as Type; - if (type != null) - { - type = type.BaseType; - if (type == null) - return _inheritedCustomAttributes ??= Concat(list); - - self = type; - continue; - } - - var method = self as MethodInfo; - if (method != null) - { - var prev = self; - method = method.GetBaseDefinition(); - if (method == null || method == prev) - return _inheritedCustomAttributes ??= Concat(list); - - self = method; - continue; - } - - return _inheritedCustomAttributes ??= Concat(list); - } - } - - return _customAttributes ??= ResolveCustomAttributes(UnderlyingMember.GetCustomAttributesData())!; + if (ctor is null) + throw new ArgumentNullException(nameof(ctor)); + + if (UnderlyingMember == ctor) + return (IReflectionConstructorSymbolBuilder)this; + + if (ctor.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateConstructorSymbol(ctor); + + return base.ResolveConstructorSymbol(ctor); } /// - public virtual CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) + [return: NotNullIfNotNull(nameof(method))] + public override IReflectionMethodSymbolBuilder ResolveMethodSymbol(MethodBuilder method) { - return GetCustomAttributes(inherit).Where(i => i.AttributeType == attributeType).ToArray(); + if (method is null) + throw new ArgumentNullException(nameof(method)); + + if (UnderlyingMember == method) + return (IReflectionMethodSymbolBuilder)this; + + if (method.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateMethodSymbol(method); + + return base.ResolveMethodSymbol(method); } /// - public virtual CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) + [return: NotNullIfNotNull(nameof(field))] + public override IReflectionFieldSymbolBuilder ResolveFieldSymbol(FieldBuilder field) { - return GetCustomAttributes(attributeType, inherit).FirstOrDefault(); + if (field is null) + throw new ArgumentNullException(nameof(field)); + + if (UnderlyingMember == field) + return (IReflectionFieldSymbolBuilder)this; + + if (field.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateFieldSymbol(field); + + return base.ResolveFieldSymbol(field); } /// - public virtual bool IsDefined(ITypeSymbol attributeType, bool inherit = false) + [return: NotNullIfNotNull(nameof(property))] + public override IReflectionPropertySymbolBuilder ResolvePropertySymbol(PropertyBuilder property) { - return UnderlyingMember.IsDefined(attributeType.Unpack(), inherit); + if (property is null) + throw new ArgumentNullException(nameof(property)); + + if (UnderlyingMember == property) + return (IReflectionPropertySymbolBuilder)this; + + if (property.Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreatePropertySymbol(property); + + return base.ResolvePropertySymbol(property); } - #endregion + /// + [return: NotNullIfNotNull(nameof(@event))] + public override IReflectionEventSymbolBuilder ResolveEventSymbol(EventBuilder @event) + { + if (@event is null) + throw new ArgumentNullException(nameof(@event)); + + if (@event.GetModuleBuilder() == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateEventSymbol(@event); + + return base.ResolveEventSymbol(@event); + } /// - [return: NotNullIfNotNull(nameof(type))] - public override IReflectionTypeSymbol? ResolveTypeSymbol(Type? type) + [return: NotNullIfNotNull(nameof(parameter))] + public override IReflectionParameterSymbolBuilder? ResolveParameterSymbol(IReflectionMethodBaseSymbolBuilder method, ParameterBuilder parameter) { - if (type is null) + if (parameter is null) return null; - if (UnderlyingMember == type) - return (IReflectionTypeSymbol)this; + if (parameter.GetModuleBuilder() == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateParameterSymbol(method, parameter); - if (_resolvingType != null && type == _resolvingType.UnderlyingType) - return _resolvingType; + return base.ResolveParameterSymbol(method, parameter); + } - if (type.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateTypeSymbol(type); + /// + [return: NotNullIfNotNull(nameof(parameter))] + public override IReflectionParameterSymbolBuilder? ResolveParameterSymbol(IReflectionPropertySymbolBuilder property, ParameterBuilder parameter) + { + if (parameter is null) + return null; - return base.ResolveTypeSymbol(type); + if (parameter.GetMethodBuilder().Module == _resolvingModule.UnderlyingModule) + return _resolvingModule.GetOrCreateParameterSymbol(property, parameter); + + return base.ResolveParameterSymbol(property, parameter); } + #endregion + + #region IReflectionSymbol + /// - [return: NotNullIfNotNull("type")] - public override IReflectionTypeSymbolBuilder ResolveTypeSymbol(TypeBuilder type) + [return: NotNullIfNotNull(nameof(type))] + public override IReflectionTypeSymbol? ResolveTypeSymbol(Type? type) { if (type is null) - throw new ArgumentNullException(nameof(type)); + return null; if (UnderlyingMember == type) - return (IReflectionTypeSymbolBuilder)this; + return (IReflectionTypeSymbol)this; if (_resolvingType != null && type == _resolvingType.UnderlyingType) - return (IReflectionTypeSymbolBuilder)_resolvingType; + return _resolvingType; if (type.Module == _resolvingModule.UnderlyingModule) return _resolvingModule.GetOrCreateTypeSymbol(type); @@ -214,22 +207,6 @@ public override IReflectionTypeSymbolBuilder ResolveTypeSymbol(TypeBuilder type) return base.ResolveConstructorSymbol(ctor); } - /// - [return: NotNullIfNotNull(nameof(ctor))] - public override IReflectionConstructorSymbolBuilder ResolveConstructorSymbol(ConstructorBuilder ctor) - { - if (ctor is null) - throw new ArgumentNullException(nameof(ctor)); - - if (UnderlyingMember == ctor) - return (IReflectionConstructorSymbolBuilder)this; - - if (ctor.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateConstructorSymbol(ctor); - - return base.ResolveConstructorSymbol(ctor); - } - /// [return: NotNullIfNotNull(nameof(method))] public override IReflectionMethodSymbol? ResolveMethodSymbol(MethodInfo? method) @@ -246,22 +223,6 @@ public override IReflectionConstructorSymbolBuilder ResolveConstructorSymbol(Con return base.ResolveMethodSymbol(method); } - /// - [return: NotNullIfNotNull(nameof(method))] - public override IReflectionMethodSymbolBuilder ResolveMethodSymbol(MethodBuilder method) - { - if (method is null) - throw new ArgumentNullException(nameof(method)); - - if (UnderlyingMember == method) - return (IReflectionMethodSymbolBuilder)this; - - if (method.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateMethodSymbol(method); - - return base.ResolveMethodSymbol(method); - } - /// [return: NotNullIfNotNull(nameof(field))] public override IReflectionFieldSymbol? ResolveFieldSymbol(FieldInfo? field) @@ -278,22 +239,6 @@ public override IReflectionMethodSymbolBuilder ResolveMethodSymbol(MethodBuilder return base.ResolveFieldSymbol(field); } - /// - [return: NotNullIfNotNull(nameof(field))] - public override IReflectionFieldSymbolBuilder ResolveFieldSymbol(FieldBuilder field) - { - if (field is null) - throw new ArgumentNullException(nameof(field)); - - if (UnderlyingMember == field) - return (IReflectionFieldSymbolBuilder)this; - - if (field.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateFieldSymbol(field); - - return base.ResolveFieldSymbol(field); - } - /// [return: NotNullIfNotNull(nameof(property))] public override IReflectionPropertySymbol? ResolvePropertySymbol(PropertyInfo? property) @@ -310,22 +255,6 @@ public override IReflectionFieldSymbolBuilder ResolveFieldSymbol(FieldBuilder fi return base.ResolvePropertySymbol(property); } - /// - [return: NotNullIfNotNull(nameof(property))] - public override IReflectionPropertySymbolBuilder ResolvePropertySymbol(PropertyBuilder property) - { - if (property is null) - throw new ArgumentNullException(nameof(property)); - - if (UnderlyingMember == property) - return (IReflectionPropertySymbolBuilder)this; - - if (property.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreatePropertySymbol(property); - - return base.ResolvePropertySymbol(property); - } - /// [return: NotNullIfNotNull(nameof(@event))] public override IReflectionEventSymbol? ResolveEventSymbol(EventInfo? @event) @@ -342,19 +271,6 @@ public override IReflectionPropertySymbolBuilder ResolvePropertySymbol(PropertyB return base.ResolveEventSymbol(@event); } - /// - [return: NotNullIfNotNull(nameof(@event))] - public override IReflectionEventSymbolBuilder ResolveEventSymbol(EventBuilder @event) - { - if (@event is null) - throw new ArgumentNullException(nameof(@event)); - - if (@event.GetModuleBuilder() == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateEventSymbol(@event); - - return base.ResolveEventSymbol(@event); - } - /// [return: NotNullIfNotNull(nameof(parameter))] public override IReflectionParameterSymbol? ResolveParameterSymbol(ParameterInfo? parameter) @@ -368,19 +284,53 @@ public override IReflectionEventSymbolBuilder ResolveEventSymbol(EventBuilder @e return base.ResolveParameterSymbol(parameter); } + #endregion + + #region IMemberSymbol + /// - [return: NotNullIfNotNull(nameof(parameter))] - public override IReflectionParameterSymbolBuilder ResolveParameterSymbol(ParameterBuilder parameter) + public virtual IModuleSymbol Module => ResolveModuleSymbol(UnderlyingMember.Module)!; + + /// + public virtual ITypeSymbol? DeclaringType => ResolveTypeSymbol(UnderlyingMember.DeclaringType)!; + + /// + public virtual System.Reflection.MemberTypes MemberType => (System.Reflection.MemberTypes)UnderlyingMember.MemberType; + + /// + public virtual int MetadataToken => UnderlyingMember.MetadataToken; + + /// + public virtual string Name => UnderlyingMember.Name; + + /// + public CustomAttribute[] GetCustomAttributes(bool inherit = false) { - if (parameter is null) - throw new ArgumentNullException(nameof(parameter)); + return ResolveCustomAttributes(UnderlyingMember.GetCustomAttributesData()); + } - if (parameter.GetModuleBuilder() == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateParameterSymbol(parameter); + /// + public CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) + { + var _attributeType = attributeType.Unpack(); + return ResolveCustomAttributes(UnderlyingMember.GetCustomAttributesData().Where(i => i.AttributeType == _attributeType).ToArray()); + } - return base.ResolveParameterSymbol(parameter); + /// + public CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) + { + var _attributeType = attributeType.Unpack(); + return ResolveCustomAttribute(UnderlyingMember.GetCustomAttributesData().Where(i => i.AttributeType == _attributeType).FirstOrDefault()); } + /// + public virtual bool IsDefined(ITypeSymbol attributeType, bool inherit = false) + { + return UnderlyingMember.IsDefined(attributeType.Unpack(), inherit); + } + + #endregion + /// public virtual void OnComplete() { diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodBaseSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodBaseSymbolBuilder.cs index d9d283327..03cd589a4 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodBaseSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodBaseSymbolBuilder.cs @@ -1,4 +1,5 @@ using System.Reflection; +using System.Reflection.Emit; using IKVM.CoreLib.Symbols.Emit; @@ -8,16 +9,18 @@ namespace IKVM.CoreLib.Symbols.Reflection.Emit abstract class ReflectionMethodBaseSymbolBuilder : ReflectionMemberSymbolBuilder, IReflectionMethodBaseSymbolBuilder { + ReflectionParameterTable _parameterTable; + /// /// Initializes a new instance. /// /// /// /// - public ReflectionMethodBaseSymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol? resolvingType) : + public ReflectionMethodBaseSymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbolBuilder resolvingModule, IReflectionTypeSymbolBuilder? resolvingType) : base(context, resolvingModule, resolvingType) { - + _parameterTable = new ReflectionParameterTable(context, resolvingModule, this); } /// @@ -26,6 +29,16 @@ public ReflectionMethodBaseSymbolBuilder(ReflectionSymbolContext context, IRefle /// public override MemberInfo UnderlyingMember => UnderlyingMethodBase; + #region IReflectionMethodBaseSymbol + + /// + public IReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) + { + return _parameterTable.GetOrCreateParameterSymbol(parameter); + } + + #endregion + #region IMethodBaseSymbolBuilder /// @@ -46,15 +59,21 @@ public ReflectionMethodBaseSymbolBuilder(ReflectionSymbolContext context, IRefle /// public abstract void SetCustomAttribute(ICustomAttributeBuilder customBuilder); + /// + public IReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter) + { + return _parameterTable.GetOrCreateParameterSymbol(parameter); + } + #endregion #region IMethodBaseSymbol /// - public MethodAttributes Attributes => UnderlyingMethodBase.Attributes; + public System.Reflection.MethodAttributes Attributes => (System.Reflection.MethodAttributes)UnderlyingMethodBase.Attributes; /// - public CallingConventions CallingConvention => UnderlyingMethodBase.CallingConvention; + public System.Reflection.CallingConventions CallingConvention => (System.Reflection.CallingConventions)UnderlyingMethodBase.CallingConvention; /// public bool ContainsGenericParameters => UnderlyingMethodBase.ContainsGenericParameters; @@ -105,7 +124,7 @@ public ReflectionMethodBaseSymbolBuilder(ReflectionSymbolContext context, IRefle public bool IsSpecialName => UnderlyingMethodBase.IsSpecialName; /// - public MethodImplAttributes MethodImplementationFlags => UnderlyingMethodBase.MethodImplementationFlags; + public System.Reflection.MethodImplAttributes MethodImplementationFlags => (System.Reflection.MethodImplAttributes)UnderlyingMethodBase.MethodImplementationFlags; /// public ITypeSymbol[] GetGenericArguments() @@ -114,7 +133,7 @@ public ITypeSymbol[] GetGenericArguments() } /// - public MethodImplAttributes GetMethodImplementationFlags() + public System.Reflection.MethodImplAttributes GetMethodImplementationFlags() { return UnderlyingMethodBase.GetMethodImplementationFlags(); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs index 933623740..43ab72c52 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs @@ -13,6 +13,9 @@ class ReflectionMethodSymbolBuilder : ReflectionMethodBaseSymbolBuilder, IReflec MethodBuilder? _builder; MethodInfo _method; + ReflectionGenericTypeParameterTable _genericTypeParameterTable; + ReflectionMethodSpecTable _specTable; + ReflectionILGenerator? _il; /// @@ -23,11 +26,13 @@ class ReflectionMethodSymbolBuilder : ReflectionMethodBaseSymbolBuilder, IReflec /// /// /// - public ReflectionMethodSymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol? resolvingType, MethodBuilder builder) : + public ReflectionMethodSymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbolBuilder resolvingModule, IReflectionTypeSymbolBuilder? resolvingType, MethodBuilder builder) : base(context, resolvingModule, resolvingType) { _builder = builder ?? throw new ArgumentNullException(nameof(builder)); _method = _builder; + _genericTypeParameterTable = new ReflectionGenericTypeParameterTable(context, resolvingModule, this); + _specTable = new ReflectionMethodSpecTable(context, resolvingModule, resolvingType, this); } /// @@ -39,18 +44,52 @@ public ReflectionMethodSymbolBuilder(ReflectionSymbolContext context, IReflectio /// public MethodBuilder UnderlyingMethodBuilder => _builder ?? throw new InvalidOperationException(); + #region IReflectionMethodSymbolBuilder + + /// + public IReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeParameterSymbol(GenericTypeParameterBuilder genericTypeParameter) + { + return _genericTypeParameterTable.GetOrCreateGenericTypeParameterSymbol(genericTypeParameter); + } + + #endregion + + #region IReflectionMethodSymbol + + /// + public IReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type genericTypeParameter) + { + return _genericTypeParameterTable.GetOrCreateGenericTypeParameterSymbol(genericTypeParameter); + } + + /// + public IReflectionMethodSymbol GetOrCreateGenericMethodSymbol(MethodInfo method) + { + return _specTable.GetOrCreateGenericMethodSymbol(method.GetGenericArguments()); + } + + #endregion + + #region IReflectionMethodBaseSymbol + + #endregion + + #region IReflectionMethodBaseSymbolBuilder + + #endregion + #region IMethodBaseSymbolBuilder /// - public override void SetImplementationFlags(MethodImplAttributes attributes) + public override void SetImplementationFlags(System.Reflection.MethodImplAttributes attributes) { - UnderlyingMethodBuilder.SetImplementationFlags(attributes); + UnderlyingMethodBuilder.SetImplementationFlags((MethodImplAttributes)attributes); } /// - public override IParameterSymbolBuilder DefineParameter(int position, ParameterAttributes attributes, string? strParamName) + public override IParameterSymbolBuilder DefineParameter(int position, System.Reflection.ParameterAttributes attributes, string? strParamName) { - return ResolveParameterSymbol(UnderlyingMethodBuilder.DefineParameter(position, attributes, strParamName)); + return ResolveParameterSymbol(this, UnderlyingMethodBuilder.DefineParameter(position, (ParameterAttributes)attributes, strParamName)); } /// @@ -104,7 +143,7 @@ public IGenericTypeParameterSymbolBuilder[] DefineGenericParameters(params strin var l = UnderlyingMethodBuilder.DefineGenericParameters(names); var a = new IGenericTypeParameterSymbolBuilder[l.Length]; for (int i = 0; i < l.Length; i++) - a[i] = (IGenericTypeParameterSymbolBuilder)ResolveTypeSymbol(l[i]); + a[i] = ResolveGenericTypeParameterSymbol(l[i]); return a; } @@ -152,7 +191,6 @@ public override void OnComplete() _builder = null; base.OnComplete(); } - } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionModuleSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionModuleSymbolBuilder.cs index 42fdb989d..b671cc5e6 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionModuleSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionModuleSymbolBuilder.cs @@ -4,9 +4,9 @@ using System.Linq; using System.Reflection; using System.Reflection.Emit; -using System.Reflection.PortableExecutable; using System.Resources; +using IKVM.CoreLib.Reflection; using IKVM.CoreLib.Symbols.Emit; namespace IKVM.CoreLib.Symbols.Reflection.Emit @@ -16,9 +16,12 @@ class ReflectionModuleSymbolBuilder : ReflectionSymbolBuilder, IReflectionModule { readonly IReflectionAssemblySymbol _resolvingAssembly; + Module _module; + ModuleBuilder? _builder; - readonly ModuleBuilder _builder; - ReflectionModuleMetadata _metadata; + ReflectionTypeTable _typeTable; + ReflectionMethodTable _methodTable; + ReflectionFieldTable _fieldTable; /// /// Initializes a new instance. @@ -32,18 +35,167 @@ public ReflectionModuleSymbolBuilder(ReflectionSymbolContext context, IReflectio { _resolvingAssembly = resolvingAssembly ?? throw new ArgumentNullException(nameof(resolvingAssembly)); _builder = builder ?? throw new ArgumentNullException(nameof(builder)); - _metadata = new ReflectionModuleMetadata(this); + _module = _builder; + + _typeTable = new ReflectionTypeTable(context, this, null); + _methodTable = new ReflectionMethodTable(context, this, null); + _fieldTable = new ReflectionFieldTable(context, this, null); } /// - public Module UnderlyingModule => UnderlyingModuleBuilder; + public Module UnderlyingModule => _module; /// - public ModuleBuilder UnderlyingModuleBuilder => _builder; + public ModuleBuilder UnderlyingModuleBuilder => _builder ?? throw new InvalidOperationException(); /// public IReflectionAssemblySymbol ResolvingAssembly => _resolvingAssembly; + #region IReflectionModuleSymbol + + /// + public IReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) + { + if (type.IsTypeDefinition()) + return _typeTable.GetOrCreateTypeSymbol(type); + else if (type.IsGenericType) + return ResolveTypeSymbol(type.GetGenericTypeDefinition()).GetOrCreateGenericTypeSymbol(type.GetGenericArguments()); + else if (type.IsSZArray()) + return ResolveTypeSymbol(type.GetElementType()!).GetOrCreateSZArrayTypeSymbol(); + else if (type.IsArray) + return ResolveTypeSymbol(type.GetElementType()!).GetOrCreateArrayTypeSymbol(type.GetArrayRank()); + else if (type.IsPointer) + return ResolveTypeSymbol(type.GetElementType()!).GetOrCreatePointerTypeSymbol(); + else if (type.IsByRef) + return ResolveTypeSymbol(type.GetElementType()!).GetOrCreateByRefTypeSymbol(); + else if (type.IsGenericParameter && type.DeclaringMethod is MethodInfo dm) + return ResolveMethodSymbol(dm).GetOrCreateGenericTypeParameterSymbol(type); + else if (type.IsGenericParameter) + return ResolveTypeSymbol(type.DeclaringType!).GetOrCreateGenericTypeParameterSymbol(type); + else + throw new InvalidOperationException(); + } + + /// + public IReflectionTypeSymbolBuilder GetOrCreateTypeSymbol(TypeBuilder type) + { + return (IReflectionTypeSymbolBuilder)_typeTable.GetOrCreateTypeSymbol((Type)type); + } + + /// + public IReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method) + { + if (method.DeclaringType is { } dt) + return ResolveTypeSymbol(dt).GetOrCreateMethodBaseSymbol(method); + else + return _methodTable.GetOrCreateMethodBaseSymbol(method); + } + + /// + public IReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) + { + return ResolveTypeSymbol(ctor.DeclaringType!).GetOrCreateConstructorSymbol(ctor); + } + + /// + public IReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor) + { + return ResolveTypeSymbol((TypeBuilder)ctor.DeclaringType!).GetOrCreateConstructorSymbol(ctor); + } + + /// + public IReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) + { + if (method.DeclaringType is { } dt) + return ResolveTypeSymbol(dt).GetOrCreateMethodSymbol(method); + else + return _methodTable.GetOrCreateMethodSymbol(method); + } + + /// + public IReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method) + { + if (method.DeclaringType is { } dt) + return ResolveTypeSymbol((TypeBuilder)dt).GetOrCreateMethodSymbol(method); + else + return _methodTable.GetOrCreateMethodSymbol(method); + } + + /// + public IReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) + { + if (field.DeclaringType is { } dt) + return ResolveTypeSymbol(dt).GetOrCreateFieldSymbol(field); + else + return _fieldTable.GetOrCreateFieldSymbol(field); + } + + /// + public IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field) + { + if (field.DeclaringType is { } dt) + return ResolveTypeSymbol((TypeBuilder)dt).GetOrCreateFieldSymbol(field); + else + return _fieldTable.GetOrCreateFieldSymbol(field); + } + + /// + public IReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) + { + return ResolveTypeSymbol(property.DeclaringType!).GetOrCreatePropertySymbol(property); + } + + /// + public IReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property) + { + return ResolveTypeSymbol(property.GetTypeBuilder()).GetOrCreatePropertySymbol(property); + } + + /// + public IReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) + { + return ResolveTypeSymbol(@event.DeclaringType!).GetOrCreateEventSymbol(@event); + } + + /// + public IReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event) + { + return ResolveTypeSymbol(@event.GetTypeBuilder()).GetOrCreateEventSymbol(@event); + } + + /// + public IReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) + { + return ResolveMemberSymbol(parameter.Member) switch + { + IReflectionMethodBaseSymbol method => method.GetOrCreateParameterSymbol(parameter), + IReflectionPropertySymbol property => property.GetOrCreateParameterSymbol(parameter), + _ => throw new InvalidOperationException(), + }; + } + + /// + public IReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(IReflectionMemberSymbolBuilder member, ParameterBuilder parameter) + { + return member switch + { + IReflectionMethodBaseSymbolBuilder method => method.GetOrCreateParameterSymbol(parameter), + IReflectionPropertySymbolBuilder property => property.GetOrCreateParameterSymbol(parameter), + _ => throw new InvalidOperationException(), + }; + } + + /// + public IReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeParameterSymbol(GenericTypeParameterBuilder genericParameterType) + { + if (genericParameterType.DeclaringMethod is MethodBuilder dm) + return ResolveMethodSymbol(dm).GetOrCreateGenericTypeParameterSymbol(genericParameterType); + else + return ResolveTypeSymbol((TypeBuilder)genericParameterType.DeclaringType!).GetOrCreateGenericTypeParameterSymbol(genericParameterType); + } + + #endregion + #region IModuleSymbolBuilder /// @@ -57,10 +209,10 @@ public ReflectionModuleSymbolBuilder(ReflectionSymbolContext context, IReflectio } /// - public void DefineManifestResource(string name, Stream stream, ResourceAttributes attribute) + public void DefineManifestResource(string name, Stream stream, System.Reflection.ResourceAttributes attribute) { #if NETFRAMEWORK - UnderlyingModuleBuilder.DefineManifestResource(name, stream, attribute); + UnderlyingModuleBuilder.DefineManifestResource(name, stream, attribute); #else throw new NotSupportedException(); #endif @@ -70,80 +222,80 @@ public void DefineManifestResource(string name, Stream stream, ResourceAttribute public IResourceWriter DefineResource(string name, string description) { #if NETFRAMEWORK - return UnderlyingModuleBuilder.DefineResource(name, description); + return UnderlyingModuleBuilder.DefineResource(name, description); #else throw new NotImplementedException(); #endif } /// - public IResourceWriter DefineResource(string name, string description, ResourceAttributes attribute) + public IResourceWriter DefineResource(string name, string description, System.Reflection.ResourceAttributes attribute) { #if NETFRAMEWORK - return UnderlyingModuleBuilder.DefineResource(name, description, attribute); + return UnderlyingModuleBuilder.DefineResource(name, description, attribute); #else throw new NotImplementedException(); #endif } /// - public IMethodSymbolBuilder DefineGlobalMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes) + public IMethodSymbolBuilder DefineGlobalMethod(string name, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes) { - return ResolveMethodSymbol(UnderlyingModuleBuilder.DefineGlobalMethod(name, attributes, callingConvention, returnType?.Unpack(), parameterTypes?.Unpack())); + return ResolveMethodSymbol(UnderlyingModuleBuilder.DefineGlobalMethod(name, (MethodAttributes)attributes, (CallingConventions)callingConvention, returnType?.Unpack(), parameterTypes?.Unpack())); } /// - public IMethodSymbolBuilder DefineGlobalMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? requiredReturnTypeCustomModifiers, ITypeSymbol[]? optionalReturnTypeCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? requiredParameterTypeCustomModifiers, ITypeSymbol[][]? optionalParameterTypeCustomModifiers) + public IMethodSymbolBuilder DefineGlobalMethod(string name, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? requiredReturnTypeCustomModifiers, ITypeSymbol[]? optionalReturnTypeCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? requiredParameterTypeCustomModifiers, ITypeSymbol[][]? optionalParameterTypeCustomModifiers) { - return ResolveMethodSymbol(UnderlyingModuleBuilder.DefineGlobalMethod(name, attributes, callingConvention, returnType?.Unpack(), requiredReturnTypeCustomModifiers?.Unpack(), optionalReturnTypeCustomModifiers?.Unpack(), parameterTypes?.Unpack(), requiredParameterTypeCustomModifiers?.Unpack(), optionalParameterTypeCustomModifiers?.Unpack())); + return ResolveMethodSymbol(UnderlyingModuleBuilder.DefineGlobalMethod(name, (MethodAttributes)attributes, (CallingConventions)callingConvention, returnType?.Unpack(), requiredReturnTypeCustomModifiers?.Unpack(), optionalReturnTypeCustomModifiers?.Unpack(), parameterTypes?.Unpack(), requiredParameterTypeCustomModifiers?.Unpack(), optionalParameterTypeCustomModifiers?.Unpack())); } /// - public IMethodSymbolBuilder DefineGlobalMethod(string name, MethodAttributes attributes, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes) + public IMethodSymbolBuilder DefineGlobalMethod(string name, System.Reflection.MethodAttributes attributes, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes) { - return ResolveMethodSymbol(UnderlyingModuleBuilder.DefineGlobalMethod(name, attributes, returnType?.Unpack(), parameterTypes?.Unpack())); + return ResolveMethodSymbol(UnderlyingModuleBuilder.DefineGlobalMethod(name, (MethodAttributes)attributes, returnType?.Unpack(), parameterTypes?.Unpack())); } /// public ITypeSymbolBuilder DefineType(string name) { - return (ITypeSymbolBuilder)ResolveTypeSymbol(UnderlyingModuleBuilder.DefineType(name)); + return ResolveTypeSymbol(UnderlyingModuleBuilder.DefineType(name)); } /// - public ITypeSymbolBuilder DefineType(string name, TypeAttributes attr, ITypeSymbol? parent, int typesize) + public ITypeSymbolBuilder DefineType(string name, System.Reflection.TypeAttributes attr, ITypeSymbol? parent, int typesize) { - return (ITypeSymbolBuilder)ResolveTypeSymbol(UnderlyingModuleBuilder.DefineType(name, attr, parent?.Unpack(), typesize)); + return ResolveTypeSymbol(UnderlyingModuleBuilder.DefineType(name, (TypeAttributes)attr, parent?.Unpack(), typesize)); } /// - public ITypeSymbolBuilder DefineType(string name, TypeAttributes attr, ITypeSymbol? parent) + public ITypeSymbolBuilder DefineType(string name, System.Reflection.TypeAttributes attr, ITypeSymbol? parent) { - return (ITypeSymbolBuilder)ResolveTypeSymbol(UnderlyingModuleBuilder.DefineType(name, attr, parent?.Unpack())); + return ResolveTypeSymbol(UnderlyingModuleBuilder.DefineType(name, (TypeAttributes)attr, parent?.Unpack())); } /// - public ITypeSymbolBuilder DefineType(string name, TypeAttributes attr) + public ITypeSymbolBuilder DefineType(string name, System.Reflection.TypeAttributes attr) { - return (ITypeSymbolBuilder)ResolveTypeSymbol(UnderlyingModuleBuilder.DefineType(name, attr)); + return ResolveTypeSymbol(UnderlyingModuleBuilder.DefineType(name, (TypeAttributes)attr)); } /// - public ITypeSymbolBuilder DefineType(string name, TypeAttributes attr, ITypeSymbol? parent, PackingSize packsize) + public ITypeSymbolBuilder DefineType(string name, System.Reflection.TypeAttributes attr, ITypeSymbol? parent, System.Reflection.Emit.PackingSize packsize) { - return (ITypeSymbolBuilder)ResolveTypeSymbol(UnderlyingModuleBuilder.DefineType(name, attr, parent?.Unpack(), packsize)); + return ResolveTypeSymbol(UnderlyingModuleBuilder.DefineType(name, (TypeAttributes)attr, parent?.Unpack(), (PackingSize)packsize)); } /// - public ITypeSymbolBuilder DefineType(string name, TypeAttributes attr, ITypeSymbol? parent, PackingSize packingSize, int typesize) + public ITypeSymbolBuilder DefineType(string name, System.Reflection.TypeAttributes attr, ITypeSymbol? parent, System.Reflection.Emit.PackingSize packingSize, int typesize) { - return (ITypeSymbolBuilder)ResolveTypeSymbol(UnderlyingModuleBuilder.DefineType(name, attr, parent?.Unpack(), packingSize, typesize)); + return ResolveTypeSymbol(UnderlyingModuleBuilder.DefineType(name, (TypeAttributes)attr, parent?.Unpack(), (PackingSize)packingSize, typesize)); } /// - public ITypeSymbolBuilder DefineType(string name, TypeAttributes attr, ITypeSymbol? parent, ITypeSymbol[]? interfaces) + public ITypeSymbolBuilder DefineType(string name, System.Reflection.TypeAttributes attr, ITypeSymbol? parent, ITypeSymbol[]? interfaces) { - return (ITypeSymbolBuilder)ResolveTypeSymbol(UnderlyingModuleBuilder.DefineType(name, attr, parent?.Unpack(), interfaces?.Unpack())); + return ResolveTypeSymbol(UnderlyingModuleBuilder.DefineType(name, (TypeAttributes)attr, parent?.Unpack(), interfaces?.Unpack())); } /// @@ -158,6 +310,36 @@ public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) UnderlyingModuleBuilder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); } + /// + public void AddReference(IAssemblySymbol assembly) + { +#if NETFRAMEWORK + var t = ((IReflectionAssemblySymbol)assembly).GetExportedTypes(); + if (t.Length > 0) + UnderlyingModuleBuilder.GetTypeToken(t[0].Unpack()); +#else + throw new NotSupportedException(); +#endif + } + + /// + public void Complete() + { + UnderlyingModuleBuilder.CreateGlobalFunctions(); + + foreach (var type in GetTypes()) + if (type is IReflectionTypeSymbolBuilder t) + t.Complete(); + + _builder = null; + } + + /// + public void Save(System.Reflection.PortableExecutableKinds portableExecutableKind, IKVM.CoreLib.Symbols.ImageFileMachine imageFileMachine) + { + throw new NotSupportedException(); + } + #endregion #region IModuleSymbol @@ -195,7 +377,7 @@ public uint FileAlignment } /// - public DllCharacteristics DllCharacteristics + public System.Reflection.PortableExecutable.DllCharacteristics DllCharacteristics { get => throw new NotSupportedException(); set => throw new NotSupportedException(); @@ -211,15 +393,15 @@ public DllCharacteristics DllCharacteristics } /// - public IFieldSymbol? GetField(string name, BindingFlags bindingAttr) + public IFieldSymbol? GetField(string name, System.Reflection.BindingFlags bindingAttr) { - return ResolveFieldSymbol(UnderlyingModule.GetField(name, bindingAttr)); + return ResolveFieldSymbol(UnderlyingModule.GetField(name, (BindingFlags)bindingAttr)); } /// - public IFieldSymbol[] GetFields(BindingFlags bindingFlags) + public IFieldSymbol[] GetFields(System.Reflection.BindingFlags bindingFlags) { - return ResolveFieldSymbols(UnderlyingModule.GetFields(bindingFlags))!; + return ResolveFieldSymbols(UnderlyingModule.GetFields((BindingFlags)bindingFlags))!; } /// @@ -241,9 +423,9 @@ public IFieldSymbol[] GetFields() } /// - public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return ResolveMethodSymbol(UnderlyingModule.GetMethod(name, bindingAttr, null, callConvention, types.Unpack(), modifiers)); + return ResolveMethodSymbol(UnderlyingModule.GetMethod(name, (BindingFlags)bindingAttr, null, (CallingConventions)callConvention, types.Unpack(), modifiers?.Unpack())); } /// @@ -253,9 +435,9 @@ public IMethodSymbol[] GetMethods() } /// - public IMethodSymbol[] GetMethods(BindingFlags bindingFlags) + public IMethodSymbol[] GetMethods(System.Reflection.BindingFlags bindingFlags) { - return ResolveMethodSymbols(UnderlyingModule.GetMethods(bindingFlags))!; + return ResolveMethodSymbols(UnderlyingModule.GetMethods((BindingFlags)bindingFlags))!; } /// @@ -355,16 +537,17 @@ public CustomAttribute[] GetCustomAttributes(bool inherit = false) } /// - public CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) + public virtual CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) { var _attributeType = attributeType.Unpack(); return ResolveCustomAttributes(UnderlyingModule.GetCustomAttributesData().Where(i => i.AttributeType == _attributeType).ToArray()); } /// - public CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) + public virtual CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) { - return GetCustomAttributes(attributeType, inherit).FirstOrDefault(); + var _attributeType = attributeType.Unpack(); + return ResolveCustomAttribute(UnderlyingModule.GetCustomAttributesData().Where(i => i.AttributeType == _attributeType).FirstOrDefault()); } /// @@ -373,122 +556,8 @@ public bool IsDefined(ITypeSymbol attributeType, bool inherit = false) return UnderlyingModule.IsDefined(attributeType.Unpack(), false); } - /// - public void AddReference(IAssemblySymbol assembly) - { -#if NETFRAMEWORK - var t = ((IReflectionAssemblySymbol)assembly).GetExportedTypes(); - if (t.Length > 0) - UnderlyingModuleBuilder.GetTypeToken(t[0].Unpack()); -#else - throw new NotSupportedException(); -#endif - } - - /// - public void AddTypeForwarder(ITypeSymbol type) - { - throw new NotImplementedException(); - } - - /// - public void Complete() - { - UnderlyingModuleBuilder.CreateGlobalFunctions(); - } - - /// - public void Save(PortableExecutableKinds pekind, ImageFileMachine imageFileMachine) - { - throw new NotSupportedException(); - } - #endregion - /// - public IReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) - { - return _metadata.GetOrCreateTypeSymbol(type); - } - - /// - public IReflectionTypeSymbolBuilder GetOrCreateTypeSymbol(TypeBuilder type) - { - return _metadata.GetOrCreateTypeSymbol(type); - } - - /// - public IReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) - { - return _metadata.GetOrCreateConstructorSymbol(ctor); - } - - /// - public IReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor) - { - return _metadata.GetOrCreateConstructorSymbol(ctor); - } - - /// - public IReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) - { - return _metadata.GetOrCreateMethodSymbol(method); - } - - /// - public IReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method) - { - return _metadata.GetOrCreateMethodSymbol(method); - } - - /// - public IReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) - { - return _metadata.GetOrCreateFieldSymbol(field); - } - - /// - public IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field) - { - return _metadata.GetOrCreateFieldSymbol(field); - } - - /// - public IReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) - { - return _metadata.GetOrCreatePropertySymbol(property); - } - - /// - public IReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property) - { - return _metadata.GetOrCreatePropertySymbol(property); - } - - /// - public IReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) - { - return _metadata.GetOrCreateEventSymbol(@event); - } - - /// - public IReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event) - { - return _metadata.GetOrCreateEventSymbol(@event); - } - - /// - public IReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) - { - return _metadata.GetOrCreateParameterSymbol(parameter); - } - - /// - public IReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter) - { - return _metadata.GetOrCreateParameterSymbol(parameter); - } - } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionParameterBuilderInfo.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionParameterBuilderInfo.cs index 816de787d..a3dc81626 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionParameterBuilderInfo.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionParameterBuilderInfo.cs @@ -1,6 +1,7 @@ using System; using System.Reflection; using System.Reflection.Emit; + using IKVM.CoreLib.Reflection; namespace IKVM.CoreLib.Symbols.Reflection.Emit @@ -37,7 +38,7 @@ public ReflectionParameterBuilderInfo(ParameterBuilder builder, Func ge public override string? Name => _builder.Name; /// - public override int Position => _builder.Position; + public override int Position => _builder.Position - 1; /// public override int MetadataToken => _builder.GetMetadataToken(); diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionParameterSymbolBuilder.cs index 879a74a62..d5bd36f67 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionParameterSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionParameterSymbolBuilder.cs @@ -11,8 +11,8 @@ namespace IKVM.CoreLib.Symbols.Reflection.Emit class ReflectionParameterSymbolBuilder : ReflectionSymbolBuilder, IReflectionParameterSymbolBuilder { - readonly IReflectionModuleSymbol _resolvingModule; - readonly IReflectionMethodBaseSymbol _resolvingMethod; + readonly IReflectionModuleSymbol _module; + readonly IReflectionMemberSymbol _member; ParameterBuilder? _builder; ParameterInfo _parameter; @@ -23,23 +23,23 @@ class ReflectionParameterSymbolBuilder : ReflectionSymbolBuilder, IReflectionPar /// Initializes a new instance. /// /// - /// - /// + /// + /// /// - public ReflectionParameterSymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionMethodBaseSymbol resolvingMethod, ParameterBuilder builder) : + public ReflectionParameterSymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbol module, IReflectionMemberSymbol member, ParameterBuilder builder) : base(context) { - _resolvingModule = resolvingModule ?? throw new ArgumentNullException(nameof(resolvingModule)); - _resolvingMethod = resolvingMethod ?? throw new ArgumentNullException(nameof(resolvingMethod)); + _module = module ?? throw new ArgumentNullException(nameof(module)); + _member = member ?? throw new ArgumentNullException(nameof(member)); _builder = builder ?? throw new ArgumentNullException(nameof(builder)); - _parameter = new ReflectionParameterBuilderInfo(_builder, () => _constant); + _parameter = new ReflectionParameterBuilderInfo(builder, () => _constant); } /// - public IReflectionModuleSymbol ResolvingModule => _resolvingMethod.ResolvingModule; + public IReflectionModuleSymbol ResolvingModule => _module; /// - public IReflectionMethodBaseSymbol ResolvingMethod => _resolvingMethod; + public IReflectionMemberSymbol ResolvingMember => _member; /// public ParameterInfo UnderlyingParameter => _parameter; @@ -72,10 +72,10 @@ public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) #region IParameterSymbol /// - public ParameterAttributes Attributes => UnderlyingParameter.Attributes; + public System.Reflection.ParameterAttributes Attributes => (System.Reflection.ParameterAttributes)UnderlyingParameter.Attributes; /// - public object? DefaultValue => UnderlyingParameter.DefaultValue; + public object? DefaultValue => UnderlyingParameter.RawDefaultValue; /// public bool HasDefaultValue => UnderlyingParameter.HasDefaultValue; @@ -128,7 +128,8 @@ public virtual CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, /// public virtual CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) { - return ResolveCustomAttribute(UnderlyingParameter.GetCustomAttributesData().Where(i => attributeType.IsAssignableFrom(attributeType)).FirstOrDefault()); + var _attributeType = attributeType.Unpack(); + return ResolveCustomAttribute(UnderlyingParameter.GetCustomAttributesData().Where(i => i.AttributeType == _attributeType).FirstOrDefault()); } /// @@ -154,8 +155,12 @@ public ITypeSymbol[] GetRequiredCustomModifiers() /// public void OnComplete() { - var p = ResolvingMethod.UnderlyingMethodBase.GetParameters(); - _parameter = p[Position]; + if (ResolvingMember is IReflectionMethodBaseSymbolBuilder b) + _parameter = b.UnderlyingMethodBase.GetParameters()[Position]; + + if (ResolvingMember is IReflectionPropertySymbolBuilder p) + _parameter = p.UnderlyingPropertyBuilder.GetIndexParameters()[Position]; + _builder = null; } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionPropertySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionPropertySymbolBuilder.cs index de0c8ac1c..99859af76 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionPropertySymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionPropertySymbolBuilder.cs @@ -13,6 +13,8 @@ class ReflectionPropertySymbolBuilder : ReflectionMemberSymbolBuilder, IReflecti PropertyBuilder? _builder; PropertyInfo _property; + ReflectionParameterTable _parameterTable; + /// /// Initializes a new instance. /// @@ -21,11 +23,12 @@ class ReflectionPropertySymbolBuilder : ReflectionMemberSymbolBuilder, IReflecti /// /// /// - public ReflectionPropertySymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol resolvingType, PropertyBuilder builder) : + public ReflectionPropertySymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbolBuilder resolvingModule, IReflectionTypeSymbolBuilder resolvingType, PropertyBuilder builder) : base(context, resolvingModule, resolvingType) { _builder = builder ?? throw new ArgumentNullException(nameof(builder)); _property = _builder; + _parameterTable = new ReflectionParameterTable(context, resolvingModule, this); } /// @@ -37,7 +40,27 @@ public ReflectionPropertySymbolBuilder(ReflectionSymbolContext context, IReflect /// public override MemberInfo UnderlyingMember => UnderlyingProperty; - #region IPropertySymbol + #region IReflectionPropertySymbolBuilder + + /// + public IReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter) + { + return _parameterTable.GetOrCreateParameterSymbol(parameter); + } + + #endregion + + #region IReflectionPropertySymbol + + /// + public IReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) + { + return _parameterTable.GetOrCreateParameterSymbol(parameter); + } + + #endregion + + #region IPropertySymbolBuilder /// public void SetConstant(object? defaultValue) @@ -80,7 +103,7 @@ public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) #region IPropertySymbol /// - public PropertyAttributes Attributes => UnderlyingProperty.Attributes; + public System.Reflection.PropertyAttributes Attributes => (System.Reflection.PropertyAttributes)UnderlyingProperty.Attributes; /// public bool CanRead => UnderlyingProperty.CanRead; @@ -169,7 +192,7 @@ public ITypeSymbol[] GetRequiredCustomModifiers() return ResolveTypeSymbols(UnderlyingProperty.GetRequiredCustomModifiers()); } -#endregion + #endregion /// public override void OnComplete() diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionSymbolBuilder.cs index aff7f0300..902317749 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionSymbolBuilder.cs @@ -1,4 +1,7 @@ -using IKVM.CoreLib.Symbols.Emit; +using System.Diagnostics.CodeAnalysis; +using System.Reflection.Emit; + +using IKVM.CoreLib.Symbols.Emit; namespace IKVM.CoreLib.Symbols.Reflection.Emit { @@ -19,6 +22,13 @@ protected ReflectionSymbolBuilder(ReflectionSymbolContext context) : } + /// + [return: NotNullIfNotNull("genericTypeParameter")] + public IReflectionGenericTypeParameterSymbolBuilder? ResolveGenericTypeParameterSymbol(GenericTypeParameterBuilder genericTypeParameter) + { + return Context.GetOrCreateGenericTypeParameterSymbol(genericTypeParameter); + } + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs index 8c64b611e..92a173aad 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs @@ -3,6 +3,7 @@ using System.Reflection.Emit; using System.Runtime.InteropServices; +using IKVM.CoreLib.Reflection; using IKVM.CoreLib.Symbols.Emit; namespace IKVM.CoreLib.Symbols.Reflection.Emit @@ -13,20 +14,31 @@ class ReflectionTypeSymbolBuilder : ReflectionMemberSymbolBuilder, IReflectionTy TypeBuilder? _builder; Type _type; - ReflectionTypeImpl _impl; + + ReflectionMethodTable _methodTable; + ReflectionFieldTable _fieldTable; + ReflectionPropertyTable _propertyTable; + ReflectionEventTable _eventTable; + ReflectionGenericTypeParameterTable _genericTypeParameterTable; + ReflectionTypeSpecTable _specTable; /// /// Initializes a new instance. /// /// - /// + /// /// - public ReflectionTypeSymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, TypeBuilder builder) : - base(context, resolvingModule, null) + public ReflectionTypeSymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbolBuilder module, TypeBuilder builder) : + base(context, module, null) { _builder = builder ?? throw new ArgumentNullException(nameof(builder)); _type = _builder; - _impl = new ReflectionTypeImpl(this); + _methodTable = new ReflectionMethodTable(context, module, this); + _fieldTable = new ReflectionFieldTable(context, module, this); + _propertyTable = new ReflectionPropertyTable(context, module, this); + _eventTable = new ReflectionEventTable(context, module, this); + _genericTypeParameterTable = new ReflectionGenericTypeParameterTable(context, module, this); + _specTable = new ReflectionTypeSpecTable(context, module, this); } /// @@ -38,6 +50,122 @@ public ReflectionTypeSymbolBuilder(ReflectionSymbolContext context, IReflectionM /// public TypeBuilder UnderlyingTypeBuilder => _builder ?? throw new InvalidOperationException(); + #region ReflectionTypeSymbol + + /// + public IReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) + { + return _methodTable.GetOrCreateConstructorSymbol(ctor); + } + + /// + public IReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method) + { + return _methodTable.GetOrCreateMethodBaseSymbol(method); + } + + /// + public IReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) + { + return _methodTable.GetOrCreateMethodSymbol(method); + } + + /// + public IReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) + { + return _fieldTable.GetOrCreateFieldSymbol(field); + } + + /// + public IReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) + { + return _propertyTable.GetOrCreatePropertySymbol(property); + } + + /// + public IReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) + { + return _eventTable.GetOrCreateEventSymbol(@event); + } + + /// + public IReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type genericTypeParameter) + { + return _genericTypeParameterTable.GetOrCreateGenericTypeParameterSymbol(genericTypeParameter); + } + + /// + public IReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeParameterSymbol(GenericTypeParameterBuilder genericTypeParameter) + { + return _genericTypeParameterTable.GetOrCreateGenericTypeParameterSymbol(genericTypeParameter); + } + + /// + public IReflectionTypeSymbol GetOrCreateSZArrayTypeSymbol() + { + return _specTable.GetOrCreateSZArrayTypeSymbol(); + } + + /// + public IReflectionTypeSymbol GetOrCreateArrayTypeSymbol(int rank) + { + return _specTable.GetOrCreateArrayTypeSymbol(rank); + } + + /// + public IReflectionTypeSymbol GetOrCreatePointerTypeSymbol() + { + return _specTable.GetOrCreatePointerTypeSymbol(); + } + + /// + public IReflectionTypeSymbol GetOrCreateByRefTypeSymbol() + { + return _specTable.GetOrCreateByRefTypeSymbol(); + } + + /// + public IReflectionTypeSymbol GetOrCreateGenericTypeSymbol(Type[] genericTypeDefinition) + { + return _specTable.GetOrCreateGenericTypeSymbol(genericTypeDefinition); + } + + #endregion + + #region IReflectionTypeSymbolBuilder + + /// + public IReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor) + { + return _methodTable.GetOrCreateConstructorSymbol(ctor); + } + + /// + public IReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method) + { + return _methodTable.GetOrCreateMethodSymbol(method); + } + + /// + public IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field) + { + return _fieldTable.GetOrCreateFieldSymbol(field); + } + + /// + public IReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property) + { + return _propertyTable.GetOrCreatePropertySymbol(property); + } + + /// + public IReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event) + { + return _eventTable.GetOrCreateEventSymbol(@event); + } + + #endregion + #region ITypeSymbolBuilder /// @@ -52,7 +180,7 @@ public IGenericTypeParameterSymbolBuilder[] DefineGenericParameters(params strin var l = UnderlyingTypeBuilder.DefineGenericParameters(names); var a = new IGenericTypeParameterSymbolBuilder[l.Length]; for (int i = 0; i < l.Length; i++) - a[i] = new ReflectionGenericTypeParameterSymbolBuilder(Context, ResolvingModule, this, null, l[i]); + a[i] = ResolveGenericTypeParameterSymbol(l[i]); return a; } @@ -64,75 +192,75 @@ public void AddInterfaceImplementation(ITypeSymbol interfaceType) } /// - public IConstructorSymbolBuilder DefineConstructor(MethodAttributes attributes, ITypeSymbol[]? parameterTypes) + public IConstructorSymbolBuilder DefineConstructor(System.Reflection.MethodAttributes attributes, ITypeSymbol[]? parameterTypes) { - return (IConstructorSymbolBuilder)ResolveConstructorSymbol(UnderlyingTypeBuilder.DefineConstructor(attributes, CallingConventions.Standard, parameterTypes?.Unpack())); + return ResolveConstructorSymbol(UnderlyingTypeBuilder.DefineConstructor((MethodAttributes)attributes, CallingConventions.Standard, parameterTypes?.Unpack())); } /// - public IConstructorSymbolBuilder DefineConstructor(MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol[]? parameterTypes) + public IConstructorSymbolBuilder DefineConstructor(System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, ITypeSymbol[]? parameterTypes) { - return (IConstructorSymbolBuilder)ResolveConstructorSymbol(UnderlyingTypeBuilder.DefineConstructor(attributes, callingConvention, parameterTypes?.Unpack())); + return ResolveConstructorSymbol(UnderlyingTypeBuilder.DefineConstructor((MethodAttributes)attributes, (CallingConventions)callingConvention, parameterTypes?.Unpack())); } /// - public IConstructorSymbolBuilder DefineConstructor(MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? requiredCustomModifiers, ITypeSymbol[][]? optionalCustomModifiers) + public IConstructorSymbolBuilder DefineConstructor(System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? requiredCustomModifiers, ITypeSymbol[][]? optionalCustomModifiers) { - return (IConstructorSymbolBuilder)ResolveConstructorSymbol(UnderlyingTypeBuilder.DefineConstructor(attributes, callingConvention, parameterTypes?.Unpack(), requiredCustomModifiers?.Unpack(), optionalCustomModifiers?.Unpack())); + return ResolveConstructorSymbol(UnderlyingTypeBuilder.DefineConstructor((MethodAttributes)attributes, (CallingConventions)callingConvention, parameterTypes?.Unpack(), requiredCustomModifiers?.Unpack(), optionalCustomModifiers?.Unpack())); } /// - public IConstructorSymbolBuilder DefineDefaultConstructor(MethodAttributes attributes) + public IConstructorSymbolBuilder DefineDefaultConstructor(System.Reflection.MethodAttributes attributes) { - return (IConstructorSymbolBuilder)ResolveConstructorSymbol(UnderlyingTypeBuilder.DefineDefaultConstructor(attributes)); + return ResolveConstructorSymbol(UnderlyingTypeBuilder.DefineDefaultConstructor((MethodAttributes)attributes)); } /// - public IEventSymbolBuilder DefineEvent(string name, EventAttributes attributes, ITypeSymbol eventtype) + public IEventSymbolBuilder DefineEvent(string name, System.Reflection.EventAttributes attributes, ITypeSymbol eventtype) { - return (IEventSymbolBuilder)ResolveEventSymbol(UnderlyingTypeBuilder.DefineEvent(name, attributes, eventtype.Unpack())); + return ResolveEventSymbol(UnderlyingTypeBuilder.DefineEvent(name, (EventAttributes)attributes, eventtype.Unpack())); } /// - public IFieldSymbolBuilder DefineField(string fieldName, ITypeSymbol type, FieldAttributes attributes) + public IFieldSymbolBuilder DefineField(string fieldName, ITypeSymbol type, System.Reflection.FieldAttributes attributes) { - return (IFieldSymbolBuilder)ResolveFieldSymbol(UnderlyingTypeBuilder.DefineField(fieldName, type.Unpack(), attributes)); + return ResolveFieldSymbol(UnderlyingTypeBuilder.DefineField(fieldName, type.Unpack(), (FieldAttributes)attributes)); } /// - public IFieldSymbolBuilder DefineField(string fieldName, ITypeSymbol type, ITypeSymbol[]? requiredCustomModifiers, ITypeSymbol[]? optionalCustomModifiers, FieldAttributes attributes) + public IFieldSymbolBuilder DefineField(string fieldName, ITypeSymbol type, ITypeSymbol[]? requiredCustomModifiers, ITypeSymbol[]? optionalCustomModifiers, System.Reflection.FieldAttributes attributes) { - return (IFieldSymbolBuilder)ResolveFieldSymbol(UnderlyingTypeBuilder.DefineField(fieldName, type.Unpack(), requiredCustomModifiers?.Unpack(), optionalCustomModifiers?.Unpack(), attributes)); + return ResolveFieldSymbol(UnderlyingTypeBuilder.DefineField(fieldName, type.Unpack(), requiredCustomModifiers?.Unpack(), optionalCustomModifiers?.Unpack(), (FieldAttributes)attributes)); } /// - public IMethodSymbolBuilder DefineMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers) + public IMethodSymbolBuilder DefineMethod(string name, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers) { - return (IMethodSymbolBuilder)ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, attributes, callingConvention, returnType?.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack())); + return ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, (MethodAttributes)attributes, (CallingConventions)callingConvention, returnType?.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack())); } /// - public IMethodSymbolBuilder DefineMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes) + public IMethodSymbolBuilder DefineMethod(string name, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes) { - return (IMethodSymbolBuilder)ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, attributes, callingConvention, returnType?.Unpack(), parameterTypes?.Unpack())); + return ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, (MethodAttributes)attributes, (CallingConventions)callingConvention, returnType?.Unpack(), parameterTypes?.Unpack())); } /// - public IMethodSymbolBuilder DefineMethod(string name, MethodAttributes attributes, CallingConventions callingConvention) + public IMethodSymbolBuilder DefineMethod(string name, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention) { - return (IMethodSymbolBuilder)ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, attributes, callingConvention)); + return ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, (MethodAttributes)attributes, (CallingConventions)callingConvention)); } /// - public IMethodSymbolBuilder DefineMethod(string name, MethodAttributes attributes) + public IMethodSymbolBuilder DefineMethod(string name, System.Reflection.MethodAttributes attributes) { - return (IMethodSymbolBuilder)ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, attributes)); + return ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, (MethodAttributes)attributes)); } /// - public IMethodSymbolBuilder DefineMethod(string name, MethodAttributes attributes, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes) + public IMethodSymbolBuilder DefineMethod(string name, System.Reflection.MethodAttributes attributes, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes) { - return (IMethodSymbolBuilder)ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, attributes, returnType?.Unpack(), parameterTypes?.Unpack())); + return ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, (MethodAttributes)attributes, returnType?.Unpack(), parameterTypes?.Unpack())); } /// @@ -142,21 +270,21 @@ public void DefineMethodOverride(IMethodSymbol methodInfoBody, IMethodSymbol met } /// - public ITypeSymbolBuilder DefineNestedType(string name, TypeAttributes attr, ITypeSymbol? parent, ITypeSymbol[]? interfaces) + public ITypeSymbolBuilder DefineNestedType(string name, System.Reflection.TypeAttributes attr, ITypeSymbol? parent, ITypeSymbol[]? interfaces) { - return (ITypeSymbolBuilder)ResolveTypeSymbol(UnderlyingTypeBuilder.DefineNestedType(name, attr, parent?.Unpack(), interfaces?.Unpack())); + return ResolveTypeSymbol(UnderlyingTypeBuilder.DefineNestedType(name, (TypeAttributes)attr, parent?.Unpack(), interfaces?.Unpack())); } /// - public ITypeSymbolBuilder DefineNestedType(string name, TypeAttributes attr, ITypeSymbol? parent, PackingSize packSize, int typeSize) + public ITypeSymbolBuilder DefineNestedType(string name, System.Reflection.TypeAttributes attr, ITypeSymbol? parent, System.Reflection.Emit.PackingSize packSize, int typeSize) { - return (ITypeSymbolBuilder)ResolveTypeSymbol(UnderlyingTypeBuilder.DefineNestedType(name, attr, parent?.Unpack(), packSize, typeSize)); + return ResolveTypeSymbol(UnderlyingTypeBuilder.DefineNestedType(name, (TypeAttributes)attr, parent?.Unpack(), (PackingSize)packSize, typeSize)); } /// - public ITypeSymbolBuilder DefineNestedType(string name, TypeAttributes attr, ITypeSymbol? parent, PackingSize packSize) + public ITypeSymbolBuilder DefineNestedType(string name, System.Reflection.TypeAttributes attr, ITypeSymbol? parent, System.Reflection.Emit.PackingSize packSize) { - return (ITypeSymbolBuilder)ResolveTypeSymbol(UnderlyingTypeBuilder.DefineNestedType(name, attr, parent?.Unpack(), packSize)); + return (ITypeSymbolBuilder)ResolveTypeSymbol(UnderlyingTypeBuilder.DefineNestedType(name, (TypeAttributes)attr, parent?.Unpack(), (PackingSize)packSize)); } /// @@ -166,63 +294,63 @@ public ITypeSymbolBuilder DefineNestedType(string name) } /// - public ITypeSymbolBuilder DefineNestedType(string name, TypeAttributes attr, ITypeSymbol? parent) + public ITypeSymbolBuilder DefineNestedType(string name, System.Reflection.TypeAttributes attr, ITypeSymbol? parent) { - return (ITypeSymbolBuilder)ResolveTypeSymbol(UnderlyingTypeBuilder.DefineNestedType(name, attr, parent?.Unpack())); + return (ITypeSymbolBuilder)ResolveTypeSymbol(UnderlyingTypeBuilder.DefineNestedType(name, (TypeAttributes)attr, parent?.Unpack())); } /// - public ITypeSymbolBuilder DefineNestedType(string name, TypeAttributes attr) + public ITypeSymbolBuilder DefineNestedType(string name, System.Reflection.TypeAttributes attr) { - return (ITypeSymbolBuilder)ResolveTypeSymbol(UnderlyingTypeBuilder.DefineNestedType(name, attr)); + return (ITypeSymbolBuilder)ResolveTypeSymbol(UnderlyingTypeBuilder.DefineNestedType(name, (TypeAttributes)attr)); } /// - public ITypeSymbolBuilder DefineNestedType(string name, TypeAttributes attr, ITypeSymbol? parent, int typeSize) + public ITypeSymbolBuilder DefineNestedType(string name, System.Reflection.TypeAttributes attr, ITypeSymbol? parent, int typeSize) { - return (ITypeSymbolBuilder)ResolveTypeSymbol(UnderlyingTypeBuilder.DefineNestedType(name, attr, parent?.Unpack(), typeSize)); + return (ITypeSymbolBuilder)ResolveTypeSymbol(UnderlyingTypeBuilder.DefineNestedType(name, (TypeAttributes)attr, parent?.Unpack(), typeSize)); } /// - public IMethodSymbolBuilder DefinePInvokeMethod(string name, string dllName, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet) + public IMethodSymbolBuilder DefinePInvokeMethod(string name, string dllName, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet) { - return (IMethodSymbolBuilder)ResolveMethodSymbol(UnderlyingTypeBuilder.DefinePInvokeMethod(name, dllName, attributes, callingConvention, returnType?.Unpack(), parameterTypes?.Unpack(), nativeCallConv, nativeCharSet)); + return (IMethodSymbolBuilder)ResolveMethodSymbol(UnderlyingTypeBuilder.DefinePInvokeMethod(name, dllName, (MethodAttributes)attributes, (CallingConventions)callingConvention, returnType?.Unpack(), parameterTypes?.Unpack(), nativeCallConv, nativeCharSet)); } /// - public IMethodSymbolBuilder DefinePInvokeMethod(string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet) + public IMethodSymbolBuilder DefinePInvokeMethod(string name, string dllName, string entryName, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet) { - return (IMethodSymbolBuilder)ResolveMethodSymbol(UnderlyingTypeBuilder.DefinePInvokeMethod(name, dllName, entryName, attributes, callingConvention, returnType?.Unpack(), parameterTypes?.Unpack(), nativeCallConv, nativeCharSet)); + return (IMethodSymbolBuilder)ResolveMethodSymbol(UnderlyingTypeBuilder.DefinePInvokeMethod(name, dllName, entryName, (MethodAttributes)attributes, (CallingConventions)callingConvention, returnType?.Unpack(), parameterTypes?.Unpack(), nativeCallConv, nativeCharSet)); } /// - public IMethodSymbolBuilder DefinePInvokeMethod(string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers, CallingConvention nativeCallConv, CharSet nativeCharSet) + public IMethodSymbolBuilder DefinePInvokeMethod(string name, string dllName, string entryName, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers, CallingConvention nativeCallConv, CharSet nativeCharSet) { - return (IMethodSymbolBuilder)ResolveMethodSymbol(UnderlyingTypeBuilder.DefinePInvokeMethod(name, dllName, entryName, attributes, callingConvention, returnType?.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack(), nativeCallConv, nativeCharSet)); + return (IMethodSymbolBuilder)ResolveMethodSymbol(UnderlyingTypeBuilder.DefinePInvokeMethod(name, dllName, entryName, (MethodAttributes)attributes, (CallingConventions)callingConvention, returnType?.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack(), nativeCallConv, nativeCharSet)); } /// - public IPropertySymbolBuilder DefineProperty(string name, PropertyAttributes attributes, ITypeSymbol returnType, ITypeSymbol[]? parameterTypes) + public IPropertySymbolBuilder DefineProperty(string name, System.Reflection.PropertyAttributes attributes, ITypeSymbol returnType, ITypeSymbol[]? parameterTypes) { - return (IPropertySymbolBuilder)ResolvePropertySymbol(UnderlyingTypeBuilder.DefineProperty(name, attributes, returnType.Unpack(), parameterTypes?.Unpack())); + return (IPropertySymbolBuilder)ResolvePropertySymbol(UnderlyingTypeBuilder.DefineProperty(name, (PropertyAttributes)attributes, returnType.Unpack(), parameterTypes?.Unpack())); } /// - public IPropertySymbolBuilder DefineProperty(string name, PropertyAttributes attributes, CallingConventions callingConvention, ITypeSymbol returnType, ITypeSymbol[]? parameterTypes) + public IPropertySymbolBuilder DefineProperty(string name, System.Reflection.PropertyAttributes attributes, System.Reflection.CallingConventions callingConvention, ITypeSymbol returnType, ITypeSymbol[]? parameterTypes) { - return (IPropertySymbolBuilder)ResolvePropertySymbol(UnderlyingTypeBuilder.DefineProperty(name, attributes, callingConvention, returnType.Unpack(), parameterTypes?.Unpack())); + return (IPropertySymbolBuilder)ResolvePropertySymbol(UnderlyingTypeBuilder.DefineProperty(name, (PropertyAttributes)attributes, (CallingConventions)callingConvention, returnType.Unpack(), parameterTypes?.Unpack())); } /// - public IPropertySymbolBuilder DefineProperty(string name, PropertyAttributes attributes, ITypeSymbol returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers) + public IPropertySymbolBuilder DefineProperty(string name, System.Reflection.PropertyAttributes attributes, ITypeSymbol returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers) { - return (IPropertySymbolBuilder)ResolvePropertySymbol(UnderlyingTypeBuilder.DefineProperty(name, attributes, returnType.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack())); + return (IPropertySymbolBuilder)ResolvePropertySymbol(UnderlyingTypeBuilder.DefineProperty(name, (PropertyAttributes)attributes, returnType.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack())); } /// - public IPropertySymbolBuilder DefineProperty(string name, PropertyAttributes attributes, CallingConventions callingConvention, ITypeSymbol returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers) + public IPropertySymbolBuilder DefineProperty(string name, System.Reflection.PropertyAttributes attributes, System.Reflection.CallingConventions callingConvention, ITypeSymbol returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers) { - return (IPropertySymbolBuilder)ResolvePropertySymbol(UnderlyingTypeBuilder.DefineProperty(name, attributes, callingConvention, returnType.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack())); + return (IPropertySymbolBuilder)ResolvePropertySymbol(UnderlyingTypeBuilder.DefineProperty(name, (PropertyAttributes)attributes, (CallingConventions)callingConvention, returnType.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack())); } /// @@ -247,506 +375,525 @@ public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) #region ITypeSymbol /// - public TypeAttributes Attributes => _impl.Attributes; + public IAssemblySymbol Assembly => ResolveAssemblySymbol(UnderlyingType.Assembly); /// - public IAssemblySymbol Assembly => _impl.Assembly; + public string? AssemblyQualifiedName => UnderlyingType.AssemblyQualifiedName; /// - public IMethodBaseSymbol? DeclaringMethod => _impl.DeclaringMethod; + public System.Reflection.TypeAttributes Attributes => (System.Reflection.TypeAttributes)UnderlyingType.Attributes; /// - public string? AssemblyQualifiedName => _impl.AssemblyQualifiedName; + public ITypeSymbol? BaseType => ResolveTypeSymbol(UnderlyingType.BaseType); /// - public string? FullName => _impl.FullName; + public bool ContainsGenericParameters => UnderlyingType.ContainsGenericParameters; /// - public string? Namespace => _impl.Namespace; + public IMethodBaseSymbol? DeclaringMethod => ResolveMethodBaseSymbol(UnderlyingType.DeclaringMethod); /// - public TypeCode TypeCode => _impl.TypeCode; + public string? FullName => UnderlyingType.FullName; /// - public ITypeSymbol? BaseType => _impl.BaseType; + public string? Namespace => UnderlyingType.Namespace; /// - public bool ContainsGenericParameters => _impl.ContainsGenericParameters; + public System.Reflection.GenericParameterAttributes GenericParameterAttributes => (System.Reflection.GenericParameterAttributes)UnderlyingType.GenericParameterAttributes; /// - public GenericParameterAttributes GenericParameterAttributes => _impl.GenericParameterAttributes; + public int GenericParameterPosition => UnderlyingType.GenericParameterPosition; /// - public int GenericParameterPosition => _impl.GenericParameterPosition; + public ITypeSymbol[] GenericTypeArguments => ResolveTypeSymbols(UnderlyingType.GenericTypeArguments); /// - public ITypeSymbol[] GenericTypeArguments => _impl.GenericTypeArguments; + public bool HasElementType => UnderlyingType.HasElementType; /// - public bool IsConstructedGenericType => _impl.IsConstructedGenericType; + public TypeCode TypeCode => Type.GetTypeCode(UnderlyingType); /// - public bool IsGenericType => _impl.IsGenericType; + public bool IsAbstract => UnderlyingType.IsAbstract; /// - public bool IsGenericTypeDefinition => _impl.IsGenericTypeDefinition; + public bool IsSZArray => UnderlyingType.IsSZArray(); /// - public bool IsGenericParameter => _impl.IsGenericParameter; + public bool IsArray => UnderlyingType.IsArray; /// - public bool IsAutoLayout => _impl.IsAutoLayout; + public bool IsAutoLayout => UnderlyingType.IsAutoLayout; /// - public bool IsExplicitLayout => _impl.IsExplicitLayout; + public bool IsExplicitLayout => UnderlyingType.IsExplicitLayout; /// - public bool IsLayoutSequential => _impl.IsLayoutSequential; + public bool IsByRef => UnderlyingType.IsByRef; /// - public bool HasElementType => _impl.HasElementType; + public bool IsClass => UnderlyingType.IsClass; /// - public bool IsClass => _impl.IsClass; + public bool IsEnum => UnderlyingType.IsEnum; /// - public bool IsValueType => _impl.IsValueType; + public bool IsInterface => UnderlyingType.IsInterface; /// - public bool IsInterface => _impl.IsInterface; + public bool IsConstructedGenericType => UnderlyingType.IsConstructedGenericType; /// - public bool IsPrimitive => _impl.IsPrimitive; + public bool IsGenericParameter => UnderlyingType.IsGenericParameter; /// - public bool IsSZArray => _impl.IsSZArray; + public bool IsGenericType => UnderlyingType.IsGenericType; /// - public bool IsArray => _impl.IsArray; + public bool IsGenericTypeDefinition => UnderlyingType.IsGenericTypeDefinition; /// - public bool IsEnum => _impl.IsEnum; + public bool IsLayoutSequential => UnderlyingType.IsLayoutSequential; /// - public bool IsPointer => _impl.IsPointer; + public bool IsNested => UnderlyingType.IsNested; /// - public bool IsFunctionPointer => _impl.IsFunctionPointer; + public bool IsNestedAssembly => UnderlyingType.IsNestedAssembly; /// - public bool IsUnmanagedFunctionPointer => _impl.IsUnmanagedFunctionPointer; + public bool IsNestedFamANDAssem => UnderlyingType.IsNestedFamANDAssem; /// - public bool IsByRef => _impl.IsByRef; + public bool IsNestedFamORAssem => UnderlyingType.IsNestedFamORAssem; /// - public bool IsAbstract => _impl.IsAbstract; + public bool IsNestedFamily => UnderlyingType.IsNestedFamily; /// - public bool IsSealed => _impl.IsSealed; + public bool IsNestedPrivate => UnderlyingType.IsNestedPrivate; /// - public bool IsVisible => _impl.IsVisible; + public bool IsNestedPublic => UnderlyingType.IsNestedPublic; /// - public bool IsPublic => _impl.IsPublic; + public bool IsNotPublic => UnderlyingType.IsNotPublic; + + /// + public bool IsPointer => UnderlyingType.IsPointer; + +#if NET8_0_OR_GREATER /// - public bool IsNotPublic => _impl.IsNotPublic; + public bool IsFunctionPointer => UnderlyingType.IsFunctionPointer; /// - public bool IsNested => _impl.IsNested; + public bool IsUnmanagedFunctionPointer => UnderlyingType.IsUnmanagedFunctionPointer; + +#else /// - public bool IsNestedAssembly => _impl.IsNestedAssembly; + public bool IsFunctionPointer => throw new NotImplementedException(); /// - public bool IsNestedFamANDAssem => _impl.IsNestedFamANDAssem; + public bool IsUnmanagedFunctionPointer => throw new NotImplementedException(); + +#endif /// - public bool IsNestedFamily => _impl.IsNestedFamily; + public bool IsPrimitive => UnderlyingType.IsPrimitive; /// - public bool IsNestedFamORAssem => _impl.IsNestedFamORAssem; + public bool IsPublic => UnderlyingType.IsPublic; /// - public bool IsNestedPrivate => _impl.IsNestedPrivate; + public bool IsSealed => UnderlyingType.IsSealed; /// - public bool IsNestedPublic => _impl.IsNestedPublic; + public bool IsSerializable => UnderlyingType.IsSerializable; /// - public bool IsSerializable => _impl.IsSerializable; + public bool IsValueType => UnderlyingType.IsValueType; /// - public bool IsSignatureType => _impl.IsSignatureType; + public bool IsVisible => UnderlyingType.IsVisible; /// - public bool IsSpecialName => _impl.IsSpecialName; + public bool IsSignatureType => throw new NotImplementedException(); /// - public IConstructorSymbol? TypeInitializer => _impl.TypeInitializer; + public bool IsSpecialName => UnderlyingType.IsSpecialName; /// - public override bool IsComplete => _builder == null; + public IConstructorSymbol? TypeInitializer => ResolveConstructorSymbol(UnderlyingType.TypeInitializer); /// public int GetArrayRank() { - return _impl.GetArrayRank(); + return UnderlyingType.GetArrayRank(); } /// - public IMemberSymbol[] GetDefaultMembers() + public IConstructorSymbol? GetConstructor(System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) { - return _impl.GetDefaultMembers(); + return ResolveConstructorSymbol(UnderlyingType.GetConstructor((BindingFlags)bindingAttr, binder: null, types.Unpack(), modifiers: null)); } /// - public ITypeSymbol? GetElementType() + public IConstructorSymbol? GetConstructor(ITypeSymbol[] types) { - return _impl.GetElementType(); + return ResolveConstructorSymbol(UnderlyingType.GetConstructor(types.Unpack())); } /// - public string? GetEnumName(object value) + public IConstructorSymbol[] GetConstructors() { - return _impl.GetEnumName(value); + return ResolveConstructorSymbols(UnderlyingType.GetConstructors()); } /// - public string[] GetEnumNames() + public IConstructorSymbol[] GetConstructors(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetEnumNames(); + return ResolveConstructorSymbols(UnderlyingType.GetConstructors((BindingFlags)bindingAttr)); } /// - public ITypeSymbol GetEnumUnderlyingType() + public IMemberSymbol[] GetDefaultMembers() { - return _impl.GetEnumUnderlyingType(); + return ResolveMemberSymbols(UnderlyingType.GetDefaultMembers()); } /// - public ITypeSymbol[] GetGenericArguments() + public ITypeSymbol? GetElementType() { - return _impl.GetGenericArguments(); + return ResolveTypeSymbol(UnderlyingType.GetElementType()); } /// - public ITypeSymbol[] GetGenericParameterConstraints() + public string? GetEnumName(object value) { - return _impl.GetGenericParameterConstraints(); + return UnderlyingType.GetEnumName(value); } /// - public ITypeSymbol GetGenericTypeDefinition() + public string[] GetEnumNames() { - return _impl.GetGenericTypeDefinition(); + return UnderlyingType.GetEnumNames(); } /// - public ITypeSymbol? GetInterface(string name) + public ITypeSymbol GetEnumUnderlyingType() { - return _impl.GetInterface(name); + return ResolveTypeSymbol(UnderlyingType.GetEnumUnderlyingType()); } /// - public ITypeSymbol? GetInterface(string name, bool ignoreCase) + public Array GetEnumValues() { - return _impl.GetInterface(name, ignoreCase); + return UnderlyingType.GetEnumValues(); } /// - public ITypeSymbol[] GetInterfaces(bool inherit = true) + public IEventSymbol? GetEvent(string name) { - return _impl.GetInterfaces(inherit); + return ResolveEventSymbol(UnderlyingType.GetEvent(name)); } /// - public InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) + public IEventSymbol? GetEvent(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetInterfaceMap(interfaceType); + return ResolveEventSymbol(UnderlyingType.GetEvent(name, (BindingFlags)bindingAttr)); } /// - public IMemberSymbol[] GetMember(string name) + public IEventSymbol[] GetEvents() { - return _impl.GetMember(name); + return ResolveEventSymbols(UnderlyingType.GetEvents()); } /// - public IMemberSymbol[] GetMember(string name, BindingFlags bindingAttr) + public IEventSymbol[] GetEvents(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMember(name, bindingAttr); + return ResolveEventSymbols(UnderlyingType.GetEvents((BindingFlags)bindingAttr)); } /// - public IMemberSymbol[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) + public IFieldSymbol? GetField(string name) { - return _impl.GetMember(name, type, bindingAttr); + return ResolveFieldSymbol(UnderlyingType.GetField(name)); } /// - public IMemberSymbol[] GetMembers() + public IFieldSymbol? GetField(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMembers(); + return ResolveFieldSymbol(UnderlyingType.GetField(name, (BindingFlags)bindingAttr)); } /// - public IMemberSymbol[] GetMembers(BindingFlags bindingAttr) + public IFieldSymbol[] GetFields() { - return _impl.GetMembers(bindingAttr); + return ResolveFieldSymbols(UnderlyingType.GetFields()); } - public IConstructorSymbol? GetConstructor(ITypeSymbol[] types) + /// + public IFieldSymbol[] GetFields(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetConstructor(types); + return ResolveFieldSymbols(UnderlyingType.GetFields((BindingFlags)bindingAttr)); } /// - public IConstructorSymbol? GetConstructor(BindingFlags bindingAttr, ITypeSymbol[] types) + public ITypeSymbol[] GetGenericArguments() { - return _impl.GetConstructor(bindingAttr, types); + return ResolveTypeSymbols(UnderlyingType.GetGenericArguments()); } /// - public IConstructorSymbol[] GetConstructors() + public ITypeSymbol[] GetGenericParameterConstraints() { - return _impl.GetConstructors(); + return ResolveTypeSymbols(UnderlyingType.GetGenericParameterConstraints()); } /// - public IConstructorSymbol[] GetConstructors(BindingFlags bindingAttr) + public ITypeSymbol GetGenericTypeDefinition() { - return _impl.GetConstructors(bindingAttr); + return ResolveTypeSymbol(UnderlyingType.GetGenericTypeDefinition()); } /// - public IFieldSymbol? GetField(string name) + public ITypeSymbol? GetInterface(string name) { - return _impl.GetField(name); + return ResolveTypeSymbol(UnderlyingType.GetInterface(name)); } /// - public IFieldSymbol? GetField(string name, BindingFlags bindingAttr) + public ITypeSymbol? GetInterface(string name, bool ignoreCase) { - return _impl.GetField(name, bindingAttr); + return ResolveTypeSymbol(UnderlyingType.GetInterface(name, ignoreCase)); } /// - public IFieldSymbol[] GetFields() + public InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) { - return _impl.GetFields(); + throw new NotImplementedException(); } /// - public IFieldSymbol[] GetFields(BindingFlags bindingAttr) + public ITypeSymbol[] GetInterfaces(bool inherit = true) { - return _impl.GetFields(bindingAttr); + if (inherit) + return ResolveTypeSymbols(UnderlyingType.GetInterfaces()); + else + throw new NotImplementedException(); } /// - public IMethodSymbol? GetMethod(string name) + public IMemberSymbol[] GetMember(string name) { - return _impl.GetMethod(name); + return ResolveMemberSymbols(UnderlyingType.GetMember(name)); } /// - public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) + public IMemberSymbol[] GetMember(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMethod(name, types); + return ResolveMemberSymbols(UnderlyingType.GetMember(name, (BindingFlags)bindingAttr)); } /// - public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr) + public IMemberSymbol[] GetMember(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMethod(name, bindingAttr); + return ResolveMemberSymbols(UnderlyingType.GetMember(name, (MemberTypes)type, (BindingFlags)bindingAttr)); } /// - public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types) + public IMemberSymbol[] GetMembers(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMethod(name, bindingAttr, types); + return ResolveMemberSymbols(UnderlyingType.GetMembers((BindingFlags)bindingAttr)); } /// - public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers) + public IMemberSymbol[] GetMembers() { - return _impl.GetMethod(name, bindingAttr, callConvention, types, modifiers); + return ResolveMemberSymbols(UnderlyingType.GetMembers()); } /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMethod(name, genericParameterCount, bindingAttr, callConvention, types, modifiers); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr)); } /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, ITypeSymbol[] types, ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) { - return _impl.GetMethod(name, genericParameterCount, bindingAttr, types, modifiers); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, types.Unpack())); } /// - public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types, ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) { - return _impl.GetMethod(name, bindingAttr, types, modifiers); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), null)); } /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name) { - return _impl.GetMethod(name, genericParameterCount, types, modifiers); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name)); } /// - public IMethodSymbol[] GetMethods() + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return _impl.GetMethods(); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, (CallingConventions)callConvention, types.Unpack(), modifiers?.Unpack())); } /// - public IMethodSymbol[] GetMethods(BindingFlags bindingAttr) + public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return _impl.GetMethods(bindingAttr); + throw new NotImplementedException(); } /// - public IPropertySymbol? GetProperty(string name) + public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return _impl.GetProperty(name); + throw new NotImplementedException(); } /// - public IPropertySymbol? GetProperty(string name, BindingFlags bindingAttr) + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return _impl.GetProperty(name, bindingAttr); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), modifiers?.Unpack())); } /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol[] types) + public IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return _impl.GetProperty(name, types); + throw new NotImplementedException(); } /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types) + public IMethodSymbol[] GetMethods(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetProperty(name, returnType, types); + return ResolveMethodSymbols(UnderlyingType.GetMethods((BindingFlags)bindingAttr)); } /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) + public IMethodSymbol[] GetMethods() { - return _impl.GetProperty(name, returnType); + return ResolveMethodSymbols(UnderlyingType.GetMethods()); } /// - public IPropertySymbol[] GetProperties() + public ITypeSymbol? GetNestedType(string name) { - return _impl.GetProperties(); + return ResolveTypeSymbol(UnderlyingType.GetNestedType(name)); } /// - public IPropertySymbol[] GetProperties(BindingFlags bindingAttr) + public ITypeSymbol? GetNestedType(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetProperties(bindingAttr); + return ResolveTypeSymbol(UnderlyingType.GetNestedType(name, (BindingFlags)bindingAttr)); } /// - public IEventSymbol? GetEvent(string name) + public ITypeSymbol[] GetNestedTypes() { - return _impl.GetEvent(name); + return ResolveTypeSymbols(UnderlyingType.GetNestedTypes()); } /// - public IEventSymbol? GetEvent(string name, BindingFlags bindingAttr) + public ITypeSymbol[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetEvent(name, bindingAttr); + return ResolveTypeSymbols(UnderlyingType.GetNestedTypes((BindingFlags)bindingAttr)); } /// - public IEventSymbol[] GetEvents() + public IPropertySymbol[] GetProperties() { - return _impl.GetEvents(); + return ResolvePropertySymbols(UnderlyingType.GetProperties()); } /// - public IEventSymbol[] GetEvents(BindingFlags bindingAttr) + public IPropertySymbol[] GetProperties(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetEvents(bindingAttr); + return ResolvePropertySymbols(UnderlyingType.GetProperties((BindingFlags)bindingAttr)); } /// - public ITypeSymbol? GetNestedType(string name) + public IPropertySymbol? GetProperty(string name, ITypeSymbol[] types) { - return _impl.GetNestedType(name); + return ResolvePropertySymbol(UnderlyingType.GetProperty(name, types.Unpack())); } /// - public ITypeSymbol? GetNestedType(string name, BindingFlags bindingAttr) + public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types) { - return _impl.GetNestedType(name, bindingAttr); + return ResolvePropertySymbol(UnderlyingType.GetProperty(name, returnType?.Unpack(), types.Unpack())); } /// - public ITypeSymbol[] GetNestedTypes() + public IPropertySymbol? GetProperty(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetNestedTypes(); + return ResolvePropertySymbol(UnderlyingType.GetProperty(name, (BindingFlags)bindingAttr)); } /// - public ITypeSymbol[] GetNestedTypes(BindingFlags bindingAttr) + public IPropertySymbol? GetProperty(string name) { - return _impl.GetNestedTypes(); + return ResolvePropertySymbol(UnderlyingType.GetProperty(name)); } /// - public bool IsAssignableFrom(ITypeSymbol? c) + public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) { - return _impl.IsAssignableFrom(c); + return ResolvePropertySymbol(UnderlyingType.GetProperty(name, returnType?.Unpack())); } /// - public bool IsSubclassOf(ITypeSymbol c) + public bool IsAssignableFrom(ITypeSymbol? c) { - return _impl.IsSubclassOf(c); + return UnderlyingType.IsAssignableFrom(c?.Unpack()); } /// public bool IsEnumDefined(object value) { - return _impl.IsEnumDefined(value); + return UnderlyingType.IsEnumDefined(value); + } + + /// + public bool IsSubclassOf(ITypeSymbol c) + { + return UnderlyingType.IsSubclassOf(c.Unpack()); } /// public ITypeSymbol MakeArrayType() { - return _impl.MakeArrayType(); + return ResolveTypeSymbol(_type.MakeArrayType()); } /// public ITypeSymbol MakeArrayType(int rank) { - return _impl.MakeArrayType(rank); + return ResolveTypeSymbol(_type.MakeArrayType(rank)); } /// public ITypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments) { - return _impl.MakeGenericType(typeArguments); + return ResolveTypeSymbol(_type.MakeGenericType(typeArguments.Unpack())); } /// public ITypeSymbol MakePointerType() { - return _impl.MakePointerType(); + return ResolveTypeSymbol(_type.MakePointerType()); } /// public ITypeSymbol MakeByRefType() { - return _impl.MakeByRefType(); + return ResolveTypeSymbol(_type.MakeByRefType()); } #endregion @@ -758,7 +905,10 @@ public void Complete() { // complete type if (_builder.IsCreated() == false) - _builder.CreateType(); + { + _type = _builder.CreateType()!; + _builder = null; + } // force module to reresolve Context.GetOrCreateModuleSymbol(ResolvingModule.UnderlyingModule); @@ -771,9 +921,6 @@ public override void OnComplete() { const BindingFlags DefaultBindingFlags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static; - _type = ResolvingModule.UnderlyingModule.ResolveType(MetadataToken); - _builder = null; - foreach (var i in GetGenericArguments()) if (i is IReflectionGenericTypeParameterSymbolBuilder b) b.OnComplete(); diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionAssemblySymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionAssemblySymbol.cs index c16db0d74..b85865404 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionAssemblySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionAssemblySymbol.cs @@ -1,7 +1,4 @@ using System.Reflection; -using System.Reflection.Emit; - -using IKVM.CoreLib.Symbols.Reflection.Emit; namespace IKVM.CoreLib.Symbols.Reflection { @@ -21,13 +18,6 @@ interface IReflectionAssemblySymbol : IReflectionSymbol, IAssemblySymbol /// IReflectionModuleSymbol GetOrCreateModuleSymbol(Module module); - /// - /// Gets or creates a for the specified . - /// - /// - /// - IReflectionModuleSymbolBuilder GetOrCreateModuleSymbol(ModuleBuilder module); - } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionEventSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionEventSymbol.cs index 33eca5d42..09a99ae06 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionEventSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionEventSymbol.cs @@ -1,9 +1,15 @@ -namespace IKVM.CoreLib.Symbols.Reflection +using System.Reflection; + +namespace IKVM.CoreLib.Symbols.Reflection { interface IReflectionEventSymbol : IReflectionMemberSymbol, IEventSymbol { + /// + /// Gets the underlying . + /// + EventInfo UnderlyingEvent { get; } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMethodBaseSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMethodBaseSymbol.cs index 13ccd1ef9..9e0105610 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMethodBaseSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMethodBaseSymbol.cs @@ -11,6 +11,13 @@ interface IReflectionMethodBaseSymbol : IReflectionMemberSymbol, IMethodBaseSymb /// MethodBase UnderlyingMethodBase { get; } + /// + /// Gets or creates a for the given . + /// + /// + /// + public IReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter); + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMethodSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMethodSymbol.cs index a806c9195..6d17a00c4 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMethodSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMethodSymbol.cs @@ -1,4 +1,5 @@ -using System.Reflection; +using System; +using System.Reflection; namespace IKVM.CoreLib.Symbols.Reflection { @@ -11,6 +12,20 @@ interface IReflectionMethodSymbol : IReflectionMethodBaseSymbol, IMethodSymbol /// MethodInfo UnderlyingMethod { get; } + /// + /// Gets or creates a for the given generic type parameter. + /// + /// + /// + IReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type genericTypeParameter); + + /// + /// Gets or creates a for the given generic version of this method definition. + /// + /// + /// + IReflectionMethodSymbol GetOrCreateGenericMethodSymbol(MethodInfo method); + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionModuleSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionModuleSymbol.cs index c4b936129..d91499c77 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionModuleSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionModuleSymbol.cs @@ -1,8 +1,5 @@ using System; using System.Reflection; -using System.Reflection.Emit; - -using IKVM.CoreLib.Symbols.Reflection.Emit; namespace IKVM.CoreLib.Symbols.Reflection { @@ -28,11 +25,11 @@ interface IReflectionModuleSymbol : IReflectionSymbol, IModuleSymbol IReflectionTypeSymbol GetOrCreateTypeSymbol(Type type); /// - /// Gets or creates a for the specified . + /// Gets or creates a for the specified . /// - /// + /// /// - IReflectionTypeSymbolBuilder GetOrCreateTypeSymbol(TypeBuilder type); + IReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method); /// /// Gets or creates a for the specified . @@ -41,13 +38,6 @@ interface IReflectionModuleSymbol : IReflectionSymbol, IModuleSymbol /// IReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor); - /// - /// Gets or creates a for the specified . - /// - /// - /// - IReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor); - /// /// Gets or creates a for the specified . /// @@ -55,13 +45,6 @@ interface IReflectionModuleSymbol : IReflectionSymbol, IModuleSymbol /// IReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method); - /// - /// Gets or creates a for the specified . - /// - /// - /// - IReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method); - /// /// Gets or creates a for the specified . /// @@ -69,13 +52,6 @@ interface IReflectionModuleSymbol : IReflectionSymbol, IModuleSymbol /// IReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field); - /// - /// Gets or creates a for the specified . - /// - /// - /// - IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field); - /// /// Gets or creates a for the specified . /// @@ -83,13 +59,6 @@ interface IReflectionModuleSymbol : IReflectionSymbol, IModuleSymbol /// IReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property); - /// - /// Gets or creates a for the specified . - /// - /// - /// - IReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property); - /// /// Gets or creates a for the specified . /// @@ -97,13 +66,6 @@ interface IReflectionModuleSymbol : IReflectionSymbol, IModuleSymbol /// IReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event); - /// - /// Gets or creates a for the specified . - /// - /// - /// - IReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event); - /// /// Gets or creates a for the specified . /// @@ -111,13 +73,6 @@ interface IReflectionModuleSymbol : IReflectionSymbol, IModuleSymbol /// IReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter); - /// - /// Gets or creates a for the specified . - /// - /// - /// - IReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter); - } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionParameterSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionParameterSymbol.cs index 20e1cb494..60632e80c 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionParameterSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionParameterSymbol.cs @@ -12,9 +12,9 @@ interface IReflectionParameterSymbol : IReflectionSymbol, IParameterSymbol IReflectionModuleSymbol ResolvingModule { get; } /// - /// Gets the method that resolved the parameter. + /// Gets the member that resolved the parameter. /// - IReflectionMethodBaseSymbol ResolvingMethod { get; } + IReflectionMemberSymbol ResolvingMember { get; } /// /// Gets the underlying . diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionPropertySymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionPropertySymbol.cs index 9309bf3ea..2b7aa2401 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionPropertySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionPropertySymbol.cs @@ -11,6 +11,13 @@ interface IReflectionPropertySymbol : IReflectionMemberSymbol, IPropertySymbol /// PropertyInfo UnderlyingProperty { get; } + /// + /// Gets or creates a for the given . + /// + /// + /// + public IReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter); + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionSymbol.cs index 1ee1657d8..c2a970c28 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionSymbol.cs @@ -3,9 +3,6 @@ using System.Collections.Immutable; using System.Diagnostics.CodeAnalysis; using System.Reflection; -using System.Reflection.Emit; - -using IKVM.CoreLib.Symbols.Reflection.Emit; namespace IKVM.CoreLib.Symbols.Reflection { @@ -26,14 +23,6 @@ interface IReflectionSymbol : ISymbol [return: NotNullIfNotNull(nameof(assembly))] IReflectionAssemblySymbol? ResolveAssemblySymbol(Assembly? assembly); - /// - /// Resolves the symbol for the specified assembly builder. - /// - /// - /// - [return: NotNullIfNotNull(nameof(assembly))] - IReflectionAssemblySymbolBuilder ResolveAssemblySymbol(AssemblyBuilder assembly); - /// /// Resolves the symbols for the specified assemblies. /// @@ -50,14 +39,6 @@ interface IReflectionSymbol : ISymbol [return: NotNullIfNotNull(nameof(module))] IReflectionModuleSymbol? ResolveModuleSymbol(Module? module); - /// - /// Resolves the symbol for the specified module. - /// - /// - /// - [return: NotNullIfNotNull(nameof(module))] - IReflectionModuleSymbolBuilder ResolveModuleSymbol(ModuleBuilder module); - /// /// Resolves the symbols for the specified modules. /// @@ -97,14 +78,6 @@ interface IReflectionSymbol : ISymbol [return: NotNullIfNotNull(nameof(type))] IReflectionTypeSymbol? ResolveTypeSymbol(Type? type); - /// - /// Resolves the symbol for the specified type. - /// - /// - /// - [return: NotNullIfNotNull(nameof(type))] - IReflectionTypeSymbolBuilder ResolveTypeSymbol(TypeBuilder type); - /// /// Resolves the symbols for the specified types. /// @@ -136,14 +109,6 @@ interface IReflectionSymbol : ISymbol [return: NotNullIfNotNull(nameof(ctor))] IReflectionConstructorSymbol? ResolveConstructorSymbol(ConstructorInfo? ctor); - /// - /// Resolves the symbol for the specified constructor. - /// - /// - /// - [return: NotNullIfNotNull(nameof(ctor))] - IReflectionConstructorSymbolBuilder ResolveConstructorSymbol(ConstructorBuilder ctor); - /// /// Resolves the symbols for the specified constructors. /// @@ -160,14 +125,6 @@ interface IReflectionSymbol : ISymbol [return: NotNullIfNotNull(nameof(method))] IReflectionMethodSymbol? ResolveMethodSymbol(MethodInfo? method); - /// - /// Resolves the symbol for the specified method. - /// - /// - /// - [return: NotNullIfNotNull(nameof(method))] - IReflectionMethodSymbolBuilder ResolveMethodSymbol(MethodBuilder method); - /// /// Resolves the symbols for the specified methods. /// @@ -184,14 +141,6 @@ interface IReflectionSymbol : ISymbol [return: NotNullIfNotNull(nameof(field))] IReflectionFieldSymbol? ResolveFieldSymbol(FieldInfo? field); - /// - /// Resolves the symbol for the specified field. - /// - /// - /// - [return: NotNullIfNotNull(nameof(field))] - IReflectionFieldSymbolBuilder ResolveFieldSymbol(FieldBuilder field); - /// /// Resolves the symbols for the specified fields. /// @@ -208,14 +157,6 @@ interface IReflectionSymbol : ISymbol [return: NotNullIfNotNull(nameof(property))] IReflectionPropertySymbol? ResolvePropertySymbol(PropertyInfo? property); - /// - /// Resolves the symbol for the specified property. - /// - /// - /// - [return: NotNullIfNotNull(nameof(property))] - IReflectionPropertySymbolBuilder ResolvePropertySymbol(PropertyBuilder property); - /// /// Resolves the symbols for the specified properties. /// @@ -232,14 +173,6 @@ interface IReflectionSymbol : ISymbol [return: NotNullIfNotNull(nameof(@event))] IReflectionEventSymbol? ResolveEventSymbol(EventInfo? @event); - /// - /// Resolves the symbol for the specified event. - /// - /// - /// - [return: NotNullIfNotNull(nameof(@event))] - IReflectionEventSymbolBuilder ResolveEventSymbol(EventBuilder @event); - /// /// Resolves the symbols for the specified events. /// @@ -256,14 +189,6 @@ interface IReflectionSymbol : ISymbol [return: NotNullIfNotNull(nameof(parameter))] IReflectionParameterSymbol? ResolveParameterSymbol(ParameterInfo? parameter); - /// - /// Resolves the symbol for the specified parameter. - /// - /// - /// - [return: NotNullIfNotNull(nameof(parameter))] - IReflectionParameterSymbolBuilder? ResolveParameterSymbol(ParameterBuilder parameter); - /// /// Resolves the symbols for the specified parameters. /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionTypeSymbol.cs index fa7dc4bba..464cc4a3d 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionTypeSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionTypeSymbol.cs @@ -1,4 +1,5 @@ using System; +using System.Reflection; namespace IKVM.CoreLib.Symbols.Reflection { @@ -11,6 +12,87 @@ interface IReflectionTypeSymbol : IReflectionMemberSymbol, ITypeSymbol /// Type UnderlyingType { get; } + /// + /// Gets or creates a for the given . + /// + /// + /// + IReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method); + + /// + /// Gets or creates a for the given . + /// + /// + /// + IReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor); + + /// + /// Gets or creates a for the given . + /// + /// + /// + IReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method); + + /// + /// Gets or creates a for the given . + /// + /// + /// + IReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field); + + /// + /// Gets or creates a for the given . + /// + /// + /// + IReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property); + + /// + /// Gets or creates a for the given . + /// + /// + /// + IReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event); + + /// + /// Gets or creates a for the given generic type parameter type. + /// + /// + /// + IReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type genericTypeParameter); + + /// + /// Gets or creates a for the given element type. + /// + /// + IReflectionTypeSymbol GetOrCreateSZArrayTypeSymbol(); + + /// + /// Gets or creates a for the given element type. + /// + /// + /// + IReflectionTypeSymbol GetOrCreateArrayTypeSymbol(int rank); + + /// + /// Gets or creates a for the given element type. + /// + /// + IReflectionTypeSymbol GetOrCreatePointerTypeSymbol(); + + /// + /// Gets or creates a for the given element type. + /// + /// + IReflectionTypeSymbol GetOrCreateByRefTypeSymbol(); + + /// + /// Gets or creates a for the given element type. + /// + /// + /// + IReflectionTypeSymbol GetOrCreateGenericTypeSymbol(Type[] genericTypeDefinition); + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs index df2d48527..c922a5b4d 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs @@ -1,12 +1,8 @@ using System; using System.Collections.Generic; -using System.Collections.Immutable; using System.IO; using System.Linq; using System.Reflection; -using System.Reflection.Emit; - -using IKVM.CoreLib.Symbols.Reflection.Emit; namespace IKVM.CoreLib.Symbols.Reflection { @@ -15,7 +11,8 @@ class ReflectionAssemblySymbol : ReflectionSymbol, IReflectionAssemblySymbol { readonly Assembly _assembly; - ReflectionAssemblyMetadata _impl; + + ReflectionModuleTable _moduleTable; /// /// Initializes a new instance. @@ -26,7 +23,7 @@ public ReflectionAssemblySymbol(ReflectionSymbolContext context, Assembly assemb base(context) { _assembly = assembly ?? throw new ArgumentNullException(nameof(assembly)); - _impl = new ReflectionAssemblyMetadata(this); + _moduleTable = new ReflectionModuleTable(context, this); } /// @@ -37,123 +34,127 @@ public ReflectionAssemblySymbol(ReflectionSymbolContext context, Assembly assemb #region IAssemblySymbol /// - public IEnumerable DefinedTypes => ResolveTypeSymbols(_assembly.DefinedTypes); + public IReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) + { + return _moduleTable.GetOrCreateModuleSymbol(module); + } + + #endregion + + #region IAssemblySymbol + + /// + public IEnumerable DefinedTypes => ResolveTypeSymbols(UnderlyingAssembly.DefinedTypes); /// - public IMethodSymbol? EntryPoint => ResolveMethodSymbol(_assembly.EntryPoint); + public IMethodSymbol? EntryPoint => ResolveMethodSymbol(UnderlyingAssembly.EntryPoint); /// - public IEnumerable ExportedTypes => ResolveTypeSymbols(_assembly.ExportedTypes); + public IEnumerable ExportedTypes => ResolveTypeSymbols(UnderlyingAssembly.ExportedTypes); /// - public string? FullName => _assembly.FullName; + public string? FullName => UnderlyingAssembly.FullName; /// - public string ImageRuntimeVersion => _assembly.ImageRuntimeVersion; + public string ImageRuntimeVersion => UnderlyingAssembly.ImageRuntimeVersion; /// - public string Location => _assembly.Location; + public string Location => UnderlyingAssembly.Location; /// - public IModuleSymbol ManifestModule => ResolveModuleSymbol(_assembly.ManifestModule); + public IModuleSymbol ManifestModule => ResolveModuleSymbol(UnderlyingAssembly.ManifestModule); /// - public IEnumerable Modules => ResolveModuleSymbols(_assembly.Modules); + public IEnumerable Modules => ResolveModuleSymbols(UnderlyingAssembly.Modules); /// public ITypeSymbol[] GetExportedTypes() { - return ResolveTypeSymbols(_assembly.GetExportedTypes()); + return ResolveTypeSymbols(UnderlyingAssembly.GetExportedTypes()); } /// public IModuleSymbol? GetModule(string name) { - return ResolveModuleSymbol(_assembly.GetModule(name)); + return ResolveModuleSymbol(UnderlyingAssembly.GetModule(name)); } /// public IModuleSymbol[] GetModules() { - return ResolveModuleSymbols(_assembly.GetModules()); + return ResolveModuleSymbols(UnderlyingAssembly.GetModules()); } /// public IModuleSymbol[] GetModules(bool getResourceModules) { - return ResolveModuleSymbols(_assembly.GetModules(getResourceModules)); + return ResolveModuleSymbols(UnderlyingAssembly.GetModules(getResourceModules)); } /// public AssemblyNameInfo GetName() { - return ToAssemblyNameInfo(_assembly.GetName()); + return UnderlyingAssembly.GetName().Pack(); } /// public AssemblyNameInfo[] GetReferencedAssemblies() { - return _assembly.GetReferencedAssemblies().Select(i => ToAssemblyNameInfo(i)).ToArray(); - } - - /// - /// Transforms the to a . - /// - /// - /// - /// - AssemblyNameInfo ToAssemblyNameInfo(AssemblyName n) - { - return new AssemblyNameInfo(n.Name ?? throw new InvalidOperationException(), n.Version, n.CultureName, n.Flags, n.GetPublicKeyToken()?.ToImmutableArray() ?? []); + return UnderlyingAssembly.GetReferencedAssemblies().Pack(); } /// public ITypeSymbol? GetType(string name, bool throwOnError) { - return ResolveTypeSymbol(_assembly.GetType(name, throwOnError)); + return ResolveTypeSymbol(UnderlyingAssembly.GetType(name, throwOnError)); } /// public ITypeSymbol? GetType(string name, bool throwOnError, bool ignoreCase) { - return ResolveTypeSymbol(_assembly.GetType(name, throwOnError, ignoreCase)); + return ResolveTypeSymbol(UnderlyingAssembly.GetType(name, throwOnError, ignoreCase)); } /// public ITypeSymbol? GetType(string name) { - return ResolveTypeSymbol(_assembly.GetType(name)); + return ResolveTypeSymbol(UnderlyingAssembly.GetType(name)); } /// public ITypeSymbol[] GetTypes() { - return ResolveTypeSymbols(_assembly.GetTypes()); + return ResolveTypeSymbols(UnderlyingAssembly.GetTypes()); } /// public CustomAttribute[] GetCustomAttributes(bool inherit = false) { - return ResolveCustomAttributes(_assembly.GetCustomAttributesData()); + return ResolveCustomAttributes(UnderlyingAssembly.GetCustomAttributesData()); } /// public CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) { var _attributeType = attributeType.Unpack(); - return ResolveCustomAttributes(_assembly.GetCustomAttributesData().Where(i => i.AttributeType == _attributeType).ToArray()); + return ResolveCustomAttributes(UnderlyingAssembly.GetCustomAttributesData().Where(i => i.AttributeType == _attributeType).ToArray()); } /// public CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) { - return GetCustomAttributes(attributeType, inherit).FirstOrDefault(); + var _attributeType = attributeType.Unpack(); + var a = UnderlyingAssembly.GetCustomAttributesData().Where(i => i.AttributeType == _attributeType).ToList(); + if (a.Count > 0) + return ResolveCustomAttribute(a[0]); + + return null; } /// public bool IsDefined(ITypeSymbol attributeType, bool inherit = false) { - return _assembly.IsDefined(attributeType.Unpack(), inherit); + return UnderlyingAssembly.IsDefined(attributeType.Unpack(), inherit); } /// @@ -176,16 +177,6 @@ public bool IsDefined(ITypeSymbol attributeType, bool inherit = false) #endregion - public IReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) - { - return _impl.GetOrCreateModuleSymbol(module); - } - - public IReflectionModuleSymbolBuilder GetOrCreateModuleSymbol(ModuleBuilder module) - { - return (IReflectionModuleSymbolBuilder)_impl.GetOrCreateModuleSymbol(module); - } - } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionConstructorSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionConstructorSymbol.cs index 6b30a2fc8..0d7c95667 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionConstructorSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionConstructorSymbol.cs @@ -17,7 +17,7 @@ class ReflectionConstructorSymbol : ReflectionMethodBaseSymbol, IReflectionConst /// /// public ReflectionConstructorSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol resolvingType, ConstructorInfo ctor) : - base(context, resolvingModule, resolvingType, ctor) + base(context, resolvingModule, resolvingType) { _ctor = ctor ?? throw new ArgumentNullException(nameof(ctor)); } @@ -25,6 +25,9 @@ public ReflectionConstructorSymbol(ReflectionSymbolContext context, IReflectionM /// public ConstructorInfo UnderlyingConstructor => _ctor; + /// + public override MethodBase UnderlyingMethodBase => UnderlyingConstructor; + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionEventSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionEventSymbol.cs index dc1b0c8ee..1b8abba99 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionEventSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionEventSymbol.cs @@ -17,20 +17,21 @@ class ReflectionEventSymbol : ReflectionMemberSymbol, IReflectionEventSymbol /// /// public ReflectionEventSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol resolvingType, EventInfo @event) : - base(context, resolvingModule, resolvingType, @event) + base(context, resolvingModule, resolvingType) { _event = @event ?? throw new ArgumentNullException(nameof(@event)); } - /// - /// Gets the underlying wrapped by this symbol. - /// + /// public EventInfo UnderlyingEvent => _event; + /// + public override MemberInfo UnderlyingMember => UnderlyingEvent; + #region IEventSymbol /// - public EventAttributes Attributes => UnderlyingEvent.Attributes; + public System.Reflection.EventAttributes Attributes => (System.Reflection.EventAttributes)UnderlyingEvent.Attributes; /// public ITypeSymbol? EventHandlerType => ResolveTypeSymbol(UnderlyingEvent.EventHandlerType); diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionEventTable.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionEventTable.cs new file mode 100644 index 000000000..dcd4f11eb --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionEventTable.cs @@ -0,0 +1,95 @@ +using System; +using System.Reflection; +using System.Reflection.Emit; +using System.Reflection.Metadata.Ecma335; +using System.Threading; + +using IKVM.CoreLib.Collections; +using IKVM.CoreLib.Reflection; +using IKVM.CoreLib.Symbols.Reflection.Emit; +using IKVM.CoreLib.Threading; + +namespace IKVM.CoreLib.Symbols.Reflection +{ + + struct ReflectionEventTable + { + + readonly ReflectionSymbolContext _context; + readonly IReflectionModuleSymbol _module; + readonly IReflectionTypeSymbol _type; + + IndexRangeDictionary _table = new(); + ReaderWriterLockSlim? _lock; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + public ReflectionEventTable(ReflectionSymbolContext context, IReflectionModuleSymbol module, IReflectionTypeSymbol type) + { + _context = context ?? throw new ArgumentNullException(nameof(context)); + _module = module ?? throw new ArgumentNullException(nameof(module)); + _type = type ?? throw new ArgumentNullException(nameof(type)); + } + + /// + /// Gets or creates the cached for the type by event. + /// + /// + /// + public IReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) + { + if (@event is null) + throw new ArgumentNullException(nameof(@event)); + if (@event.Module.MetadataToken != _module.MetadataToken) + throw new ArgumentException(nameof(@event)); + + // create lock on demand + if (_lock == null) + Interlocked.CompareExchange(ref _lock, new ReaderWriterLockSlim(), null); + + using (_lock.CreateUpgradeableReadLock()) + { + var row = @event.GetMetadataTokenRowNumberSafe(); + if (_table[row] == null) + using (_lock.CreateWriteLock()) + return _table[row] ??= new ReflectionEventSymbol(_context, _module, _type, @event); + + return _table[row] ?? throw new InvalidOperationException(); + } + } + + /// + /// Gets or creates the cached for the type by event. + /// + /// + /// + public IReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event) + { + if (@event is null) + throw new ArgumentNullException(nameof(@event)); + if (@event.GetModuleBuilder() != _module.UnderlyingModule) + throw new ArgumentException(nameof(@event)); + + // create lock on demand + if (_lock == null) + Interlocked.CompareExchange(ref _lock, new ReaderWriterLockSlim(), null); + + using (_lock.CreateUpgradeableReadLock()) + { + var row = @event.GetMetadataTokenRowNumberSafe(); + if (_table[row] == null) + using (_lock.CreateWriteLock()) + return (IReflectionEventSymbolBuilder)(_table[row] ??= new ReflectionEventSymbolBuilder(_context, (IReflectionModuleSymbolBuilder)_module, (IReflectionTypeSymbolBuilder)_type, @event)); + + return (IReflectionEventSymbolBuilder?)_table[row] ?? throw new InvalidOperationException(); + } + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionFieldSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionFieldSymbol.cs index 8e476d98e..c82d80e20 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionFieldSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionFieldSymbol.cs @@ -17,7 +17,7 @@ class ReflectionFieldSymbol : ReflectionMemberSymbol, IReflectionFieldSymbol /// /// public ReflectionFieldSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol? resolvingType, FieldInfo field) : - base(context, resolvingModule, resolvingType, field) + base(context, resolvingModule, resolvingType) { _field = field ?? throw new ArgumentNullException(nameof(field)); } @@ -25,10 +25,13 @@ public ReflectionFieldSymbol(ReflectionSymbolContext context, IReflectionModuleS /// public FieldInfo UnderlyingField => _field; + /// + public override MemberInfo UnderlyingMember => UnderlyingField; + #region IFieldSymbol /// - public FieldAttributes Attributes => UnderlyingField.Attributes; + public System.Reflection.FieldAttributes Attributes => (System.Reflection.FieldAttributes)UnderlyingField.Attributes; /// public ITypeSymbol FieldType => ResolveTypeSymbol(UnderlyingField.FieldType); @@ -54,10 +57,8 @@ public ReflectionFieldSymbol(ReflectionSymbolContext context, IReflectionModuleS /// public bool IsLiteral => UnderlyingField.IsLiteral; -#pragma warning disable SYSLIB0050 // Type or member is obsolete /// public bool IsNotSerialized => UnderlyingField.IsNotSerialized; -#pragma warning restore SYSLIB0050 // Type or member is obsolete /// public bool IsPinvokeImpl => UnderlyingField.IsPinvokeImpl; diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionFieldTable.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionFieldTable.cs new file mode 100644 index 000000000..c2e1b3afd --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionFieldTable.cs @@ -0,0 +1,81 @@ +using System; +using System.Reflection; +using System.Reflection.Emit; +using System.Reflection.Metadata.Ecma335; +using System.Threading; + +using IKVM.CoreLib.Collections; +using IKVM.CoreLib.Reflection; +using IKVM.CoreLib.Symbols.Reflection.Emit; +using IKVM.CoreLib.Threading; + +namespace IKVM.CoreLib.Symbols.Reflection +{ + + struct ReflectionFieldTable + { + + readonly ReflectionSymbolContext _context; + readonly IReflectionModuleSymbol _module; + readonly IReflectionTypeSymbol? _type; + + IndexRangeDictionary _table = new(); + ReaderWriterLockSlim? _lock; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + public ReflectionFieldTable(ReflectionSymbolContext context, IReflectionModuleSymbol module, IReflectionTypeSymbol? type) + { + _context = context ?? throw new ArgumentNullException(nameof(context)); + _module = module ?? throw new ArgumentNullException(nameof(module)); + _type = type; + } + + /// + /// Gets or creates the cached for the type by field. + /// + /// + /// + public IReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) + { + if (field is null) + throw new ArgumentNullException(nameof(field)); + if (field.Module.MetadataToken != _module.MetadataToken) + throw new ArgumentException(nameof(field)); + + // create lock on demand + if (_lock == null) + Interlocked.CompareExchange(ref _lock, new ReaderWriterLockSlim(), null); + + using (_lock.CreateUpgradeableReadLock()) + { + var row = field.GetMetadataTokenRowNumberSafe(); + if (_table[row] == null) + using (_lock.CreateWriteLock()) + if (field is FieldBuilder builder) + return _table[row] ??= new ReflectionFieldSymbolBuilder(_context, (IReflectionModuleSymbolBuilder)_module, (IReflectionTypeSymbolBuilder?)_type, builder); + else + return _table[row] ??= new ReflectionFieldSymbol(_context, _module, _type, field); + + return _table[row] ?? throw new InvalidOperationException(); + } + } + + /// + /// Gets or creates the cached for the type by field. + /// + /// + /// + public IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field) + { + return (IReflectionFieldSymbolBuilder)GetOrCreateFieldSymbol((FieldInfo)field); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericTypeParameterSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericTypeParameterSymbol.cs index a851d2cf9..3fdc602d8 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericTypeParameterSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericTypeParameterSymbol.cs @@ -2,38 +2,49 @@ using System.Diagnostics.CodeAnalysis; using System.Reflection; +using IKVM.CoreLib.Reflection; + namespace IKVM.CoreLib.Symbols.Reflection { class ReflectionGenericTypeParameterSymbol : ReflectionMemberSymbol, IReflectionTypeSymbol { - readonly IReflectionMethodSymbol? _resolvingMethod; + readonly IReflectionMemberSymbol _resolvingMember; readonly Type _type; - ReflectionTypeImpl _impl; + + ReflectionTypeSpecTable _specTable; /// /// Initializes a new instance. /// /// /// - /// - /// + /// /// /// - public ReflectionGenericTypeParameterSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol? resolvingType, IReflectionMethodSymbol? resolvingMethod, Type type) : - base(context, resolvingModule, resolvingType, type) + public ReflectionGenericTypeParameterSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionMemberSymbol resolvingMember, Type type) : + base(context, resolvingModule, resolvingMember as IReflectionTypeSymbol) { - _resolvingMethod = resolvingMethod; + _resolvingMember = resolvingMember ?? throw new ArgumentNullException(nameof(resolvingMember)); _type = type ?? throw new ArgumentNullException(nameof(type)); - _impl = new ReflectionTypeImpl(this); + _specTable = new ReflectionTypeSpecTable(); } + /// + public Type UnderlyingType => _type; + + /// + public override MemberInfo UnderlyingMember => UnderlyingType; + /// - /// Resolves the symbol for the specified type. + /// Gets the method base that declares this type parameter. /// - /// - /// + public IReflectionMemberSymbol? ResolvingMemberSymbol => _resolvingMember; + + #region IReflectionSymbol + + /// [return: NotNullIfNotNull(nameof(type))] public override IReflectionTypeSymbol? ResolveTypeSymbol(Type? type) { @@ -43,519 +54,609 @@ public ReflectionGenericTypeParameterSymbol(ReflectionSymbolContext context, IRe return base.ResolveTypeSymbol(type); } - /// - /// Gets the underlying . - /// - public Type UnderlyingType => _type; + #endregion - /// - /// Gets the method base that declares this type parameter. - /// - public IReflectionMethodBaseSymbol? ResolvingMethodBase => _resolvingMethod; + #region IReflectionTypeSymbol + + /// + public IReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method) + { + throw new NotSupportedException(); + } + + /// + public IReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) + { + throw new NotSupportedException(); + } + + /// + public IReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) + { + throw new NotSupportedException(); + } + + /// + public IReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) + { + throw new NotSupportedException(); + } + + /// + public IReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) + { + throw new NotSupportedException(); + } + + /// + public IReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) + { + throw new NotSupportedException(); + } + + /// + public IReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type type) + { + throw new NotSupportedException(); + } + + /// + public IReflectionTypeSymbol GetOrCreateSZArrayTypeSymbol() + { + return _specTable.GetOrCreateSZArrayTypeSymbol(); + } + + /// + public IReflectionTypeSymbol GetOrCreateArrayTypeSymbol(int rank) + { + return _specTable.GetOrCreateArrayTypeSymbol(rank); + } + + /// + public IReflectionTypeSymbol GetOrCreatePointerTypeSymbol() + { + return _specTable.GetOrCreatePointerTypeSymbol(); + } + + /// + public IReflectionTypeSymbol GetOrCreateByRefTypeSymbol() + { + return _specTable.GetOrCreateByRefTypeSymbol(); + } + + /// + public IReflectionTypeSymbol GetOrCreateGenericTypeSymbol(Type[] genericTypeDefinition) + { + return _specTable.GetOrCreateGenericTypeSymbol(genericTypeDefinition); + } + + #endregion #region ITypeSymbol /// - public TypeAttributes Attributes => _impl.Attributes; + public IAssemblySymbol Assembly => ResolveAssemblySymbol(UnderlyingType.Assembly); /// - public IAssemblySymbol Assembly => _impl.Assembly; + public string? AssemblyQualifiedName => UnderlyingType.AssemblyQualifiedName; /// - public IMethodBaseSymbol? DeclaringMethod => _impl.DeclaringMethod; + public System.Reflection.TypeAttributes Attributes => (System.Reflection.TypeAttributes)UnderlyingType.Attributes; /// - public string? AssemblyQualifiedName => _impl.AssemblyQualifiedName; + public ITypeSymbol? BaseType => ResolveTypeSymbol(UnderlyingType.BaseType); /// - public string? FullName => _impl.FullName; + public bool ContainsGenericParameters => UnderlyingType.ContainsGenericParameters; /// - public string? Namespace => _impl.Namespace; + public IMethodBaseSymbol? DeclaringMethod => ResolveMethodBaseSymbol(UnderlyingType.DeclaringMethod); /// - public TypeCode TypeCode => _impl.TypeCode; + public string? FullName => UnderlyingType.FullName; /// - public ITypeSymbol? BaseType => _impl.BaseType; + public string? Namespace => UnderlyingType.Namespace; /// - public bool ContainsGenericParameters => _impl.ContainsGenericParameters; + public System.Reflection.GenericParameterAttributes GenericParameterAttributes => (System.Reflection.GenericParameterAttributes)UnderlyingType.GenericParameterAttributes; /// - public GenericParameterAttributes GenericParameterAttributes => _impl.GenericParameterAttributes; + public int GenericParameterPosition => UnderlyingType.GenericParameterPosition; /// - public int GenericParameterPosition => _impl.GenericParameterPosition; + public ITypeSymbol[] GenericTypeArguments => ResolveTypeSymbols(UnderlyingType.GenericTypeArguments); /// - public ITypeSymbol[] GenericTypeArguments => _impl.GenericTypeArguments; + public bool HasElementType => UnderlyingType.HasElementType; /// - public bool IsConstructedGenericType => _impl.IsConstructedGenericType; + public TypeCode TypeCode => Type.GetTypeCode(UnderlyingType); /// - public bool IsGenericType => _impl.IsGenericType; + public bool IsAbstract => UnderlyingType.IsAbstract; /// - public bool IsGenericTypeDefinition => _impl.IsGenericTypeDefinition; + public bool IsSZArray => UnderlyingType.IsSZArray(); /// - public bool IsGenericParameter => _impl.IsGenericParameter; + public bool IsArray => UnderlyingType.IsArray; /// - public bool IsAutoLayout => _impl.IsAutoLayout; + public bool IsAutoLayout => UnderlyingType.IsAutoLayout; /// - public bool IsExplicitLayout => _impl.IsExplicitLayout; + public bool IsExplicitLayout => UnderlyingType.IsExplicitLayout; /// - public bool IsLayoutSequential => _impl.IsLayoutSequential; + public bool IsByRef => UnderlyingType.IsByRef; /// - public bool HasElementType => _impl.HasElementType; + public bool IsClass => UnderlyingType.IsClass; /// - public bool IsClass => _impl.IsClass; + public bool IsEnum => UnderlyingType.IsEnum; /// - public bool IsValueType => _impl.IsValueType; + public bool IsInterface => UnderlyingType.IsInterface; /// - public bool IsInterface => _impl.IsInterface; + public bool IsConstructedGenericType => UnderlyingType.IsConstructedGenericType; /// - public bool IsPrimitive => _impl.IsPrimitive; + public bool IsGenericParameter => UnderlyingType.IsGenericParameter; /// - public bool IsSZArray => _impl.IsSZArray; + public bool IsGenericType => UnderlyingType.IsGenericType; /// - public bool IsArray => _impl.IsArray; + public bool IsGenericTypeDefinition => UnderlyingType.IsGenericTypeDefinition; /// - public bool IsEnum => _impl.IsEnum; + public bool IsLayoutSequential => UnderlyingType.IsLayoutSequential; /// - public bool IsPointer => _impl.IsPointer; + public bool IsNested => UnderlyingType.IsNested; /// - public bool IsFunctionPointer => _impl.IsFunctionPointer; + public bool IsNestedAssembly => UnderlyingType.IsNestedAssembly; /// - public bool IsUnmanagedFunctionPointer => _impl.IsUnmanagedFunctionPointer; + public bool IsNestedFamANDAssem => UnderlyingType.IsNestedFamANDAssem; /// - public bool IsByRef => _impl.IsByRef; + public bool IsNestedFamORAssem => UnderlyingType.IsNestedFamORAssem; /// - public bool IsAbstract => _impl.IsAbstract; + public bool IsNestedFamily => UnderlyingType.IsNestedFamily; /// - public bool IsSealed => _impl.IsSealed; + public bool IsNestedPrivate => UnderlyingType.IsNestedPrivate; /// - public bool IsVisible => _impl.IsVisible; + public bool IsNestedPublic => UnderlyingType.IsNestedPublic; /// - public bool IsPublic => _impl.IsPublic; + public bool IsNotPublic => UnderlyingType.IsNotPublic; /// - public bool IsNotPublic => _impl.IsNotPublic; + public bool IsPointer => UnderlyingType.IsPointer; + +#if NET8_0_OR_GREATER /// - public bool IsNested => _impl.IsNested; + public bool IsFunctionPointer => UnderlyingType.IsFunctionPointer; /// - public bool IsNestedAssembly => _impl.IsNestedAssembly; + public bool IsUnmanagedFunctionPointer => UnderlyingType.IsUnmanagedFunctionPointer; + +#else + + /// + public bool IsFunctionPointer => throw new NotImplementedException(); + + /// + public bool IsUnmanagedFunctionPointer => throw new NotImplementedException(); + +#endif /// - public bool IsNestedFamANDAssem => _impl.IsNestedFamANDAssem; + public bool IsPrimitive => UnderlyingType.IsPrimitive; /// - public bool IsNestedFamily => _impl.IsNestedFamily; + public bool IsPublic => UnderlyingType.IsPublic; /// - public bool IsNestedFamORAssem => _impl.IsNestedFamORAssem; + public bool IsSealed => UnderlyingType.IsSealed; /// - public bool IsNestedPrivate => _impl.IsNestedPrivate; + public bool IsSerializable => UnderlyingType.IsSerializable; /// - public bool IsNestedPublic => _impl.IsNestedPublic; + public bool IsValueType => UnderlyingType.IsValueType; /// - public bool IsSerializable => _impl.IsSerializable; + public bool IsVisible => UnderlyingType.IsVisible; /// - public bool IsSignatureType => _impl.IsSignatureType; + public bool IsSignatureType => throw new NotImplementedException(); /// - public bool IsSpecialName => _impl.IsSpecialName; + public bool IsSpecialName => UnderlyingType.IsSpecialName; /// - public IConstructorSymbol? TypeInitializer => throw new NotImplementedException(); + public IConstructorSymbol? TypeInitializer => ResolveConstructorSymbol(UnderlyingType.TypeInitializer); /// public int GetArrayRank() { - return _impl.GetArrayRank(); + return UnderlyingType.GetArrayRank(); } /// - public IMemberSymbol[] GetDefaultMembers() + public IConstructorSymbol? GetConstructor(System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) { - return _impl.GetDefaultMembers(); + return ResolveConstructorSymbol(UnderlyingType.GetConstructor((BindingFlags)bindingAttr, binder: null, types.Unpack(), modifiers: null)); } /// - public ITypeSymbol? GetElementType() + public IConstructorSymbol? GetConstructor(ITypeSymbol[] types) { - return _impl.GetElementType(); + return ResolveConstructorSymbol(UnderlyingType.GetConstructor(types.Unpack())); } /// - public string? GetEnumName(object value) + public IConstructorSymbol[] GetConstructors() { - return _impl.GetEnumName(value); + return ResolveConstructorSymbols(UnderlyingType.GetConstructors()); } /// - public string[] GetEnumNames() + public IConstructorSymbol[] GetConstructors(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetEnumNames(); + return ResolveConstructorSymbols(UnderlyingType.GetConstructors((BindingFlags)bindingAttr)); } /// - public ITypeSymbol GetEnumUnderlyingType() + public IMemberSymbol[] GetDefaultMembers() { - return _impl.GetEnumUnderlyingType(); + return ResolveMemberSymbols(UnderlyingType.GetDefaultMembers()); } /// - public ITypeSymbol[] GetGenericArguments() + public ITypeSymbol? GetElementType() { - return _impl.GetGenericArguments(); + return ResolveTypeSymbol(UnderlyingType.GetElementType()); } /// - public ITypeSymbol[] GetGenericParameterConstraints() + public string? GetEnumName(object value) { - return _impl.GetGenericParameterConstraints(); + return UnderlyingType.GetEnumName(value); } /// - public ITypeSymbol GetGenericTypeDefinition() + public string[] GetEnumNames() { - return _impl.GetGenericTypeDefinition(); + return UnderlyingType.GetEnumNames(); } /// - public ITypeSymbol? GetInterface(string name) + public ITypeSymbol GetEnumUnderlyingType() { - return _impl.GetInterface(name); + return ResolveTypeSymbol(UnderlyingType.GetEnumUnderlyingType()); } /// - public ITypeSymbol? GetInterface(string name, bool ignoreCase) + public Array GetEnumValues() { - return _impl.GetInterface(name, ignoreCase); + return UnderlyingType.GetEnumValues(); } /// - public ITypeSymbol[] GetInterfaces(bool inherit = true) + public IEventSymbol? GetEvent(string name) { - return _impl.GetInterfaces(inherit); + return ResolveEventSymbol(UnderlyingType.GetEvent(name)); } /// - public InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) + public IEventSymbol? GetEvent(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetInterfaceMap(interfaceType); + return ResolveEventSymbol(UnderlyingType.GetEvent(name, (BindingFlags)bindingAttr)); } /// - public IMemberSymbol[] GetMember(string name) + public IEventSymbol[] GetEvents() { - return _impl.GetMember(name); + return ResolveEventSymbols(UnderlyingType.GetEvents()); } /// - public IMemberSymbol[] GetMember(string name, BindingFlags bindingAttr) + public IEventSymbol[] GetEvents(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMember(name, bindingAttr); + return ResolveEventSymbols(UnderlyingType.GetEvents((BindingFlags)bindingAttr)); } /// - public IMemberSymbol[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) + public IFieldSymbol? GetField(string name) { - return _impl.GetMember(name, type, bindingAttr); + return ResolveFieldSymbol(UnderlyingType.GetField(name)); } /// - public IMemberSymbol[] GetMembers() + public IFieldSymbol? GetField(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMembers(); + return ResolveFieldSymbol(UnderlyingType.GetField(name, (BindingFlags)bindingAttr)); } /// - public IMemberSymbol[] GetMembers(BindingFlags bindingAttr) + public IFieldSymbol[] GetFields() { - return _impl.GetMembers(bindingAttr); + return ResolveFieldSymbols(UnderlyingType.GetFields()); } - public IConstructorSymbol? GetConstructor(ITypeSymbol[] types) + /// + public IFieldSymbol[] GetFields(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetConstructor(types); + return ResolveFieldSymbols(UnderlyingType.GetFields((BindingFlags)bindingAttr)); } /// - public IConstructorSymbol? GetConstructor(BindingFlags bindingAttr, ITypeSymbol[] types) + public ITypeSymbol[] GetGenericArguments() { - return _impl.GetConstructor(bindingAttr, types); + return ResolveTypeSymbols(UnderlyingType.GetGenericArguments()); } /// - public IConstructorSymbol[] GetConstructors() + public ITypeSymbol[] GetGenericParameterConstraints() { - return _impl.GetConstructors(); + return ResolveTypeSymbols(UnderlyingType.GetGenericParameterConstraints()); } /// - public IConstructorSymbol[] GetConstructors(BindingFlags bindingAttr) + public ITypeSymbol GetGenericTypeDefinition() { - return _impl.GetConstructors(bindingAttr); + return ResolveTypeSymbol(UnderlyingType.GetGenericTypeDefinition()); } /// - public IFieldSymbol? GetField(string name) + public ITypeSymbol? GetInterface(string name) { - return _impl.GetField(name); + return ResolveTypeSymbol(UnderlyingType.GetInterface(name)); } /// - public IFieldSymbol? GetField(string name, BindingFlags bindingAttr) + public ITypeSymbol? GetInterface(string name, bool ignoreCase) { - return _impl.GetField(name, bindingAttr); + return ResolveTypeSymbol(UnderlyingType.GetInterface(name, ignoreCase)); } /// - public IFieldSymbol[] GetFields() + public InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) { - return _impl.GetFields(); + return ResolveInterfaceMapping(UnderlyingType.GetInterfaceMap(interfaceType.Unpack())); } /// - public IFieldSymbol[] GetFields(BindingFlags bindingAttr) + public ITypeSymbol[] GetInterfaces(bool inherit = true) { - return _impl.GetFields(bindingAttr); + if (inherit) + return ResolveTypeSymbols(UnderlyingType.GetInterfaces()); + else + throw new NotImplementedException(); } /// - public IMethodSymbol? GetMethod(string name) + public IMemberSymbol[] GetMember(string name) { - return _impl.GetMethod(name); + return ResolveMemberSymbols(UnderlyingType.GetMember(name)); } /// - public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) + public IMemberSymbol[] GetMember(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMethod(name, types); + return ResolveMemberSymbols(UnderlyingType.GetMember(name, (BindingFlags)bindingAttr)); } /// - public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr) + public IMemberSymbol[] GetMember(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMethod(name, bindingAttr); + return ResolveMemberSymbols(UnderlyingType.GetMember(name, (MemberTypes)type, (BindingFlags)bindingAttr)); } /// - public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types) + public IMemberSymbol[] GetMembers(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMethod(name, bindingAttr, types); + return ResolveMemberSymbols(UnderlyingType.GetMembers((BindingFlags)bindingAttr)); } /// - public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers) + public IMemberSymbol[] GetMembers() { - return _impl.GetMethod(name, bindingAttr, callConvention, types, modifiers); + return ResolveMemberSymbols(UnderlyingType.GetMembers()); } /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMethod(name, genericParameterCount, bindingAttr, callConvention, types, modifiers); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr)); } /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, ITypeSymbol[] types, ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) { - return _impl.GetMethod(name, genericParameterCount, bindingAttr, types, modifiers); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, types.Unpack())); } /// - public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types, ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) { - return _impl.GetMethod(name, bindingAttr, types, modifiers); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), null)); } /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name) { - return _impl.GetMethod(name, genericParameterCount, types, modifiers); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name)); } /// - public IMethodSymbol[] GetMethods() + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return _impl.GetMethods(); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, (CallingConventions)callConvention, types.Unpack(), modifiers?.Unpack())); } /// - public IMethodSymbol[] GetMethods(BindingFlags bindingAttr) + public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return _impl.GetMethods(bindingAttr); + throw new NotImplementedException(); } /// - public IPropertySymbol? GetProperty(string name) + public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return _impl.GetProperty(name); + throw new NotImplementedException(); } /// - public IPropertySymbol? GetProperty(string name, BindingFlags bindingAttr) + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return _impl.GetProperty(name, bindingAttr); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), modifiers?.Unpack())); } /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol[] types) + public IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return _impl.GetProperty(name, types); + throw new NotImplementedException(); } /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types) + public IMethodSymbol[] GetMethods(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetProperty(name, returnType, types); + return ResolveMethodSymbols(UnderlyingType.GetMethods((BindingFlags)bindingAttr)); } /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) + public IMethodSymbol[] GetMethods() { - return _impl.GetProperty(name, returnType); + return ResolveMethodSymbols(UnderlyingType.GetMethods()); } /// - public IPropertySymbol[] GetProperties() + public ITypeSymbol? GetNestedType(string name) { - return _impl.GetProperties(); + return ResolveTypeSymbol(UnderlyingType.GetNestedType(name)); } /// - public IPropertySymbol[] GetProperties(BindingFlags bindingAttr) + public ITypeSymbol? GetNestedType(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetProperties(bindingAttr); + return ResolveTypeSymbol(UnderlyingType.GetNestedType(name, (BindingFlags)bindingAttr)); } /// - public IEventSymbol? GetEvent(string name) + public ITypeSymbol[] GetNestedTypes() { - return _impl.GetEvent(name); + return ResolveTypeSymbols(UnderlyingType.GetNestedTypes()); } /// - public IEventSymbol? GetEvent(string name, BindingFlags bindingAttr) + public ITypeSymbol[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetEvent(name, bindingAttr); + return ResolveTypeSymbols(UnderlyingType.GetNestedTypes((BindingFlags)bindingAttr)); } /// - public IEventSymbol[] GetEvents() + public IPropertySymbol[] GetProperties() { - return _impl.GetEvents(); + return ResolvePropertySymbols(UnderlyingType.GetProperties()); } /// - public IEventSymbol[] GetEvents(BindingFlags bindingAttr) + public IPropertySymbol[] GetProperties(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetEvents(bindingAttr); + return ResolvePropertySymbols(UnderlyingType.GetProperties((BindingFlags)bindingAttr)); } /// - public ITypeSymbol? GetNestedType(string name) + public IPropertySymbol? GetProperty(string name, ITypeSymbol[] types) { - return _impl.GetNestedType(name); + return ResolvePropertySymbol(UnderlyingType.GetProperty(name, types.Unpack())); } /// - public ITypeSymbol? GetNestedType(string name, BindingFlags bindingAttr) + public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types) { - return _impl.GetNestedType(name, bindingAttr); + return ResolvePropertySymbol(UnderlyingType.GetProperty(name, returnType?.Unpack(), types.Unpack())); } /// - public ITypeSymbol[] GetNestedTypes() + public IPropertySymbol? GetProperty(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetNestedTypes(); + return ResolvePropertySymbol(UnderlyingType.GetProperty(name, (BindingFlags)bindingAttr)); } /// - public ITypeSymbol[] GetNestedTypes(BindingFlags bindingAttr) + public IPropertySymbol? GetProperty(string name) { - return _impl.GetNestedTypes(); + return ResolvePropertySymbol(UnderlyingType.GetProperty(name)); } /// - public bool IsAssignableFrom(ITypeSymbol? c) + public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) { - return _impl.IsAssignableFrom(c); + return ResolvePropertySymbol(UnderlyingType.GetProperty(name, returnType?.Unpack())); } /// - public bool IsSubclassOf(ITypeSymbol c) + public bool IsAssignableFrom(ITypeSymbol? c) { - return _impl.IsSubclassOf(c); + return UnderlyingType.IsAssignableFrom(c?.Unpack()); } /// public bool IsEnumDefined(object value) { - return _impl.IsEnumDefined(value); + return UnderlyingType.IsEnumDefined(value); + } + + /// + public bool IsSubclassOf(ITypeSymbol c) + { + return UnderlyingType.IsSubclassOf(c.Unpack()); } /// public ITypeSymbol MakeArrayType() { - return _impl.MakeArrayType(); + return ResolveTypeSymbol(UnderlyingType.MakeArrayType()); } /// public ITypeSymbol MakeArrayType(int rank) { - return _impl.MakeArrayType(rank); + return ResolveTypeSymbol(UnderlyingType.MakeArrayType(rank)); } /// - public ITypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments) + public ITypeSymbol MakeByRefType() { - return _impl.MakeGenericType(typeArguments); + return ResolveTypeSymbol(UnderlyingType.MakeByRefType()); } /// public ITypeSymbol MakePointerType() { - return _impl.MakePointerType(); + return ResolveTypeSymbol(UnderlyingType.MakePointerType()); } /// - public ITypeSymbol MakeByRefType() + public ITypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments) { - return _impl.MakeByRefType(); + return ResolveTypeSymbol(UnderlyingType.MakeGenericType(typeArguments.Unpack())); } - #endregion +#endregion } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericTypeParameterTable.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericTypeParameterTable.cs new file mode 100644 index 000000000..604583160 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericTypeParameterTable.cs @@ -0,0 +1,78 @@ +using System; +using System.Reflection.Emit; +using System.Threading; + +using IKVM.CoreLib.Collections; +using IKVM.CoreLib.Symbols.Reflection.Emit; +using IKVM.CoreLib.Threading; + +namespace IKVM.CoreLib.Symbols.Reflection +{ + + struct ReflectionGenericTypeParameterTable + { + + readonly ReflectionSymbolContext _context; + readonly IReflectionModuleSymbol _module; + readonly IReflectionMemberSymbol _member; + + IndexRangeDictionary _table = new(); + ReaderWriterLockSlim? _lock; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + public ReflectionGenericTypeParameterTable(ReflectionSymbolContext context, IReflectionModuleSymbol module, IReflectionMemberSymbol member) + { + _context = context ?? throw new ArgumentNullException(nameof(context)); + _module = module ?? throw new ArgumentNullException(nameof(module)); + _member = member; + } + + /// + /// Gets or creates the cached for the module by type. + /// + /// + /// + public IReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type genericTypeParameter) + { + if (genericTypeParameter is null) + throw new ArgumentNullException(nameof(genericTypeParameter)); + if (genericTypeParameter.Module.MetadataToken != _module.MetadataToken) + throw new ArgumentException(nameof(genericTypeParameter)); + + // create lock on demand + if (_lock == null) + Interlocked.CompareExchange(ref _lock, new ReaderWriterLockSlim(), null); + + using (_lock.CreateUpgradeableReadLock()) + { + var pos = genericTypeParameter.GenericParameterPosition; + if (_table[pos] == null) + using (_lock.CreateWriteLock()) + if (genericTypeParameter is GenericTypeParameterBuilder builder) + return _table[pos] ??= new ReflectionGenericTypeParameterSymbolBuilder(_context, (IReflectionModuleSymbolBuilder)_module, (IReflectionMemberSymbolBuilder)_member, builder); + else + return _table[pos] ??= new ReflectionGenericTypeParameterSymbol(_context, _module, _member, genericTypeParameter); + + return _table[pos] ?? throw new InvalidOperationException(); + } + } + + /// + /// Gets or creates the cached for the module. + /// + /// + /// + public IReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeParameterSymbol(GenericTypeParameterBuilder genericTypeParameter) + { + return (IReflectionGenericTypeParameterSymbolBuilder)GetOrCreateGenericTypeParameterSymbol((Type)genericTypeParameter); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs index 496e7b58e..3baf997db 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs @@ -1,12 +1,7 @@ using System; -using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reflection; -using System.Reflection.Emit; - -using IKVM.CoreLib.Reflection; -using IKVM.CoreLib.Symbols.Reflection.Emit; namespace IKVM.CoreLib.Symbols.Reflection { @@ -17,40 +12,8 @@ namespace IKVM.CoreLib.Symbols.Reflection abstract class ReflectionMemberSymbol : ReflectionSymbol, IReflectionMemberSymbol { - /// - /// Concatinates the list of arrays. - /// - /// - /// - static T[] Concat(List? list) - { - if (list == null) - return []; - - var c = 0; - foreach (var i in list) - c += i.Length; - - if (c == 0) - return []; - - var t = 0; - var a = new T[c]; - foreach (var i in list) - { - Array.Copy(i, 0, a, t, i.Length); - t += i.Length; - } - - return a; - } - - readonly IReflectionModuleSymbol _resolvingModule; - readonly IReflectionTypeSymbol? _resolvingType; - readonly MemberInfo _member; - - CustomAttribute[]? _customAttributes; - CustomAttribute[]? _inheritedCustomAttributes; + readonly IReflectionModuleSymbol _module; + readonly IReflectionTypeSymbol? _type; /// /// Initializes a new instance. @@ -59,117 +22,25 @@ static T[] Concat(List? list) /// /// /// - public ReflectionMemberSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol? resolvingType, MemberInfo member) : + public ReflectionMemberSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol? resolvingType) : base(context) { - _resolvingModule = resolvingModule ?? throw new ArgumentNullException(nameof(resolvingModule)); - _resolvingType = resolvingType; - _member = member ?? throw new ArgumentNullException(nameof(member)); + _module = resolvingModule ?? throw new ArgumentNullException(nameof(resolvingModule)); + _type = resolvingType; } /// - public MemberInfo UnderlyingMember => _member; + public abstract MemberInfo UnderlyingMember { get; } /// /// Gets the which contains the metadata of this member. /// - public IReflectionModuleSymbol ResolvingModule => _resolvingModule; + public IReflectionModuleSymbol ResolvingModule => _module; /// /// Gets the which contains the metadata of this member, or null if the member is not a member of a type. /// - public IReflectionTypeSymbol? ResolvingType => _resolvingType; - - #region IMemberSymbol - - /// - public virtual IModuleSymbol Module => ResolveModuleSymbol(UnderlyingMember.Module)!; - - /// - public virtual ITypeSymbol? DeclaringType => ResolveTypeSymbol(UnderlyingMember.DeclaringType)!; - - /// - public virtual MemberTypes MemberType => UnderlyingMember.MemberType; - - /// - public virtual int MetadataToken => UnderlyingMember.GetMetadataTokenSafe(); - - /// - public virtual string Name => UnderlyingMember.Name; - - /// - public virtual CustomAttribute[] GetCustomAttributes(bool inherit = false) - { - if (inherit) - { - // check that we've already processed this - if (_inheritedCustomAttributes != null) - return _inheritedCustomAttributes; - - var self = _member; - var list = default(List?); - for (; ; ) - { - if (self == null) - throw new InvalidOperationException(); - - // get attribute for current member and append to list - var attr = ResolveMemberSymbol(self)!.GetCustomAttributes(false); - if (attr.Length > 0) - { - list ??= []; - list.Add(attr); - } - - var type = self as Type; - if (type != null) - { - type = type.BaseType; - if (type == null) - return _inheritedCustomAttributes ??= Concat(list); - - self = type; - continue; - } - - var method = self as MethodInfo; - if (method != null) - { - var prev = self; - method = method.GetBaseDefinition(); - if (method == null || method == prev) - return _inheritedCustomAttributes ??= Concat(list); - - self = method; - continue; - } - - return _inheritedCustomAttributes ??= Concat(list); - } - } - - return _customAttributes ??= ResolveCustomAttributes(UnderlyingMember.GetCustomAttributesData())!; - } - - /// - public virtual CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) - { - return GetCustomAttributes(inherit).Where(i => i.AttributeType == attributeType).ToArray(); - } - - /// - public virtual CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) - { - return GetCustomAttributes(attributeType, inherit).FirstOrDefault(); - } - - /// - public virtual bool IsDefined(ITypeSymbol attributeType, bool inherit = false) - { - return UnderlyingMember.IsDefined(attributeType.Unpack(), inherit); - } - - #endregion + public IReflectionTypeSymbol? ResolvingType => _type; /// [return: NotNullIfNotNull(nameof(type))] @@ -178,14 +49,14 @@ public virtual bool IsDefined(ITypeSymbol attributeType, bool inherit = false) if (type is null) return null; - if (_member == type) + if (type == UnderlyingMember) return (IReflectionTypeSymbol)this; - if (_resolvingType != null && type == _resolvingType.UnderlyingType) - return _resolvingType; + if (_type != null && type == _type.UnderlyingType) + return _type; - if (type.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateTypeSymbol(type); + if (type.Module == _module.UnderlyingModule) + return _module.GetOrCreateTypeSymbol(type); return base.ResolveTypeSymbol(type); } @@ -197,24 +68,11 @@ public virtual bool IsDefined(ITypeSymbol attributeType, bool inherit = false) if (ctor is null) return null; - if (_member == ctor) + if (ctor == UnderlyingMember) return (IReflectionConstructorSymbol)this; - if (ctor.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateConstructorSymbol(ctor); - - return base.ResolveConstructorSymbol(ctor); - } - - /// - [return: NotNullIfNotNull(nameof(ctor))] - public override IReflectionConstructorSymbolBuilder ResolveConstructorSymbol(ConstructorBuilder ctor) - { - if (ctor is null) - throw new ArgumentNullException(nameof(ctor)); - - if (ctor.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateConstructorSymbol(ctor); + if (ctor.Module == _module.UnderlyingModule) + return _module.GetOrCreateConstructorSymbol(ctor); return base.ResolveConstructorSymbol(ctor); } @@ -226,24 +84,11 @@ public override IReflectionConstructorSymbolBuilder ResolveConstructorSymbol(Con if (method is null) return null; - if (_member == method) + if (method == UnderlyingMember) return (IReflectionMethodSymbol)this; - if (method.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateMethodSymbol(method); - - return base.ResolveMethodSymbol(method); - } - - /// - [return: NotNullIfNotNull(nameof(method))] - public override IReflectionMethodSymbolBuilder ResolveMethodSymbol(MethodBuilder method) - { - if (method is null) - throw new ArgumentNullException(nameof(method)); - - if (method.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateMethodSymbol(method); + if (method.Module == _module.UnderlyingModule) + return _module.GetOrCreateMethodSymbol(method); return base.ResolveMethodSymbol(method); } @@ -255,24 +100,11 @@ public override IReflectionMethodSymbolBuilder ResolveMethodSymbol(MethodBuilder if (field is null) return null; - if (_member == field) + if (field == UnderlyingMember) return (IReflectionFieldSymbol)this; - if (field.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateFieldSymbol(field); - - return base.ResolveFieldSymbol(field); - } - - /// - [return: NotNullIfNotNull(nameof(field))] - public override IReflectionFieldSymbolBuilder ResolveFieldSymbol(FieldBuilder field) - { - if (field is null) - throw new ArgumentNullException(nameof(field)); - - if (field.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateFieldSymbol(field); + if (field.Module == _module.UnderlyingModule) + return _module.GetOrCreateFieldSymbol(field); return base.ResolveFieldSymbol(field); } @@ -284,24 +116,11 @@ public override IReflectionFieldSymbolBuilder ResolveFieldSymbol(FieldBuilder fi if (property is null) return null; - if (_member == property) + if (property == UnderlyingMember) return (IReflectionPropertySymbol)this; - if (property.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreatePropertySymbol(property); - - return base.ResolvePropertySymbol(property); - } - - /// - [return: NotNullIfNotNull(nameof(property))] - public override IReflectionPropertySymbolBuilder ResolvePropertySymbol(PropertyBuilder property) - { - if (property is null) - throw new ArgumentNullException(nameof(property)); - - if (property.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreatePropertySymbol(property); + if (property.Module == _module.UnderlyingModule) + return _module.GetOrCreatePropertySymbol(property); return base.ResolvePropertySymbol(property); } @@ -313,54 +132,82 @@ public override IReflectionPropertySymbolBuilder ResolvePropertySymbol(PropertyB if (@event is null) return null; - if (_member == @event) + if (@event == UnderlyingMember) return (IReflectionEventSymbol)this; - if (@event.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateEventSymbol(@event); + if (@event.Module == _module.UnderlyingModule) + return _module.GetOrCreateEventSymbol(@event); return base.ResolveEventSymbol(@event); } /// - [return: NotNullIfNotNull(nameof(@event))] - public override IReflectionEventSymbolBuilder ResolveEventSymbol(EventBuilder @event) + [return: NotNullIfNotNull(nameof(parameter))] + public override IReflectionParameterSymbol? ResolveParameterSymbol(ParameterInfo? parameter) { - if (@event is null) - throw new ArgumentNullException(nameof(@event)); + if (parameter is null) + throw new ArgumentNullException(nameof(parameter)); - if (@event.GetModuleBuilder() == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateEventSymbol(@event); + if (parameter.Member.Module == _module.UnderlyingModule) + return _module.GetOrCreateParameterSymbol(parameter); - return base.ResolveEventSymbol(@event); + return base.ResolveParameterSymbol(parameter); } + #region IMemberSymbol + /// - [return: NotNullIfNotNull(nameof(parameter))] - public override IReflectionParameterSymbol? ResolveParameterSymbol(ParameterInfo? parameter) + public virtual IModuleSymbol Module => ResolveModuleSymbol(UnderlyingMember.Module)!; + + /// + public virtual ITypeSymbol? DeclaringType => ResolveTypeSymbol(UnderlyingMember.DeclaringType)!; + + /// + public virtual System.Reflection.MemberTypes MemberType => (System.Reflection.MemberTypes)UnderlyingMember.MemberType; + + /// + public virtual int MetadataToken => UnderlyingMember.MetadataToken; + + /// + public virtual string Name => UnderlyingMember.Name; + + /// + public virtual CustomAttribute[] GetCustomAttributes(bool inherit = false) { - if (parameter is null) - throw new ArgumentNullException(nameof(parameter)); + if (inherit == true) + throw new NotSupportedException(); - if (parameter.Member.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateParameterSymbol(parameter); + return ResolveCustomAttributes(UnderlyingMember.GetCustomAttributesData()); + } - return base.ResolveParameterSymbol(parameter); + /// + public virtual CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) + { + if (inherit == true) + throw new NotSupportedException(); + + var _attribyteType = attributeType.Unpack(); + return ResolveCustomAttributes(UnderlyingMember.GetCustomAttributesData().Where(i => i.AttributeType == _attribyteType).ToArray()); } /// - [return: NotNullIfNotNull(nameof(parameter))] - public override IReflectionParameterSymbolBuilder ResolveParameterSymbol(ParameterBuilder parameter) + public virtual CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) { - if (parameter is null) - throw new ArgumentNullException(nameof(parameter)); + if (inherit == true) + throw new NotSupportedException(); - if (parameter.GetModuleBuilder() == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateParameterSymbol(parameter); + var _attributeType = attributeType.Unpack(); + return ResolveCustomAttribute(UnderlyingMember.GetCustomAttributesData().Where(i => i.AttributeType == _attributeType).FirstOrDefault()); + } - return base.ResolveParameterSymbol(parameter); + /// + public virtual bool IsDefined(ITypeSymbol attributeType, bool inherit = false) + { + return UnderlyingMember.IsDefined(attributeType.Unpack(), inherit); } + #endregion + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodBaseSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodBaseSymbol.cs index 76ae425fc..a4ef99e3f 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodBaseSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodBaseSymbol.cs @@ -1,6 +1,4 @@ -using System; -using System.Diagnostics.CodeAnalysis; -using System.Reflection; +using System.Reflection; namespace IKVM.CoreLib.Symbols.Reflection { @@ -8,7 +6,7 @@ namespace IKVM.CoreLib.Symbols.Reflection abstract class ReflectionMethodBaseSymbol : ReflectionMemberSymbol, IReflectionMethodBaseSymbol { - readonly MethodBase _method; + ReflectionParameterTable _parameterTable; /// /// Initializes a new instance. @@ -16,25 +14,35 @@ abstract class ReflectionMethodBaseSymbol : ReflectionMemberSymbol, IReflectionM /// /// /// - /// - public ReflectionMethodBaseSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol? resolvingType, MethodBase method) : - base(context, resolvingModule, resolvingType, method) + public ReflectionMethodBaseSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol? resolvingType) : + base(context, resolvingModule, resolvingType) { - _method = method ?? throw new ArgumentNullException(nameof(method)); + _parameterTable = new ReflectionParameterTable(context, resolvingModule, this); } + #region IReflectionMethodBaseSymbol + + /// + public IReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) + { + return _parameterTable.GetOrCreateParameterSymbol(parameter); + } + + #endregion + #region IMethodBaseSymbol - /// - /// Gets the underlying wrapped by this symbol. - /// - public MethodBase UnderlyingMethodBase => _method; + /// + public abstract MethodBase UnderlyingMethodBase { get; } + + /// + public override MemberInfo UnderlyingMember => UnderlyingMethodBase; /// - public MethodAttributes Attributes => UnderlyingMethodBase.Attributes; + public System.Reflection.MethodAttributes Attributes => (System.Reflection.MethodAttributes)UnderlyingMethodBase.Attributes; /// - public CallingConventions CallingConvention => UnderlyingMethodBase.CallingConvention; + public System.Reflection.CallingConventions CallingConvention => (System.Reflection.CallingConventions)UnderlyingMethodBase.CallingConvention; /// public bool ContainsGenericParameters => UnderlyingMethodBase.ContainsGenericParameters; @@ -85,7 +93,7 @@ public ReflectionMethodBaseSymbol(ReflectionSymbolContext context, IReflectionMo public bool IsSpecialName => UnderlyingMethodBase.IsSpecialName; /// - public MethodImplAttributes MethodImplementationFlags => UnderlyingMethodBase.MethodImplementationFlags; + public System.Reflection.MethodImplAttributes MethodImplementationFlags => (System.Reflection.MethodImplAttributes)UnderlyingMethodBase.MethodImplementationFlags; /// public ITypeSymbol[] GetGenericArguments() @@ -94,9 +102,9 @@ public ITypeSymbol[] GetGenericArguments() } /// - public MethodImplAttributes GetMethodImplementationFlags() + public System.Reflection.MethodImplAttributes GetMethodImplementationFlags() { - return UnderlyingMethodBase.GetMethodImplementationFlags(); + return (System.Reflection.MethodImplAttributes)UnderlyingMethodBase.GetMethodImplementationFlags(); } /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSpecTable.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSpecTable.cs new file mode 100644 index 000000000..a01078ab0 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSpecTable.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Concurrent; +using System.Threading; + +namespace IKVM.CoreLib.Symbols.Reflection +{ + + struct ReflectionMethodSpecTable + { + + readonly ReflectionSymbolContext _context; + readonly IReflectionModuleSymbol _module; + readonly IReflectionTypeSymbol? _type; + readonly IReflectionMethodSymbol _method; + + ConcurrentDictionary? _genericMethodSymbols; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + /// + public ReflectionMethodSpecTable(ReflectionSymbolContext context, IReflectionModuleSymbol module, IReflectionTypeSymbol? type, IReflectionMethodSymbol method) + { + _context = context ?? throw new ArgumentNullException(nameof(context)); + _module = module ?? throw new ArgumentNullException(nameof(module)); + _type = type; + _method = method ?? throw new ArgumentNullException(nameof(method)); + } + + /// + /// Gets or creates a representing a specialized generic of this method. + /// + /// + /// + public IReflectionMethodSymbol GetOrCreateGenericMethodSymbol(Type[] genericTypeArguments) + { + if (genericTypeArguments is null) + throw new ArgumentNullException(nameof(genericTypeArguments)); + + if (_method.IsGenericMethodDefinition == false) + throw new InvalidOperationException(); + + if (_genericMethodSymbols == null) + Interlocked.CompareExchange(ref _genericMethodSymbols, new(TypeListEqualityComparer.Instance), null); + + return _genericMethodSymbols.GetOrAdd(genericTypeArguments, CreateGenericMethodSymbol); + } + + /// + /// Creates a new representing a specialized generic of this type. + /// + /// + /// + readonly IReflectionMethodSymbol CreateGenericMethodSymbol(Type[] genericTypeArguments) + { + return new ReflectionMethodSymbol(_context, _module, _type, _method.UnderlyingMethod.MakeGenericMethod(genericTypeArguments)); + } + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs index 4ee162e53..0b5004856 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs @@ -9,6 +9,9 @@ class ReflectionMethodSymbol : ReflectionMethodBaseSymbol, IReflectionMethodSymb readonly MethodInfo _method; + ReflectionGenericTypeParameterTable _genericTypeParameterTable; + ReflectionMethodSpecTable _specTable; + /// /// Initializes a new instance. /// @@ -17,16 +20,35 @@ class ReflectionMethodSymbol : ReflectionMethodBaseSymbol, IReflectionMethodSymb /// /// public ReflectionMethodSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol module, IReflectionTypeSymbol? type, MethodInfo method) : - base(context, module, type, method) + base(context, module, type) { _method = method ?? throw new ArgumentNullException(nameof(method)); + _genericTypeParameterTable = new ReflectionGenericTypeParameterTable(context, module, this); + _specTable = new ReflectionMethodSpecTable(context, module, type, this); } - /// - /// Gets the underlying wrapped by this symbol. - /// + /// public MethodInfo UnderlyingMethod => _method; + /// + public override MethodBase UnderlyingMethodBase => UnderlyingMethod; + + #region IReflectionMethodSymbol + + /// + public IReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type genericTypeParameter) + { + return _genericTypeParameterTable.GetOrCreateGenericTypeParameterSymbol(genericTypeParameter); + } + + /// + public IReflectionMethodSymbol GetOrCreateGenericMethodSymbol(MethodInfo method) + { + return _specTable.GetOrCreateGenericMethodSymbol(method.GetGenericArguments()); + } + + #endregion + #region IMethodSymbol /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodTable.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodTable.cs new file mode 100644 index 000000000..6e58bb23b --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodTable.cs @@ -0,0 +1,143 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Reflection; +using System.Reflection.Emit; +using System.Reflection.Metadata.Ecma335; +using System.Threading; + +using IKVM.CoreLib.Collections; +using IKVM.CoreLib.Reflection; +using IKVM.CoreLib.Symbols.Reflection.Emit; +using IKVM.CoreLib.Threading; + +namespace IKVM.CoreLib.Symbols.Reflection +{ + + struct ReflectionMethodTable + { + + readonly ReflectionSymbolContext _context; + readonly IReflectionModuleSymbol _module; + readonly IReflectionTypeSymbol? _type; + + IndexRangeDictionary _table = new(); + ReaderWriterLockSlim? _lock; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + public ReflectionMethodTable(ReflectionSymbolContext context, IReflectionModuleSymbol module, IReflectionTypeSymbol? type) + { + _context = context ?? throw new ArgumentNullException(nameof(context)); + _module = module ?? throw new ArgumentNullException(nameof(module)); + _type = type; + } + + /// + /// Gets or creates the cached for the type by method. + /// + /// + /// + public IReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method) + { + if (method is null) + throw new ArgumentNullException(nameof(method)); + if (method.Module.MetadataToken != _module.MetadataToken) + throw new ArgumentException(nameof(method)); + if (method is MethodInfo m_ && m_.IsMethodDefinition() == false) + throw new ArgumentException(nameof(method)); + + // create lock on demand + if (_lock == null) + Interlocked.CompareExchange(ref _lock, new(), null); + + using (_lock.CreateUpgradeableReadLock()) + { + var row = method.GetMetadataTokenRowNumberSafe(); + if (_table[row] == null) + using (_lock.CreateWriteLock()) + return _table[row] ??= CreateMethodBaseSymbol(_context, _module, _type, method); + + return _table[row] ?? throw new InvalidOperationException(); + } + } + + /// + /// Creates a new symbol. + /// + /// + /// + /// + static IReflectionMethodBaseSymbol CreateMethodBaseSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol module, IReflectionTypeSymbol? type, MethodBase method) + { + if (method is ConstructorInfo c) + { + if (type == null) + throw new InvalidOperationException(); + + if (method is ConstructorBuilder builder) + return new ReflectionConstructorSymbolBuilder(context, (IReflectionModuleSymbolBuilder)module, (IReflectionTypeSymbolBuilder)type, builder); + else + return new ReflectionConstructorSymbol(context, module, type, c); + } + else if (method is MethodInfo m) + { + if (method is MethodBuilder builder) + return new ReflectionMethodSymbolBuilder(context, (IReflectionModuleSymbolBuilder)module, (IReflectionTypeSymbolBuilder?)type, builder); + else + return new ReflectionMethodSymbol(context, module, type, m); + } + else + { + throw new InvalidOperationException(); + } + } + + /// + /// Gets or creates the cached for the type by method. + /// + /// + /// + public IReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) + { + return (IReflectionConstructorSymbol)GetOrCreateMethodBaseSymbol(ctor); + } + + /// + /// Gets or creates the cached for the type by method. + /// + /// + /// + public IReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor) + { + return (IReflectionConstructorSymbolBuilder)GetOrCreateMethodBaseSymbol(ctor); + } + + /// + /// Gets or creates the cached for the type by method. + /// + /// + /// + public IReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) + { + return (IReflectionMethodSymbol)GetOrCreateMethodBaseSymbol(method); + } + + /// + /// Gets or creates the cached for the type by method. + /// + /// + /// + public IReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method) + { + return (IReflectionMethodSymbolBuilder)GetOrCreateMethodBaseSymbol(method); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleMetadata.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleMetadata.cs deleted file mode 100644 index f51709679..000000000 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleMetadata.cs +++ /dev/null @@ -1,488 +0,0 @@ -using System; -using System.Reflection; -using System.Reflection.Emit; -using System.Reflection.Metadata.Ecma335; -using System.Threading; - -using IKVM.CoreLib.Collections; -using IKVM.CoreLib.Reflection; -using IKVM.CoreLib.Symbols.Emit; -using IKVM.CoreLib.Symbols.Reflection.Emit; -using IKVM.CoreLib.Threading; - -namespace IKVM.CoreLib.Symbols.Reflection -{ - - /// - /// Provides the metadata resolution implementation for a module. - /// - struct ReflectionModuleMetadata - { - - /// - /// Returns true if the given is a TypeDef. That is, not a modified or substituted or generic parameter type. - /// - /// - /// - static bool IsTypeDefinition(Type type) - { -#if NET - return type.IsTypeDefinition; -#else - return type.HasElementType == false && type.IsConstructedGenericType == false && type.IsGenericParameter == false; -#endif - } - - const int MAX_CAPACITY = 65536 * 2; - - readonly IReflectionModuleSymbol _symbol; - - IndexRangeDictionary _typeSymbols = new(maxCapacity: MAX_CAPACITY); - ReaderWriterLockSlim? _typeLock; - - IndexRangeDictionary _methodSymbols = new(maxCapacity: MAX_CAPACITY); - ReaderWriterLockSlim? _methodLock; - - IndexRangeDictionary _fieldSymbols = new(maxCapacity: MAX_CAPACITY); - ReaderWriterLockSlim? _fieldLock; - - IndexRangeDictionary _propertySymbols = new(maxCapacity: MAX_CAPACITY); - ReaderWriterLockSlim? _propertyLock; - - IndexRangeDictionary _eventSymbols = new(maxCapacity: MAX_CAPACITY); - ReaderWriterLockSlim? _eventLock; - - IndexRangeDictionary _parameterSymbols = new(maxCapacity: MAX_CAPACITY); - ReaderWriterLockSlim? _parameterLock; - - IndexRangeDictionary _genericParameterSymbols = new(maxCapacity: MAX_CAPACITY); - ReaderWriterLockSlim? _genericParameterLock; - - /// - /// Initializes a new instance. - /// - /// - /// - public ReflectionModuleMetadata(IReflectionModuleSymbol symbol) - { - _symbol = symbol ?? throw new ArgumentNullException(nameof(symbol)); - } - - /// - /// Gets or creates the cached for the module by type. - /// - /// - /// - public IReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) - { - if (type is null) - throw new ArgumentNullException(nameof(type)); - if (type.Module.GetMetadataTokenSafe() != _symbol.MetadataToken) - throw new ArgumentException(nameof(type)); - - // type is a generic parameter (GenericParam) - if (type.IsGenericParameter) - return GetOrCreateGenericTypeParameterSymbol(type); - - // type is not a type definition (TypeDef) - if (IsTypeDefinition(type) == false) - return GetOrCreateTypeSymbolForSpecification(type); - - // create lock on demand - if (_typeLock == null) - Interlocked.CompareExchange(ref _typeLock, new ReaderWriterLockSlim(), null); - - using (_typeLock.CreateUpgradeableReadLock()) - { - var row = type.GetMetadataTokenRowNumberSafe(); - if (_typeSymbols[row] == null) - using (_typeLock.CreateWriteLock()) - if (type is TypeBuilder builder) - return _typeSymbols[row] ??= new ReflectionTypeSymbolBuilder(_symbol.Context, _symbol, builder); - else - return _typeSymbols[row] ??= new ReflectionTypeSymbol(_symbol.Context, _symbol, type); - else - return _typeSymbols[row] ?? throw new InvalidOperationException(); - } - } - - - /// - /// Gets or creates the cached for the module by type. - /// - /// - /// - public IReflectionTypeSymbolBuilder GetOrCreateTypeSymbol(TypeBuilder type) - { - return (IReflectionTypeSymbolBuilder)GetOrCreateTypeSymbol((Type)type); - } - - /// - /// Gets or creates a for the specification type: array, pointer, generic, etc. - /// - /// - /// - /// - /// - IReflectionTypeSymbol GetOrCreateTypeSymbolForSpecification(Type type) - { - if (type is null) - throw new ArgumentNullException(nameof(type)); - if (type.Module.GetMetadataTokenSafe() != _symbol.MetadataToken) - throw new ArgumentException(nameof(type)); - - if (type.GetElementType() is { } elementType) - { - var elementTypeSymbol = _symbol.ResolveTypeSymbol(elementType)!; - - // handles both SZ arrays and normal arrays - if (type.IsArray) - return (IReflectionTypeSymbol)elementTypeSymbol.MakeArrayType(type.GetArrayRank()); - - if (type.IsPointer) - return (IReflectionTypeSymbol)elementTypeSymbol.MakePointerType(); - - if (type.IsByRef) - return (IReflectionTypeSymbol)elementTypeSymbol.MakeByRefType(); - - throw new InvalidOperationException(); - } - - if (type.IsGenericType) - { - var definitionTypeSymbol = _symbol.GetOrCreateTypeSymbol(type.GetGenericTypeDefinition()); - return (IReflectionTypeSymbol)definitionTypeSymbol.MakeGenericType(definitionTypeSymbol.ResolveTypeSymbols(type.GetGenericArguments())!); - } - - throw new InvalidOperationException(); - } - - /// - /// Gets or creates the cached for the type by method. - /// - /// - /// - public IReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method) - { - if (method is null) - throw new ArgumentNullException(nameof(method)); - if (method.Module.GetMetadataTokenSafe() != _symbol.MetadataToken) - throw new ArgumentException(nameof(method)); - - // they are methods, but they are associated differently - if (method is DynamicMethod) - throw new ArgumentException("Dynamic methods cannot be attached to context."); - - // create lock on demand - if (_methodLock == null) - Interlocked.CompareExchange(ref _methodLock, new ReaderWriterLockSlim(), null); - - using (_methodLock.CreateUpgradeableReadLock()) - { - var row = method.GetMetadataTokenRowNumberSafe(); - if (_methodSymbols[row] == null) - { - using (_methodLock.CreateWriteLock()) - { - if (method is ConstructorInfo c) - { - if (method is ConstructorBuilder builder) - return _methodSymbols[row] ??= new ReflectionConstructorSymbolBuilder(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(c.DeclaringType!), builder); - else - return _methodSymbols[row] ??= new ReflectionConstructorSymbol(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(c.DeclaringType!), c); - } - else if (method is MethodInfo m) - { - if (method is MethodBuilder builder) - return _methodSymbols[row] ??= new ReflectionMethodSymbolBuilder(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(method.DeclaringType), builder); - else - return _methodSymbols[row] ??= new ReflectionMethodSymbol(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(method.DeclaringType), m); - } - else - { - throw new InvalidOperationException(); - } - } - } - else - { - return _methodSymbols[row] ?? throw new InvalidOperationException(); - } - } - } - - /// - /// Gets or creates the cached for the type by ctor. - /// - /// - /// - public IReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) - { - return (IReflectionConstructorSymbol)GetOrCreateMethodBaseSymbol(ctor); - } - - /// - /// Gets or creates the cached for the type by ctor. - /// - /// - /// - public IReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor) - { - return (IReflectionConstructorSymbolBuilder)GetOrCreateConstructorSymbol((ConstructorInfo)ctor); - } - - /// - /// Gets or creates the cached for the type by method. - /// - /// - /// - public IReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) - { - return (IReflectionMethodSymbol)GetOrCreateMethodBaseSymbol(method); - } - - /// - /// Gets or creates the cached for the type by method. - /// - /// - /// - public IReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method) - { - return (IReflectionMethodSymbolBuilder)GetOrCreateMethodBaseSymbol((MethodInfo)method); - } - - /// - /// Gets or creates the cached for the type by field. - /// - /// - /// - public IReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) - { - if (field is null) - throw new ArgumentNullException(nameof(field)); - if (field.Module.GetMetadataTokenSafe() != _symbol.MetadataToken) - throw new ArgumentException(nameof(field)); - - // create lock on demand - if (_fieldLock == null) - Interlocked.CompareExchange(ref _fieldLock, new ReaderWriterLockSlim(), null); - - using (_fieldLock.CreateUpgradeableReadLock()) - { - var row = field.GetMetadataTokenRowNumberSafe(); - if (_fieldSymbols[row] == null) - using (_fieldLock.CreateWriteLock()) - if (field is FieldBuilder builder) - return _fieldSymbols[row] ??= new ReflectionFieldSymbolBuilder(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(field.DeclaringType), builder); - else - return _fieldSymbols[row] ??= new ReflectionFieldSymbol(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(field.DeclaringType), field); - else - return _fieldSymbols[row] ?? throw new InvalidOperationException(); - } - } - - /// - /// Gets or creates the cached for the type by method. - /// - /// - /// - public IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field) - { - return (IReflectionFieldSymbolBuilder)GetOrCreateFieldSymbol((FieldInfo)field); - } - - /// - /// Gets or creates the cached for the type by property. - /// - /// - /// - public IReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) - { - if (property is null) - throw new ArgumentNullException(nameof(property)); - if (property.Module.GetMetadataTokenSafe() != _symbol.MetadataToken) - throw new ArgumentException(nameof(property)); - - // create lock on demand - if (_propertyLock == null) - Interlocked.CompareExchange(ref _propertyLock, new ReaderWriterLockSlim(), null); - - using (_propertyLock.CreateUpgradeableReadLock()) - { - var row = property.GetMetadataTokenRowNumberSafe(); - if (_propertySymbols[row] == null) - using (_propertyLock.CreateWriteLock()) - if (property is PropertyBuilder builder) - return _propertySymbols[row] ??= new ReflectionPropertySymbolBuilder(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(property.DeclaringType!), builder); - else - return _propertySymbols[row] ??= new ReflectionPropertySymbol(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(property.DeclaringType!), property); - else - return _propertySymbols[row] ?? throw new InvalidOperationException(); - } - } - - - /// - /// Gets or creates the cached for the type by property. - /// - /// - /// - public IReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property) - { - return (IReflectionPropertySymbolBuilder)GetOrCreatePropertySymbol((PropertyInfo)property); - } - - /// - /// Gets or creates the cached for the type by event. - /// - /// - /// - public IReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) - { - if (@event is null) - throw new ArgumentNullException(nameof(@event)); - if (@event.Module.GetMetadataTokenSafe() != _symbol.MetadataToken) - throw new ArgumentException(nameof(@event)); - - // create lock on demand - if (_eventLock == null) - Interlocked.CompareExchange(ref _eventLock, new ReaderWriterLockSlim(), null); - - using (_eventLock.CreateUpgradeableReadLock()) - { - var row = @event.GetMetadataTokenRowNumberSafe(); - if (_eventSymbols[row] == null) - using (_eventLock.CreateWriteLock()) - return _eventSymbols[row] ??= new ReflectionEventSymbol(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(@event.DeclaringType!), @event); - else - return _eventSymbols[row] ?? throw new InvalidOperationException(); - } - } - - /// - /// Gets or creates the cached for the type by event. - /// - /// - /// - public IReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event) - { - if (@event is null) - throw new ArgumentNullException(nameof(@event)); - if (@event.GetModuleBuilder().GetMetadataTokenSafe() != _symbol.MetadataToken) - throw new ArgumentException(nameof(@event)); - - // create lock on demand - if (_eventLock == null) - Interlocked.CompareExchange(ref _eventLock, new ReaderWriterLockSlim(), null); - - using (_eventLock.CreateUpgradeableReadLock()) - { - var row = @event.GetMetadataTokenRowNumberSafe(); - if (_eventSymbols[row] == null) - using (_eventLock.CreateWriteLock()) - return (IReflectionEventSymbolBuilder)(_eventSymbols[row] ??= new ReflectionEventSymbolBuilder(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(@event.GetTypeBuilder()), @event)); - else - return (IReflectionEventSymbolBuilder?)_eventSymbols[row] ?? throw new InvalidOperationException(); - } - } - - /// - /// Gets or creates the cached for the type by method. - /// - /// - /// - public IReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) - { - if (parameter is null) - throw new ArgumentNullException(nameof(parameter)); - if (parameter.Member.Module.GetMetadataTokenSafe() != _symbol.MetadataToken) - throw new ArgumentException(nameof(parameter)); - - // create lock on demand - if (_parameterLock == null) - Interlocked.CompareExchange(ref _parameterLock, new ReaderWriterLockSlim(), null); - - using (_parameterLock.CreateUpgradeableReadLock()) - { - var position = parameter.Position; - if (_parameterSymbols[position] == null) - using (_parameterLock.CreateWriteLock()) - return _parameterSymbols[position] ??= new ReflectionParameterSymbol(_symbol.Context, _symbol, _symbol.ResolveMethodBaseSymbol((MethodBase)parameter.Member), parameter); - else - return _parameterSymbols[position] ?? throw new InvalidOperationException(); - } - } - - /// - /// Gets or creates the cached for the type by method. - /// - /// - /// - public IReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter) - { - if (parameter is null) - throw new ArgumentNullException(nameof(parameter)); - if (parameter.GetModuleBuilder().GetMetadataTokenSafe() != _symbol.MetadataToken) - throw new ArgumentException(nameof(parameter)); - - // create lock on demand - if (_parameterLock == null) - Interlocked.CompareExchange(ref _parameterLock, new ReaderWriterLockSlim(), null); - - using (_parameterLock.CreateUpgradeableReadLock()) - { - var position = parameter.Position; - if (_parameterSymbols[position] == null) - using (_parameterLock.CreateWriteLock()) - return (IReflectionParameterSymbolBuilder)(_parameterSymbols[position] ??= new ReflectionParameterSymbolBuilder(_symbol.Context, _symbol, _symbol.ResolveMethodSymbol(parameter.GetMethodBuilder()), parameter)); - else - return (IReflectionParameterSymbolBuilder?)_parameterSymbols[position] ?? throw new InvalidOperationException(); - } - } - - /// - /// Gets or creates the cached for the module by type. - /// - /// - /// - IReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type genericParameterType) - { - if (genericParameterType is null) - throw new ArgumentNullException(nameof(genericParameterType)); - if (genericParameterType.Module.GetMetadataTokenSafe() != _symbol.MetadataToken) - throw new ArgumentException(nameof(genericParameterType)); - - // create lock on demand - if (_genericParameterLock == null) - Interlocked.CompareExchange(ref _genericParameterLock, new ReaderWriterLockSlim(), null); - - using (_genericParameterLock.CreateUpgradeableReadLock()) - { - var hnd = MetadataTokens.GenericParameterHandle(genericParameterType.GetMetadataTokenSafe()); - var row = MetadataTokens.GetRowNumber(hnd); - if (_genericParameterSymbols[row] == null) - using (_genericParameterLock.CreateWriteLock()) - if (genericParameterType is GenericTypeParameterBuilder builder) - return _genericParameterSymbols[row] ??= new ReflectionGenericTypeParameterSymbolBuilder(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(genericParameterType.DeclaringType), _symbol.ResolveMethodSymbol((MethodInfo?)genericParameterType.DeclaringMethod), builder); - else - return _genericParameterSymbols[row] ??= new ReflectionGenericTypeParameterSymbol(_symbol.Context, _symbol, _symbol.ResolveTypeSymbol(genericParameterType.DeclaringType), _symbol.ResolveMethodSymbol((MethodInfo?)genericParameterType.DeclaringMethod), genericParameterType); - else - { - return _genericParameterSymbols[row] ?? throw new InvalidOperationException(); - } - } - } - - /// - /// Gets or creates the cached for the module. - /// - /// - /// - IReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeParameterSymbol(GenericTypeParameterBuilder genericParameterType) - { - return (IReflectionGenericTypeParameterSymbolBuilder)GetOrCreateGenericTypeParameterSymbol((Type)genericParameterType); - } - - } - -} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs index 60a8b9f32..c596f370e 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs @@ -1,9 +1,8 @@ using System; using System.Linq; using System.Reflection; -using System.Reflection.Emit; -using IKVM.CoreLib.Symbols.Reflection.Emit; +using IKVM.CoreLib.Reflection; namespace IKVM.CoreLib.Symbols.Reflection { @@ -16,7 +15,10 @@ class ReflectionModuleSymbol : ReflectionSymbol, IReflectionModuleSymbol readonly IReflectionAssemblySymbol _resolvingAssembly; readonly Module _module; - ReflectionModuleMetadata _impl; + + ReflectionTypeTable _typeTable; + ReflectionMethodTable _methodTable; + ReflectionFieldTable _fieldTable; /// /// Initializes a new instance. @@ -30,7 +32,10 @@ public ReflectionModuleSymbol(ReflectionSymbolContext context, IReflectionAssemb { _resolvingAssembly = resolvingAssembly ?? throw new ArgumentNullException(nameof(resolvingAssembly)); _module = module ?? throw new ArgumentNullException(nameof(module)); - _impl = new ReflectionModuleMetadata(this); + + _typeTable = new ReflectionTypeTable(context, this, null); + _methodTable = new ReflectionMethodTable(context, this, null); + _fieldTable = new ReflectionFieldTable(context, this, null); } /// @@ -219,7 +224,8 @@ public CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inh /// public CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) { - return GetCustomAttributes(attributeType, inherit).FirstOrDefault(); + var _attributeType = attributeType.Unpack(); + return ResolveCustomAttribute(UnderlyingModule.GetCustomAttributesData().Where(i => i.AttributeType == _attributeType).FirstOrDefault()); } /// @@ -230,89 +236,88 @@ public bool IsDefined(ITypeSymbol attributeType, bool inherit = false) #endregion + #region IReflectionModuleSymbol + /// public IReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) { - return _impl.GetOrCreateTypeSymbol(type); - } + if (type.IsTypeDefinition()) + return _typeTable.GetOrCreateTypeSymbol(type); + else if (type.IsGenericType) + return ResolveTypeSymbol(type.GetGenericTypeDefinition()).GetOrCreateGenericTypeSymbol(type.GetGenericArguments()); + else if (type.IsSZArray()) + return ResolveTypeSymbol(type.GetElementType()!).GetOrCreateSZArrayTypeSymbol(); + else if (type.IsArray) + return ResolveTypeSymbol(type.GetElementType()!).GetOrCreateArrayTypeSymbol(type.GetArrayRank()); + else if (type.IsPointer) + return ResolveTypeSymbol(type.GetElementType()!).GetOrCreatePointerTypeSymbol(); + else if (type.IsByRef) + return ResolveTypeSymbol(type.GetElementType()!).GetOrCreateByRefTypeSymbol(); + else if (type.IsGenericParameter && type.DeclaringMethod is MethodInfo dm) + return ResolveMethodSymbol(dm).GetOrCreateGenericTypeParameterSymbol(type); + else if (type.IsGenericParameter && type.DeclaringType is Type t) + return ResolveTypeSymbol(t).GetOrCreateGenericTypeParameterSymbol(type); - /// - public IReflectionTypeSymbolBuilder GetOrCreateTypeSymbol(TypeBuilder type) - { - return _impl.GetOrCreateTypeSymbol(type); + throw new InvalidOperationException(); } /// - public IReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) + public IReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method) { - return _impl.GetOrCreateConstructorSymbol(ctor); + if (method.DeclaringType is { } dt) + return ResolveTypeSymbol(dt).GetOrCreateMethodBaseSymbol(method); + else + return _methodTable.GetOrCreateMethodBaseSymbol(method); } /// - public IReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor) + public IReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) { - return _impl.GetOrCreateConstructorSymbol(ctor); + return ResolveTypeSymbol(ctor.DeclaringType!).GetOrCreateConstructorSymbol(ctor); } /// public IReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) { - return _impl.GetOrCreateMethodSymbol(method); - } - - /// - public IReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method) - { - return _impl.GetOrCreateMethodSymbol(method); + if (method.DeclaringType is { } dt) + return ResolveTypeSymbol(dt).GetOrCreateMethodSymbol(method); + else + return _methodTable.GetOrCreateMethodSymbol(method); } /// public IReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) { - return _impl.GetOrCreateFieldSymbol(field); - } - - /// - public IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field) - { - return _impl.GetOrCreateFieldSymbol(field); + if (field.DeclaringType is { } dt) + return ResolveTypeSymbol(dt).GetOrCreateFieldSymbol(field); + else + return _fieldTable.GetOrCreateFieldSymbol(field); } /// public IReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) { - return _impl.GetOrCreatePropertySymbol(property); - } - - /// - public IReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property) - { - return _impl.GetOrCreatePropertySymbol(property); + return ResolveTypeSymbol(property.DeclaringType!).GetOrCreatePropertySymbol(property); } /// public IReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) { - return _impl.GetOrCreateEventSymbol(@event); - } - - /// - public IReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event) - { - return _impl.GetOrCreateEventSymbol(@event); + return ResolveTypeSymbol(@event.DeclaringType!).GetOrCreateEventSymbol(@event); } /// public IReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) { - return _impl.GetOrCreateParameterSymbol(parameter); + return ResolveMemberSymbol(parameter.Member) switch + { + IReflectionMethodBaseSymbol method => method.GetOrCreateParameterSymbol(parameter), + IReflectionPropertySymbol property => property.GetOrCreateParameterSymbol(parameter), + _ => throw new InvalidOperationException(), + }; } - /// - public IReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter) - { - return _impl.GetOrCreateParameterSymbol(parameter); - } + #endregion } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblyMetadata.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleTable.cs similarity index 55% rename from src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblyMetadata.cs rename to src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleTable.cs index c63ae5145..38f817272 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblyMetadata.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleTable.cs @@ -1,7 +1,7 @@ using System; -using System.Diagnostics; using System.Reflection; using System.Reflection.Emit; +using System.Reflection.Metadata.Ecma335; using System.Threading; using IKVM.CoreLib.Collections; @@ -12,37 +12,36 @@ namespace IKVM.CoreLib.Symbols.Reflection { - struct ReflectionAssemblyMetadata + struct ReflectionModuleTable { - readonly IReflectionAssemblySymbol _symbol; + readonly ReflectionSymbolContext _context; + readonly IReflectionAssemblySymbol _assembly; - IndexRangeDictionary _moduleSymbols = new(maxCapacity: 32); + IndexRangeDictionary _moduleSymbols = new(); ReaderWriterLockSlim? _moduleLock; /// /// Initializes a new instance. /// - /// + /// /// - public ReflectionAssemblyMetadata(IReflectionAssemblySymbol symbol) + public ReflectionModuleTable(ReflectionSymbolContext context, IReflectionAssemblySymbol assembly) { - _symbol = symbol ?? throw new ArgumentNullException(nameof(symbol)); + _context = context ?? throw new ArgumentNullException(nameof(context)); + _assembly = assembly ?? throw new ArgumentNullException(nameof(assembly)); } /// - /// Gets or creates the cached for the module. + /// Gets or creates the cached for the module. /// /// /// - /// public IReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) { if (module is null) throw new ArgumentNullException(nameof(module)); - Debug.Assert(AssemblyNameEqualityComparer.Instance.Equals(module.Assembly.GetName(), _symbol.UnderlyingAssembly.GetName())); - // create lock on demand if (_moduleLock == null) Interlocked.CompareExchange(ref _moduleLock, new ReaderWriterLockSlim(), null); @@ -53,14 +52,24 @@ public IReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) if (_moduleSymbols[row] == null) using (_moduleLock.CreateWriteLock()) if (module is ModuleBuilder builder) - return _moduleSymbols[row] = new ReflectionModuleSymbolBuilder(_symbol.Context, _symbol, builder); + return _moduleSymbols[row] = new ReflectionModuleSymbolBuilder(_context, _assembly, builder); else - return _moduleSymbols[row] = new ReflectionModuleSymbol(_symbol.Context, _symbol, module); - else - return _moduleSymbols[row] ?? throw new InvalidOperationException(); + return _moduleSymbols[row] = new ReflectionModuleSymbol(_context, _assembly, module); + + return _moduleSymbols[row] ?? throw new InvalidOperationException(); } } + /// + /// Gets or creates the cached for the module. + /// + /// + /// + public IReflectionModuleSymbolBuilder GetOrCreateModuleSymbol(ModuleBuilder module) + { + return (IReflectionModuleSymbolBuilder)GetOrCreateModuleSymbol((Module)module); + } + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterSymbol.cs index 22628fd9d..cffe5c8ec 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterSymbol.cs @@ -9,23 +9,21 @@ class ReflectionParameterSymbol : ReflectionSymbol, IReflectionParameterSymbol { readonly IReflectionModuleSymbol _resolvingModule; - readonly IReflectionMethodBaseSymbol _resolvingMethod; + readonly IReflectionMemberSymbol _resolvingMember; readonly ParameterInfo _parameter; - CustomAttribute[]? _customAttributes; - /// /// Initializes a new instance. /// /// /// - /// + /// /// - public ReflectionParameterSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionMethodBaseSymbol resolvingMethod, ParameterInfo parameter) : + public ReflectionParameterSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionMemberSymbol? resolvingMember, ParameterInfo parameter) : base(context) { _resolvingModule = resolvingModule ?? throw new ArgumentNullException(nameof(resolvingModule)); - _resolvingMethod = resolvingMethod ?? throw new ArgumentNullException(nameof(resolvingMethod)); + _resolvingMember = resolvingMember ?? throw new ArgumentNullException(nameof(resolvingMember)); _parameter = parameter ?? throw new ArgumentNullException(nameof(parameter)); } @@ -33,7 +31,7 @@ public ReflectionParameterSymbol(ReflectionSymbolContext context, IReflectionMod public IReflectionModuleSymbol ResolvingModule => _resolvingModule; /// - public IReflectionMethodBaseSymbol ResolvingMethod => _resolvingMethod; + public IReflectionMemberSymbol ResolvingMember => _resolvingMember; /// public ParameterInfo UnderlyingParameter => _parameter; @@ -41,10 +39,10 @@ public ReflectionParameterSymbol(ReflectionSymbolContext context, IReflectionMod #region IParameterSymbol /// - public ParameterAttributes Attributes => UnderlyingParameter.Attributes; + public System.Reflection.ParameterAttributes Attributes => (System.Reflection.ParameterAttributes)UnderlyingParameter.Attributes; /// - public object? DefaultValue => UnderlyingParameter.DefaultValue; + public object? DefaultValue => UnderlyingParameter.RawDefaultValue; /// public bool HasDefaultValue => UnderlyingParameter.HasDefaultValue; @@ -80,21 +78,32 @@ public ReflectionParameterSymbol(ReflectionSymbolContext context, IReflectionMod public int Position => UnderlyingParameter.Position; /// - public CustomAttribute[] GetCustomAttributes(bool inherit = false) + public virtual CustomAttribute[] GetCustomAttributes(bool inherit = false) { - return _customAttributes ??= ResolveCustomAttributes(UnderlyingParameter.GetCustomAttributesData()); + if (inherit == true) + throw new NotSupportedException(); + + return ResolveCustomAttributes(UnderlyingParameter.GetCustomAttributesData()); } /// public virtual CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) { - return GetCustomAttributes(inherit).Where(i => i.AttributeType == attributeType).ToArray(); + if (inherit == true) + throw new NotSupportedException(); + + var _attribyteType = attributeType.Unpack(); + return ResolveCustomAttributes(UnderlyingParameter.GetCustomAttributesData().Where(i => i.AttributeType == _attribyteType).ToArray()); } /// public virtual CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) { - return GetCustomAttributes(attributeType, inherit).FirstOrDefault(); + if (inherit == true) + throw new NotSupportedException(); + + var _attributeType = attributeType.Unpack(); + return ResolveCustomAttribute(UnderlyingParameter.GetCustomAttributesData().Where(i => i.AttributeType == _attributeType).FirstOrDefault()); } /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterTable.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterTable.cs new file mode 100644 index 000000000..8d1faa6b1 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterTable.cs @@ -0,0 +1,102 @@ +using System; +using System.Reflection; +using System.Reflection.Emit; +using System.Threading; + +using IKVM.CoreLib.Collections; +using IKVM.CoreLib.Reflection; +using IKVM.CoreLib.Symbols.Reflection.Emit; +using IKVM.CoreLib.Threading; + +namespace IKVM.CoreLib.Symbols.Reflection +{ + + struct ReflectionParameterTable + { + + readonly ReflectionSymbolContext _context; + readonly IReflectionModuleSymbol _module; + readonly IReflectionMemberSymbol _member; + + IndexRangeDictionary _table = new(); + ReaderWriterLockSlim? _lock; + IReflectionParameterSymbol? _returnParameter; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + /// + public ReflectionParameterTable(ReflectionSymbolContext context, IReflectionModuleSymbol module, IReflectionMemberSymbol member) + { + _context = context ?? throw new ArgumentNullException(nameof(context)); + _module = module ?? throw new ArgumentNullException(nameof(module)); + _member = member ?? throw new ArgumentNullException(nameof(member)); + } + + /// + /// Gets or creates the cached for the type by method. + /// + /// + /// + public IReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) + { + if (parameter is null) + throw new ArgumentNullException(nameof(parameter)); + if (parameter.Member.Module.MetadataToken != _module.MetadataToken) + throw new ArgumentException(nameof(parameter)); + + // create lock on demand + if (_lock == null) + Interlocked.CompareExchange(ref _lock, new ReaderWriterLockSlim(), null); + + using (_lock.CreateUpgradeableReadLock()) + { + var position = parameter.Position; + if (position == -1) + return _returnParameter ??= new ReflectionParameterSymbol(_context, _module, _member, parameter); + + if (_table[position] == null) + using (_lock.CreateWriteLock()) + return _table[position] ??= new ReflectionParameterSymbol(_context, _module, _member, parameter); + + return _table[position] ?? throw new InvalidOperationException(); + } + } + + /// + /// Gets or creates the cached for the type by method. + /// + /// + /// + public IReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter) + { + if (parameter is null) + throw new ArgumentNullException(nameof(parameter)); + if (parameter.GetMethodBuilder().Module != _module.UnderlyingModule) + throw new ArgumentException(nameof(parameter)); + + // create lock on demand + if (_lock == null) + Interlocked.CompareExchange(ref _lock, new ReaderWriterLockSlim(), null); + + using (_lock.CreateUpgradeableReadLock()) + { + var position = parameter.Position - 1; + if (position == -1) + return (IReflectionParameterSymbolBuilder)(_returnParameter ??= new ReflectionParameterSymbolBuilder(_context, _module, (IReflectionMethodBaseSymbol)_member, parameter)); + + if (_table[position] == null) + using (_lock.CreateWriteLock()) + return (IReflectionParameterSymbolBuilder)(_table[position] ??= new ReflectionParameterSymbolBuilder(_context, _module, (IReflectionMethodBaseSymbol)_member, parameter)); + + return (IReflectionParameterSymbolBuilder?)_table[position] ?? throw new InvalidOperationException(); + } + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionPropertySymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionPropertySymbol.cs index e0f003674..4a06567d9 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionPropertySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionPropertySymbol.cs @@ -9,6 +9,8 @@ class ReflectionPropertySymbol : ReflectionMemberSymbol, IReflectionPropertySymb readonly PropertyInfo _property; + ReflectionParameterTable _parameterTable; + /// /// Initializes a new instance. /// @@ -17,16 +19,32 @@ class ReflectionPropertySymbol : ReflectionMemberSymbol, IReflectionPropertySymb /// /// public ReflectionPropertySymbol(ReflectionSymbolContext context, IReflectionModuleSymbol module, IReflectionTypeSymbol type, PropertyInfo property) : - base(context, module, type, property) + base(context, module, type) { _property = property ?? throw new ArgumentNullException(nameof(property)); + _parameterTable = new ReflectionParameterTable(context, module, this); } /// public PropertyInfo UnderlyingProperty => _property; /// - public PropertyAttributes Attributes => UnderlyingProperty.Attributes; + public override MemberInfo UnderlyingMember => UnderlyingProperty; + + #region IReflectionPropertySymbol + + /// + public IReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) + { + return _parameterTable.GetOrCreateParameterSymbol(parameter); + } + + #endregion + + #region IPropertySymbol + + /// + public System.Reflection.PropertyAttributes Attributes => (System.Reflection.PropertyAttributes)UnderlyingProperty.Attributes; /// public bool CanRead => UnderlyingProperty.CanRead; @@ -112,6 +130,8 @@ public ITypeSymbol[] GetRequiredCustomModifiers() return ResolveTypeSymbols(UnderlyingProperty.GetRequiredCustomModifiers()); } + #endregion + } } \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionPropertyTable.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionPropertyTable.cs new file mode 100644 index 000000000..c8a96fceb --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionPropertyTable.cs @@ -0,0 +1,81 @@ +using System; +using System.Reflection; +using System.Reflection.Emit; +using System.Reflection.Metadata.Ecma335; +using System.Threading; + +using IKVM.CoreLib.Collections; +using IKVM.CoreLib.Reflection; +using IKVM.CoreLib.Symbols.Reflection.Emit; +using IKVM.CoreLib.Threading; + +namespace IKVM.CoreLib.Symbols.Reflection +{ + + struct ReflectionPropertyTable + { + + readonly ReflectionSymbolContext _context; + readonly IReflectionModuleSymbol _module; + readonly IReflectionTypeSymbol _type; + + IndexRangeDictionary _table = new(); + ReaderWriterLockSlim? _lock; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + public ReflectionPropertyTable(ReflectionSymbolContext context, IReflectionModuleSymbol module, IReflectionTypeSymbol type) + { + _context = context ?? throw new ArgumentNullException(nameof(context)); + _module = module ?? throw new ArgumentNullException(nameof(module)); + _type = type ?? throw new ArgumentNullException(nameof(type)); + } + + /// + /// Gets or creates the cached for the type by property. + /// + /// + /// + public IReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) + { + if (property is null) + throw new ArgumentNullException(nameof(property)); + if (property.Module.MetadataToken != _module.MetadataToken) + throw new ArgumentException(nameof(property)); + + // create lock on demand + if (_lock == null) + Interlocked.CompareExchange(ref _lock, new ReaderWriterLockSlim(), null); + + using (_lock.CreateUpgradeableReadLock()) + { + var row = property.GetMetadataTokenRowNumberSafe(); + if (_table[row] == null) + using (_lock.CreateWriteLock()) + if (property is PropertyBuilder builder) + return _table[row] ??= new ReflectionPropertySymbolBuilder(_context, (IReflectionModuleSymbolBuilder)_module, (IReflectionTypeSymbolBuilder)_type, builder); + else + return _table[row] ??= new ReflectionPropertySymbol(_context, _module, _type, property); + + return _table[row] ?? throw new InvalidOperationException(); + } + } + + /// + /// Gets or creates the cached for the type by property. + /// + /// + /// + public IReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property) + { + return (IReflectionPropertySymbolBuilder)GetOrCreatePropertySymbol((PropertyInfo)property); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbol.cs index 822ba085c..ae1c1f317 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbol.cs @@ -60,7 +60,7 @@ public virtual IReflectionAssemblySymbolBuilder ResolveAssemblySymbol(AssemblyBu /// [return: NotNullIfNotNull(nameof(assemblies))] - public virtual IReflectionAssemblySymbol[]? ResolveAssemblySymbols(Assembly[]? assemblies) + public IReflectionAssemblySymbol[]? ResolveAssemblySymbols(Assembly[]? assemblies) { if (assemblies == null) return null; @@ -94,7 +94,7 @@ public virtual IReflectionModuleSymbolBuilder ResolveModuleSymbol(ModuleBuilder /// [return: NotNullIfNotNull(nameof(modules))] - public virtual IReflectionModuleSymbol[]? ResolveModuleSymbols(Module[]? modules) + public IReflectionModuleSymbol[]? ResolveModuleSymbols(Module[]? modules) { if (modules == null) return null; @@ -110,7 +110,7 @@ public virtual IReflectionModuleSymbolBuilder ResolveModuleSymbol(ModuleBuilder } /// - public virtual IEnumerable ResolveModuleSymbols(IEnumerable modules) + public IEnumerable ResolveModuleSymbols(IEnumerable modules) { foreach (var module in modules) if (ResolveModuleSymbol(module) is { } symbol) @@ -138,7 +138,7 @@ public virtual IEnumerable ResolveModuleSymbols(IEnumer /// [return: NotNullIfNotNull(nameof(members))] - public virtual IReflectionMemberSymbol[]? ResolveMemberSymbols(MemberInfo[]? members) + public IReflectionMemberSymbol[]? ResolveMemberSymbols(MemberInfo[]? members) { if (members == null) return null; @@ -172,7 +172,7 @@ public virtual IReflectionTypeSymbolBuilder ResolveTypeSymbol(TypeBuilder type) /// [return: NotNullIfNotNull(nameof(types))] - public virtual IReflectionTypeSymbol[]? ResolveTypeSymbols(Type[]? types) + public IReflectionTypeSymbol[]? ResolveTypeSymbols(Type[]? types) { if (types == null) return null; @@ -188,7 +188,7 @@ public virtual IReflectionTypeSymbolBuilder ResolveTypeSymbol(TypeBuilder type) } /// - public virtual IEnumerable ResolveTypeSymbols(IEnumerable types) + public IEnumerable ResolveTypeSymbols(IEnumerable types) { foreach (var type in types) if (ResolveTypeSymbol(type) is { } symbol) @@ -226,7 +226,7 @@ public virtual IReflectionConstructorSymbolBuilder ResolveConstructorSymbol(Cons /// [return: NotNullIfNotNull(nameof(ctors))] - public virtual IReflectionConstructorSymbol[]? ResolveConstructorSymbols(ConstructorInfo[]? ctors) + public IReflectionConstructorSymbol[]? ResolveConstructorSymbols(ConstructorInfo[]? ctors) { if (ctors == null) return null; @@ -260,7 +260,7 @@ public virtual IReflectionMethodSymbolBuilder ResolveMethodSymbol(MethodBuilder /// [return: NotNullIfNotNull(nameof(methods))] - public virtual IReflectionMethodSymbol[]? ResolveMethodSymbols(MethodInfo[]? methods) + public IReflectionMethodSymbol[]? ResolveMethodSymbols(MethodInfo[]? methods) { if (methods == null) return null; @@ -294,7 +294,7 @@ public virtual IReflectionFieldSymbolBuilder ResolveFieldSymbol(FieldBuilder fie /// [return: NotNullIfNotNull(nameof(fields))] - public virtual IReflectionFieldSymbol[]? ResolveFieldSymbols(FieldInfo[]? fields) + public IReflectionFieldSymbol[]? ResolveFieldSymbols(FieldInfo[]? fields) { if (fields == null) return null; @@ -328,7 +328,7 @@ public virtual IReflectionPropertySymbolBuilder ResolvePropertySymbol(PropertyBu /// [return: NotNullIfNotNull(nameof(properties))] - public virtual IReflectionPropertySymbol[]? ResolvePropertySymbols(PropertyInfo[]? properties) + public IReflectionPropertySymbol[]? ResolvePropertySymbols(PropertyInfo[]? properties) { if (properties == null) return null; @@ -347,12 +347,15 @@ public virtual IReflectionPropertySymbolBuilder ResolvePropertySymbol(PropertyBu [return: NotNullIfNotNull(nameof(@event))] public virtual IReflectionEventSymbol? ResolveEventSymbol(EventInfo? @event) { - return @event == null ? null : _context.GetOrCreateEventSymbol(@event); + if (@event is null) + return null; + + return _context.GetOrCreateEventSymbol(@event); } /// [return: NotNullIfNotNull(nameof(@event))] - public virtual IReflectionEventSymbolBuilder ResolveEventSymbol(EventBuilder @event) + public virtual IReflectionEventSymbolBuilder? ResolveEventSymbol(EventBuilder @event) { if (@event is null) throw new ArgumentNullException(nameof(@event)); @@ -362,7 +365,7 @@ public virtual IReflectionEventSymbolBuilder ResolveEventSymbol(EventBuilder @ev /// [return: NotNullIfNotNull(nameof(events))] - public virtual IReflectionEventSymbol[]? ResolveEventSymbols(EventInfo[]? events) + public IReflectionEventSymbol[]? ResolveEventSymbols(EventInfo[]? events) { if (@events == null) return null; @@ -381,22 +384,41 @@ public virtual IReflectionEventSymbolBuilder ResolveEventSymbol(EventBuilder @ev [return: NotNullIfNotNull(nameof(parameter))] public virtual IReflectionParameterSymbol? ResolveParameterSymbol(ParameterInfo? parameter) { - return parameter == null ? null : _context.GetOrCreateParameterSymbol(parameter); + if (parameter is null) + throw new ArgumentNullException(nameof(parameter)); + + return _context.GetOrCreateParameterSymbol(parameter); } /// [return: NotNullIfNotNull(nameof(parameter))] - public virtual IReflectionParameterSymbolBuilder ResolveParameterSymbol(ParameterBuilder parameter) + public virtual IReflectionParameterSymbolBuilder? ResolveParameterSymbol(IReflectionMethodBaseSymbolBuilder method, ParameterBuilder parameter) { + if (method is null) + throw new ArgumentNullException(nameof(method)); + if (parameter is null) - throw new ArgumentNullException(nameof(parameter)); + return null; - return _context.GetOrCreateParameterSymbol(parameter); + return method.GetOrCreateParameterSymbol(parameter); + } + + /// + [return: NotNullIfNotNull(nameof(parameter))] + public virtual IReflectionParameterSymbolBuilder? ResolveParameterSymbol(IReflectionPropertySymbolBuilder property, ParameterBuilder parameter) + { + if (property is null) + throw new ArgumentNullException(nameof(property)); + + if (parameter is null) + return null; + + return property.GetOrCreateParameterSymbol(parameter); } /// [return: NotNullIfNotNull(nameof(parameters))] - public virtual IReflectionParameterSymbol[]? ResolveParameterSymbols(ParameterInfo[]? parameters) + public IReflectionParameterSymbol[]? ResolveParameterSymbols(ParameterInfo[]? parameters) { if (parameters == null) return null; @@ -413,7 +435,7 @@ public virtual IReflectionParameterSymbolBuilder ResolveParameterSymbol(Paramete /// [return: NotNullIfNotNull(nameof(attributes))] - public virtual CustomAttribute[]? ResolveCustomAttributes(IList? attributes) + public CustomAttribute[]? ResolveCustomAttributes(IList? attributes) { if (attributes == null) return null; @@ -429,7 +451,7 @@ public virtual IReflectionParameterSymbolBuilder ResolveParameterSymbol(Paramete } /// - public virtual IEnumerable ResolveCustomAttributes(IEnumerable attributes) + public IEnumerable ResolveCustomAttributes(IEnumerable attributes) { if (attributes is null) throw new ArgumentNullException(nameof(attributes)); @@ -444,7 +466,7 @@ public virtual IEnumerable ResolveCustomAttributes(IEnumerable< /// [return: NotNullIfNotNull(nameof(customAttributeData))] - public virtual CustomAttribute? ResolveCustomAttribute(CustomAttributeData? customAttributeData) + public CustomAttribute? ResolveCustomAttribute(CustomAttributeData? customAttributeData) { if (customAttributeData == null) return null; @@ -484,6 +506,7 @@ public CustomAttributeTypedArgument ResolveCustomAttributeTypedArgument(System.R { return value switch { + IList aa => ResolveCustomAttributeTypedArguments(aa), Type v => ResolveTypeSymbol(v), _ => value }; @@ -527,9 +550,9 @@ public InterfaceMapping ResolveInterfaceMapping(System.Reflection.InterfaceMappi /// public ManifestResourceInfo? ResolveManifestResourceInfo(System.Reflection.ManifestResourceInfo? info) { - return info != null ? new ManifestResourceInfo(info.ResourceLocation, info.FileName, ResolveAssemblySymbol(info.ReferencedAssembly)) : null; + return info != null ? new ManifestResourceInfo((System.Reflection.ResourceLocation)info.ResourceLocation, info.FileName, ResolveAssemblySymbol(info.ReferencedAssembly)) : null; } } -} \ No newline at end of file +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs index 8b57fc2b6..1b876eb33 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs @@ -17,7 +17,7 @@ namespace IKVM.CoreLib.Symbols.Reflection class ReflectionSymbolContext : ISymbolContext { - readonly ConcurrentDictionary> _symbolByName = new(AssemblyNameEqualityComparer.Instance); + readonly ConcurrentDictionary> _symbolByName = new(); readonly ConditionalWeakTable _symbolByAssembly = new(); /// @@ -28,32 +28,30 @@ public ReflectionSymbolContext() } - /// - /// Defines a dynamic assembly that has the specified name and access rights. - /// - /// - /// - /// + /// public IAssemblySymbolBuilder DefineAssembly(AssemblyNameInfo name) { if (name is null) throw new ArgumentNullException(nameof(name)); +#if NET return GetOrCreateAssemblySymbol(AssemblyBuilder.DefineDynamicAssembly(name.Unpack(), AssemblyBuilderAccess.RunAndCollect)); +#else + return GetOrCreateAssemblySymbol(AssemblyBuilder.DefineDynamicAssembly(name.Unpack(), AssemblyBuilderAccess.RunAndSave)); +#endif } - /// - /// Defines a dynamic assembly that has the specified name and access rights. - /// - /// - /// - /// + /// public IAssemblySymbolBuilder DefineAssembly(AssemblyNameInfo name, ICustomAttributeBuilder[]? assemblyAttributes) { if (name is null) throw new ArgumentNullException(nameof(name)); +#if NET return GetOrCreateAssemblySymbol(AssemblyBuilder.DefineDynamicAssembly(name.Unpack(), AssemblyBuilderAccess.RunAndCollect, assemblyAttributes?.Unpack())); +#else + return GetOrCreateAssemblySymbol(AssemblyBuilder.DefineDynamicAssembly(name.Unpack(), AssemblyBuilderAccess.RunAndSave,assemblyAttributes?.Unpack())); +#endif } /// @@ -63,7 +61,7 @@ public IAssemblySymbolBuilder DefineAssembly(AssemblyNameInfo name, ICustomAttri /// IReflectionAssemblySymbol GetOrCreateAssemblySymbolByName(Assembly assembly) { - var r = _symbolByName.GetOrAdd(assembly.GetName(), _ => new(null)); + var r = _symbolByName.GetOrAdd(assembly.FullName ?? throw new InvalidOperationException(), _ => new(null)); lock (r) { @@ -73,7 +71,6 @@ IReflectionAssemblySymbol GetOrCreateAssemblySymbolByName(Assembly assembly) if (assembly is AssemblyBuilder builder) { // we were passed in a builder, so generate a symbol builder and set it as the builder and symbol. - var a = builder.GetRuntimeAssembly(); r.SetTarget(s = new ReflectionAssemblySymbolBuilder(this, builder)); } else @@ -138,7 +135,7 @@ public IReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) /// public IReflectionModuleSymbolBuilder GetOrCreateModuleSymbol(ModuleBuilder module) { - return GetOrCreateAssemblySymbol(module.Assembly).GetOrCreateModuleSymbol(module); + return GetOrCreateAssemblySymbol((AssemblyBuilder)module.Assembly).GetOrCreateModuleSymbol(module); } /// @@ -161,7 +158,38 @@ public IReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) /// public IReflectionTypeSymbolBuilder GetOrCreateTypeSymbol(TypeBuilder type) { - return GetOrCreateModuleSymbol(type.Module).GetOrCreateTypeSymbol(type); + return GetOrCreateModuleSymbol((ModuleBuilder)type.Module).GetOrCreateTypeSymbol(type); + } + + /// + /// Gets or creates a for the specified . + /// + /// + /// + public IReflectionMemberSymbol GetOrCreateMemberSymbol(MemberInfo member) + { + return member switch + { + MethodBase method => GetOrCreateMethodBaseSymbol(method), + FieldInfo field => GetOrCreateFieldSymbol(field), + PropertyInfo property => GetOrCreatePropertySymbol(property), + EventInfo @event => GetOrCreateEventSymbol(@event), + _ => throw new InvalidOperationException(), + }; + } + + /// + /// Gets or creates a for the specified . + /// + /// + /// + public IReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method) + { + return method switch + { + ConstructorInfo ctor => GetOrCreateConstructorSymbol(ctor), + _ => GetOrCreateMethodSymbol((MethodInfo)method) + }; } /// @@ -171,10 +199,11 @@ public IReflectionTypeSymbolBuilder GetOrCreateTypeSymbol(TypeBuilder type) /// public IReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) { - if (ctor is ConstructorBuilder builder) - return GetOrCreateConstructorSymbol(builder); - else - return GetOrCreateModuleSymbol(ctor.Module).GetOrCreateConstructorSymbol(ctor); + return ctor switch + { + ConstructorBuilder builder => GetOrCreateConstructorSymbol(builder), + _ => GetOrCreateModuleSymbol(ctor.Module).GetOrCreateConstructorSymbol(ctor) + }; } /// @@ -184,7 +213,7 @@ public IReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo /// public IReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor) { - return GetOrCreateModuleSymbol(ctor.Module).GetOrCreateConstructorSymbol(ctor); + return GetOrCreateModuleSymbol((ModuleBuilder)ctor.Module).GetOrCreateConstructorSymbol(ctor); } /// @@ -194,10 +223,11 @@ public IReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(Construc /// public IReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) { - if (method is MethodBuilder builder) - return GetOrCreateMethodSymbol(builder); - else - return GetOrCreateModuleSymbol(method.Module).GetOrCreateMethodSymbol(method); + return method switch + { + MethodBuilder builder => GetOrCreateMethodSymbol(builder), + _ => GetOrCreateModuleSymbol(method.Module).GetOrCreateMethodSymbol(method) + }; } /// @@ -207,7 +237,7 @@ public IReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) /// public IReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method) { - return GetOrCreateModuleSymbol(method.Module).GetOrCreateMethodSymbol(method); + return GetOrCreateModuleSymbol((ModuleBuilder)method.Module).GetOrCreateMethodSymbol(method); } /// @@ -220,16 +250,6 @@ public IReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo param return GetOrCreateModuleSymbol(parameter.Member.Module).GetOrCreateParameterSymbol(parameter); } - /// - /// Gets or creates a for the specified . - /// - /// - /// - public IReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter) - { - return GetOrCreateModuleSymbol(parameter.GetModuleBuilder()).GetOrCreateParameterSymbol(parameter); - } - /// /// Gets or creates a for the specified . /// @@ -237,10 +257,7 @@ public IReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBui /// public IReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) { - if (field is FieldBuilder builder) - return GetOrCreateFieldSymbol(builder); - else - return GetOrCreateModuleSymbol(field.Module).GetOrCreateFieldSymbol(field); + return GetOrCreateModuleSymbol(field.Module).GetOrCreateFieldSymbol(field); } /// @@ -250,7 +267,7 @@ public IReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) /// public IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field) { - return GetOrCreateModuleSymbol(field.Module).GetOrCreateFieldSymbol(field); + return GetOrCreateModuleSymbol((ModuleBuilder)field.Module).GetOrCreateFieldSymbol(field); } /// @@ -260,10 +277,11 @@ public IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field) /// public IReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) { - if (property is PropertyBuilder builder) - return GetOrCreatePropertySymbol(builder); - else - return GetOrCreateModuleSymbol(property.Module).GetOrCreatePropertySymbol(property); + return property switch + { + PropertyBuilder builder => GetOrCreatePropertySymbol(builder), + _ => GetOrCreateModuleSymbol(property.Module).GetOrCreatePropertySymbol(property) + }; } /// @@ -273,7 +291,7 @@ public IReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property /// public IReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property) { - return GetOrCreateModuleSymbol(property.Module).GetOrCreatePropertySymbol(property); + return GetOrCreateModuleSymbol((ModuleBuilder)property.Module).GetOrCreatePropertySymbol(property); } /// @@ -296,28 +314,65 @@ public IReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event) return GetOrCreateModuleSymbol(@event.GetModuleBuilder()).GetOrCreateEventSymbol(@event); } + /// + /// Gets or creates a for the specified . + /// + /// + /// + public IReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeParameterSymbol(GenericTypeParameterBuilder genericTypeParameter) + { + return GetOrCreateModuleSymbol((ModuleBuilder)genericTypeParameter.Module).GetOrCreateGenericTypeParameterSymbol(genericTypeParameter); + } + /// public ICustomAttributeBuilder CreateCustomAttribute(IConstructorSymbol con, object?[] constructorArgs) { - return new ReflectionCustomAttributeBuilder(new CustomAttributeBuilder(con.Unpack(), constructorArgs)); + return new ReflectionCustomAttributeBuilder(new CustomAttributeBuilder(con.Unpack(), UnpackArguments(constructorArgs))); } /// public ICustomAttributeBuilder CreateCustomAttribute(IConstructorSymbol con, object?[] constructorArgs, IFieldSymbol[] namedFields, object?[] fieldValues) { - return new ReflectionCustomAttributeBuilder(new CustomAttributeBuilder(con.Unpack(), constructorArgs, namedFields.Unpack(), fieldValues)); + return new ReflectionCustomAttributeBuilder(new CustomAttributeBuilder(con.Unpack(), UnpackArguments(constructorArgs), namedFields.Unpack(), UnpackArguments(fieldValues))); } /// public ICustomAttributeBuilder CreateCustomAttribute(IConstructorSymbol con, object?[] constructorArgs, IPropertySymbol[] namedProperties, object?[] propertyValues) { - return new ReflectionCustomAttributeBuilder(new CustomAttributeBuilder(con.Unpack(), constructorArgs, namedProperties.Unpack(), propertyValues)); + return new ReflectionCustomAttributeBuilder(new CustomAttributeBuilder(con.Unpack(), UnpackArguments(constructorArgs), namedProperties.Unpack(), UnpackArguments(propertyValues))); } /// public ICustomAttributeBuilder CreateCustomAttribute(IConstructorSymbol con, object?[] constructorArgs, IPropertySymbol[] namedProperties, object?[] propertyValues, IFieldSymbol[] namedFields, object?[] fieldValues) { - return new ReflectionCustomAttributeBuilder(new CustomAttributeBuilder(con.Unpack(), constructorArgs, namedProperties.Unpack(), propertyValues, namedFields.Unpack(), fieldValues)); + return new ReflectionCustomAttributeBuilder(new CustomAttributeBuilder(con.Unpack(), UnpackArguments(constructorArgs), namedProperties.Unpack(), UnpackArguments(propertyValues), namedFields.Unpack(), UnpackArguments(fieldValues))); + } + + /// + /// Unpacks a single constructor argument. + /// + /// + /// + object? UnpackArgument(object? constructorArg) + { + if (constructorArg is ITypeSymbol type) + return type.Unpack(); + + return constructorArg; + } + + /// + /// Unpacks a set of constructor arguments. + /// + /// + /// + object?[] UnpackArguments(object?[] constructorArgs) + { + var l = new object?[constructorArgs.Length]; + for (int i = 0; i < constructorArgs.Length; i++) + l[i] = UnpackArgument(constructorArgs[i]); + + return l; } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeImpl.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeImpl.cs deleted file mode 100644 index c7821414c..000000000 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeImpl.cs +++ /dev/null @@ -1,633 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Reflection; -using System.Threading; - -namespace IKVM.CoreLib.Symbols.Reflection -{ - - /// - /// Provides common operations against a . - /// - struct ReflectionTypeImpl - { - - readonly IReflectionTypeSymbol _symbol; - - ReflectionTypeSymbol?[]? _asArray; - ReflectionTypeSymbol? _asSZArray; - ReflectionTypeSymbol? _asPointer; - ReflectionTypeSymbol? _asByRef; - ConcurrentDictionary? _genericTypeSymbols; - - /// - /// Initializes a new instance. - /// - /// - /// - public ReflectionTypeImpl(IReflectionTypeSymbol symbol) - { - _symbol = symbol ?? throw new ArgumentNullException(nameof(symbol)); - } - - /// - /// Gets or creates the cached for the generic parameter type. - /// - /// - /// - public IReflectionTypeSymbol GetOrCreateGenericTypeSymbol(ITypeSymbol[] genericTypeArguments) - { - if (genericTypeArguments is null) - throw new ArgumentNullException(nameof(genericTypeArguments)); - - if (_symbol.UnderlyingType.IsGenericTypeDefinition == false) - throw new InvalidOperationException(); - - if (_genericTypeSymbols == null) - Interlocked.CompareExchange(ref _genericTypeSymbols, new ConcurrentDictionary(TypeSymbolListEqualityComparer.Instance), null); - - var __symbol = _symbol; - return _genericTypeSymbols.GetOrAdd(genericTypeArguments, _ => new ReflectionTypeSymbol(__symbol.Context, __symbol.ResolvingModule, __symbol.UnderlyingType.MakeGenericType(genericTypeArguments.Unpack()))); - } - - /// - public readonly IAssemblySymbol Assembly => _symbol.ResolveAssemblySymbol(_symbol.UnderlyingType.Assembly); - - /// - public readonly string? AssemblyQualifiedName => _symbol.UnderlyingType.AssemblyQualifiedName; - - /// - public readonly TypeAttributes Attributes => _symbol.UnderlyingType.Attributes; - - /// - public readonly ITypeSymbol? BaseType => _symbol.ResolveTypeSymbol(_symbol.UnderlyingType.BaseType); - - /// - public readonly bool ContainsGenericParameters => _symbol.UnderlyingType.ContainsGenericParameters; - - /// - public readonly IMethodBaseSymbol? DeclaringMethod => _symbol.ResolveMethodBaseSymbol(_symbol.UnderlyingType.DeclaringMethod); - - /// - public readonly string? FullName => _symbol.UnderlyingType.FullName; - - /// - public readonly string? Namespace => _symbol.UnderlyingType.Namespace; - - /// - public readonly GenericParameterAttributes GenericParameterAttributes => _symbol.UnderlyingType.GenericParameterAttributes; - - /// - public readonly int GenericParameterPosition => _symbol.UnderlyingType.GenericParameterPosition; - - /// - public readonly ITypeSymbol[] GenericTypeArguments => _symbol.ResolveTypeSymbols(_symbol.UnderlyingType.GenericTypeArguments); - - /// - public readonly bool HasElementType => _symbol.UnderlyingType.HasElementType; - - /// - public readonly TypeCode TypeCode => Type.GetTypeCode(_symbol.UnderlyingType); - - /// - public readonly bool IsAbstract => _symbol.UnderlyingType.IsAbstract; - -#if NETFRAMEWORK - - /// - /// - /// There's no API to distinguish an array of rank 1 from a vector, - /// so we check if the type name ends in [], which indicates it's a vector - /// (non-vectors will have [*] or [,]). - /// - public readonly bool IsSZArray => _symbol.UnderlyingType.IsArray && _symbol.UnderlyingType.Name.EndsWith("[]"); - -#else - - /// - public readonly bool IsSZArray => _symbol.UnderlyingType.IsSZArray; - -#endif - - /// - public readonly bool IsArray => _symbol.UnderlyingType.IsArray; - - /// - public readonly bool IsAutoLayout => _symbol.UnderlyingType.IsAutoLayout; - - /// - public readonly bool IsExplicitLayout => _symbol.UnderlyingType.IsExplicitLayout; - - /// - public readonly bool IsByRef => _symbol.UnderlyingType.IsByRef; - - /// - public readonly bool IsClass => _symbol.UnderlyingType.IsClass; - - /// - public readonly bool IsEnum => _symbol.UnderlyingType.IsEnum; - - /// - public readonly bool IsInterface => _symbol.UnderlyingType.IsInterface; - - /// - public readonly bool IsConstructedGenericType => _symbol.UnderlyingType.IsConstructedGenericType; - - /// - public readonly bool IsGenericParameter => _symbol.UnderlyingType.IsGenericParameter; - - /// - public readonly bool IsGenericType => _symbol.UnderlyingType.IsGenericType; - - /// - public readonly bool IsGenericTypeDefinition => _symbol.UnderlyingType.IsGenericTypeDefinition; - - /// - public readonly bool IsLayoutSequential => _symbol.UnderlyingType.IsLayoutSequential; - - /// - public readonly bool IsNested => _symbol.UnderlyingType.IsNested; - - /// - public readonly bool IsNestedAssembly => _symbol.UnderlyingType.IsNestedAssembly; - - /// - public readonly bool IsNestedFamANDAssem => _symbol.UnderlyingType.IsNestedFamANDAssem; - - /// - public readonly bool IsNestedFamORAssem => _symbol.UnderlyingType.IsNestedFamORAssem; - - /// - public readonly bool IsNestedFamily => _symbol.UnderlyingType.IsNestedFamily; - - /// - public readonly bool IsNestedPrivate => _symbol.UnderlyingType.IsNestedPrivate; - - /// - public readonly bool IsNestedPublic => _symbol.UnderlyingType.IsNestedPublic; - - /// - public readonly bool IsNotPublic => _symbol.UnderlyingType.IsNotPublic; - - /// - public readonly bool IsPointer => _symbol.UnderlyingType.IsPointer; - -#if NET8_0_OR_GREATER - - /// - public readonly bool IsFunctionPointer => _symbol.UnderlyingType.IsFunctionPointer; - - /// - public readonly bool IsUnmanagedFunctionPointer => _symbol.UnderlyingType.IsUnmanagedFunctionPointer; - -#else - - /// - public readonly bool IsFunctionPointer => throw new NotImplementedException(); - - /// - public readonly bool IsUnmanagedFunctionPointer => throw new NotImplementedException(); - -#endif - - /// - public readonly bool IsPrimitive => _symbol.UnderlyingType.IsPrimitive; - - /// - public readonly bool IsPublic => _symbol.UnderlyingType.IsPublic; - - /// - public readonly bool IsSealed => _symbol.UnderlyingType.IsSealed; - -#pragma warning disable SYSLIB0050 // Type or member is obsolete - /// - public readonly bool IsSerializable => _symbol.UnderlyingType.IsSerializable; -#pragma warning restore SYSLIB0050 // Type or member is obsolete - - /// - public readonly bool IsValueType => _symbol.UnderlyingType.IsValueType; - - /// - public readonly bool IsVisible => _symbol.UnderlyingType.IsVisible; - -#if NET6_0_OR_GREATER - - /// - public readonly bool IsSignatureType => _symbol.UnderlyingType.IsSignatureType; - -#else - - /// - public readonly bool IsSignatureType => throw new NotImplementedException(); - -#endif - - /// - public readonly bool IsSpecialName => _symbol.UnderlyingType.IsSpecialName; - - /// - public readonly IConstructorSymbol? TypeInitializer => _symbol.ResolveConstructorSymbol(_symbol.UnderlyingType.TypeInitializer); - - /// - public readonly int GetArrayRank() - { - return _symbol.UnderlyingType.GetArrayRank(); - } - - /// - public readonly IConstructorSymbol? GetConstructor(BindingFlags bindingAttr, ITypeSymbol[] types) - { - return _symbol.ResolveConstructorSymbol(_symbol.UnderlyingType.GetConstructor(bindingAttr, binder: null, types.Unpack(), modifiers: null)); - } - - /// - public readonly IConstructorSymbol? GetConstructor(ITypeSymbol[] types) - { - return _symbol.ResolveConstructorSymbol(_symbol.UnderlyingType.GetConstructor(types.Unpack())); - } - - /// - public readonly IConstructorSymbol[] GetConstructors() - { - return _symbol.ResolveConstructorSymbols(_symbol.UnderlyingType.GetConstructors()); - } - - /// - public readonly IConstructorSymbol[] GetConstructors(BindingFlags bindingAttr) - { - return _symbol.ResolveConstructorSymbols(_symbol.UnderlyingType.GetConstructors(bindingAttr)); - } - - /// - public readonly IMemberSymbol[] GetDefaultMembers() - { - return _symbol.ResolveMemberSymbols(_symbol.UnderlyingType.GetDefaultMembers()); - } - - /// - public readonly ITypeSymbol? GetElementType() - { - return _symbol.ResolveTypeSymbol(_symbol.UnderlyingType.GetElementType()); - } - - /// - public readonly string? GetEnumName(object value) - { - return _symbol.UnderlyingType.GetEnumName(value); - } - - /// - public readonly string[] GetEnumNames() - { - return _symbol.UnderlyingType.GetEnumNames(); - } - - /// - public readonly ITypeSymbol GetEnumUnderlyingType() - { - return _symbol.ResolveTypeSymbol(_symbol.UnderlyingType.GetEnumUnderlyingType()); - } - - /// - public readonly Array GetEnumValues() - { - return _symbol.UnderlyingType.GetEnumValues(); - } - - /// - public readonly IEventSymbol? GetEvent(string name) - { - return _symbol.ResolveEventSymbol(_symbol.UnderlyingType.GetEvent(name)); - } - - /// - public readonly IEventSymbol? GetEvent(string name, BindingFlags bindingAttr) - { - return _symbol.ResolveEventSymbol(_symbol.UnderlyingType.GetEvent(name, bindingAttr)); - } - - /// - public readonly IEventSymbol[] GetEvents() - { - return _symbol.ResolveEventSymbols(_symbol.UnderlyingType.GetEvents()); - } - - /// - public readonly IEventSymbol[] GetEvents(BindingFlags bindingAttr) - { - return _symbol.ResolveEventSymbols(_symbol.UnderlyingType.GetEvents(bindingAttr)); - } - - /// - public readonly IFieldSymbol? GetField(string name) - { - return _symbol.ResolveFieldSymbol(_symbol.UnderlyingType.GetField(name)); - } - - /// - public readonly IFieldSymbol? GetField(string name, BindingFlags bindingAttr) - { - return _symbol.ResolveFieldSymbol(_symbol.UnderlyingType.GetField(name, bindingAttr)); - } - - /// - public readonly IFieldSymbol[] GetFields() - { - return _symbol.ResolveFieldSymbols(_symbol.UnderlyingType.GetFields()); - } - - /// - public readonly IFieldSymbol[] GetFields(BindingFlags bindingAttr) - { - return _symbol.ResolveFieldSymbols(_symbol.UnderlyingType.GetFields(bindingAttr)); - } - - /// - public readonly ITypeSymbol[] GetGenericArguments() - { - return _symbol.ResolveTypeSymbols(_symbol.UnderlyingType.GetGenericArguments()); - } - - /// - public readonly ITypeSymbol[] GetGenericParameterConstraints() - { - return _symbol.ResolveTypeSymbols(_symbol.UnderlyingType.GetGenericParameterConstraints()); - } - - /// - public readonly ITypeSymbol GetGenericTypeDefinition() - { - return _symbol.ResolveTypeSymbol(_symbol.UnderlyingType.GetGenericTypeDefinition()); - } - - /// - public readonly ITypeSymbol? GetInterface(string name) - { - return _symbol.ResolveTypeSymbol(_symbol.UnderlyingType.GetInterface(name)); - } - - /// - public readonly ITypeSymbol? GetInterface(string name, bool ignoreCase) - { - return _symbol.ResolveTypeSymbol(_symbol.UnderlyingType.GetInterface(name, ignoreCase)); - } - - /// - public readonly InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) - { - return _symbol.ResolveInterfaceMapping(_symbol.UnderlyingType.GetInterfaceMap(interfaceType.Unpack())); - } - - /// - public readonly ITypeSymbol[] GetInterfaces(bool inherit = true) - { - if (inherit) - return _symbol.ResolveTypeSymbols(_symbol.UnderlyingType.GetInterfaces()); - else - throw new NotImplementedException(); - } - - /// - public readonly IMemberSymbol[] GetMember(string name) - { - return _symbol.ResolveMemberSymbols(_symbol.UnderlyingType.GetMember(name)); - } - - /// - public readonly IMemberSymbol[] GetMember(string name, BindingFlags bindingAttr) - { - return _symbol.ResolveMemberSymbols(_symbol.UnderlyingType.GetMember(name, bindingAttr)); - } - - /// - public readonly IMemberSymbol[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) - { - return _symbol.ResolveMemberSymbols(_symbol.UnderlyingType.GetMember(name, type, bindingAttr)); - } - - /// - public readonly IMemberSymbol[] GetMembers(BindingFlags bindingAttr) - { - return _symbol.ResolveMemberSymbols(_symbol.UnderlyingType.GetMembers(bindingAttr)); - } - - /// - public readonly IMemberSymbol[] GetMembers() - { - return _symbol.ResolveMemberSymbols(_symbol.UnderlyingType.GetMembers()); - } - - /// - public readonly IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr) - { - return _symbol.ResolveMethodSymbol(_symbol.UnderlyingType.GetMethod(name, bindingAttr)); - } - - /// - public readonly IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) - { - return _symbol.ResolveMethodSymbol(_symbol.UnderlyingType.GetMethod(name, types.Unpack())); - } - - /// - public readonly IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types) - { - return _symbol.ResolveMethodSymbol(_symbol.UnderlyingType.GetMethod(name, bindingAttr, null, types.Unpack(), null)); - } - - /// - public readonly IMethodSymbol? GetMethod(string name) - { - return _symbol.ResolveMethodSymbol(_symbol.UnderlyingType.GetMethod(name)); - } - - /// - public readonly IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers) - { - return _symbol.ResolveMethodSymbol(_symbol.UnderlyingType.GetMethod(name, bindingAttr, null, callConvention, types.Unpack(), modifiers)); - } - - /// - public readonly IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers) - { -#if NETFRAMEWORK - throw new NotImplementedException(); -#else - return _symbol.ResolveMethodSymbol(_symbol.UnderlyingType.GetMethod(name, genericParameterCount, bindingAttr, null, callConvention, types.Unpack(), modifiers)); -#endif - } - - /// - public readonly IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, ITypeSymbol[] types, ParameterModifier[]? modifiers) - { -#if NETFRAMEWORK - throw new NotImplementedException(); -#else - return _symbol.ResolveMethodSymbol(_symbol.UnderlyingType.GetMethod(name, genericParameterCount, bindingAttr, null, types.Unpack(), modifiers)); -#endif - } - - /// - public readonly IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types, ParameterModifier[]? modifiers) - { - return _symbol.ResolveMethodSymbol(_symbol.UnderlyingType.GetMethod(name, bindingAttr, null, types.Unpack(), modifiers)); - } - - /// - public readonly IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, ParameterModifier[]? modifiers) - { -#if NETFRAMEWORK - throw new NotImplementedException(); -#else - return _symbol.ResolveMethodSymbol(_symbol.UnderlyingType.GetMethod(name, genericParameterCount, types.Unpack(), modifiers)); -#endif - } - - /// - public readonly IMethodSymbol[] GetMethods(BindingFlags bindingAttr) - { - return _symbol.ResolveMethodSymbols(_symbol.UnderlyingType.GetMethods(bindingAttr)); - } - - /// - public readonly IMethodSymbol[] GetMethods() - { - return _symbol.ResolveMethodSymbols(_symbol.UnderlyingType.GetMethods()); - } - - /// - public readonly ITypeSymbol? GetNestedType(string name) - { - return _symbol.ResolveTypeSymbol(_symbol.UnderlyingType.GetNestedType(name)); - } - - /// - public readonly ITypeSymbol? GetNestedType(string name, BindingFlags bindingAttr) - { - return _symbol.ResolveTypeSymbol(_symbol.UnderlyingType.GetNestedType(name, bindingAttr)); - } - - /// - public readonly ITypeSymbol[] GetNestedTypes() - { - return _symbol.ResolveTypeSymbols(_symbol.UnderlyingType.GetNestedTypes()); - } - - /// - public readonly ITypeSymbol[] GetNestedTypes(BindingFlags bindingAttr) - { - return _symbol.ResolveTypeSymbols(_symbol.UnderlyingType.GetNestedTypes(bindingAttr)); - } - - /// - public readonly IPropertySymbol[] GetProperties() - { - return _symbol.ResolvePropertySymbols(_symbol.UnderlyingType.GetProperties()); - } - - /// - public readonly IPropertySymbol[] GetProperties(BindingFlags bindingAttr) - { - return _symbol.ResolvePropertySymbols(_symbol.UnderlyingType.GetProperties(bindingAttr)); - } - - /// - public readonly IPropertySymbol? GetProperty(string name, ITypeSymbol[] types) - { - return _symbol.ResolvePropertySymbol(_symbol.UnderlyingType.GetProperty(name, types.Unpack())); - } - - /// - public readonly IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types) - { - return _symbol.ResolvePropertySymbol(_symbol.UnderlyingType.GetProperty(name, returnType?.Unpack(), types.Unpack())); - } - - /// - public readonly IPropertySymbol? GetProperty(string name, BindingFlags bindingAttr) - { - return _symbol.ResolvePropertySymbol(_symbol.UnderlyingType.GetProperty(name, bindingAttr)); - } - - /// - public readonly IPropertySymbol? GetProperty(string name) - { - return _symbol.ResolvePropertySymbol(_symbol.UnderlyingType.GetProperty(name)); - } - - /// - public readonly IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) - { - return _symbol.ResolvePropertySymbol(_symbol.UnderlyingType.GetProperty(name, returnType?.Unpack())); - } - - /// - public readonly bool IsAssignableFrom(ITypeSymbol? c) - { - return _symbol.UnderlyingType.IsAssignableFrom(c?.Unpack()); - } - - /// - public readonly bool IsEnumDefined(object value) - { - return _symbol.UnderlyingType.IsEnumDefined(value); - } - - /// - public readonly bool IsSubclassOf(ITypeSymbol c) - { - return _symbol.UnderlyingType.IsSubclassOf(c.Unpack()); - } - - /// - public IReflectionTypeSymbol MakeArrayType() - { - if (_asSZArray == null) - Interlocked.CompareExchange(ref _asSZArray, new ReflectionTypeSymbol(_symbol.Context, _symbol.ResolvingModule, _symbol.UnderlyingType.MakeArrayType()), null); - - return _asSZArray; - } - - /// - public IReflectionTypeSymbol MakeArrayType(int rank) - { - if (rank == 1) - return MakeArrayType(); - - if (_asArray == null) - Interlocked.CompareExchange(ref _asArray, new ReflectionTypeSymbol?[32], null); - - ref var asArray = ref _asArray[rank]; - if (asArray == null) - Interlocked.CompareExchange(ref asArray, new ReflectionTypeSymbol(_symbol.Context, _symbol.ResolvingModule, _symbol.UnderlyingType.MakeArrayType(rank)), null); - - return asArray; - } - - /// - public IReflectionTypeSymbol MakeByRefType() - { - if (_asByRef == null) - Interlocked.CompareExchange(ref _asByRef, new ReflectionTypeSymbol(_symbol.Context, _symbol.ResolvingModule, _symbol.UnderlyingType.MakeByRefType()), null); - - return _asByRef; - } - - /// - public IReflectionTypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments) - { - return GetOrCreateGenericTypeSymbol(typeArguments); - } - - /// - public IReflectionTypeSymbol MakePointerType() - { - if (_asPointer == null) - Interlocked.CompareExchange(ref _asPointer, new ReflectionTypeSymbol(_symbol.Context, _symbol.ResolvingModule, _symbol.UnderlyingType.MakePointerType()), null); - - return _asPointer; - } - - } - -} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSpecTable.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSpecTable.cs new file mode 100644 index 000000000..0f98f8180 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSpecTable.cs @@ -0,0 +1,127 @@ +using System; +using System.Collections.Concurrent; +using System.Threading; + +using IKVM.CoreLib.Collections; +using IKVM.CoreLib.Threading; + +namespace IKVM.CoreLib.Symbols.Reflection +{ + + struct ReflectionTypeSpecTable + { + + readonly ReflectionSymbolContext _context; + readonly IReflectionModuleSymbol _module; + readonly IReflectionTypeSymbol _elementType; + + IndexRangeDictionary _asArray; + ReaderWriterLockSlim? _asArrayLock; + IReflectionTypeSymbol? _asSZArray; + IReflectionTypeSymbol? _asPointer; + IReflectionTypeSymbol? _asByRef; + ConcurrentDictionary? _genericTypeSymbols; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + public ReflectionTypeSpecTable(ReflectionSymbolContext context, IReflectionModuleSymbol module, IReflectionTypeSymbol elementType) + { + _context = context ?? throw new ArgumentNullException(nameof(context)); + _module = module ?? throw new ArgumentNullException(nameof(module)); + _elementType = elementType ?? throw new ArgumentNullException(nameof(elementType)); + _asArray = new IndexRangeDictionary(); + } + + /// + /// Gets or creates a representing an Array of this type. + /// + /// + /// + /// + public IReflectionTypeSymbol GetOrCreateArrayTypeSymbol(int rank) + { + if (_asArrayLock == null) + Interlocked.CompareExchange(ref _asArrayLock, new(), null); + + using (_asArrayLock.CreateUpgradeableReadLock()) + { + if (_asArray[rank] == null) + using (_asArrayLock.CreateWriteLock()) + _asArray[rank] = new ReflectionTypeSymbol(_context, _module, _elementType.UnderlyingType.MakeArrayType(rank)); + + return _asArray[rank] ?? throw new InvalidOperationException(); + } + } + + /// + /// Gets or creates a representing a SZArray of this type. + /// + /// + public IReflectionTypeSymbol GetOrCreateSZArrayTypeSymbol() + { + if (_asSZArray == null) + Interlocked.CompareExchange(ref _asSZArray, new ReflectionTypeSymbol(_context, _module, _elementType.UnderlyingType.MakeArrayType()), null); + + return _asSZArray; + } + + /// + /// Gets or creates a representing a pointer of this type. + /// + /// + public IReflectionTypeSymbol GetOrCreatePointerTypeSymbol() + { + if (_asPointer == null) + Interlocked.CompareExchange(ref _asPointer, new ReflectionTypeSymbol(_context, _module, _elementType.UnderlyingType.MakePointerType()), null); + + return _asPointer; + } + + /// + /// Gets or creates a representing a by-ref of this type. + /// + /// + public IReflectionTypeSymbol GetOrCreateByRefTypeSymbol() + { + if (_asByRef == null) + Interlocked.CompareExchange(ref _asByRef, new ReflectionTypeSymbol(_context, _module, _elementType.UnderlyingType.MakeByRefType()), null); + + return _asByRef; + } + + /// + /// Gets or creates a representing a specialized generic of this type. + /// + /// + /// + public IReflectionTypeSymbol GetOrCreateGenericTypeSymbol(Type[] genericTypeArguments) + { + if (genericTypeArguments is null) + throw new ArgumentNullException(nameof(genericTypeArguments)); + + if (_elementType.IsGenericTypeDefinition == false) + throw new InvalidOperationException(); + + if (_genericTypeSymbols == null) + Interlocked.CompareExchange(ref _genericTypeSymbols, new(TypeSymbolListEqualityComparer.Instance), null); + + return _genericTypeSymbols.GetOrAdd(_module.ResolveTypeSymbols(genericTypeArguments), CreateGenericTypeSymbol); + } + + /// + /// Creates a new representing a specialized generic of this type. + /// + /// + /// + readonly IReflectionTypeSymbol CreateGenericTypeSymbol(IReflectionTypeSymbol[] genericTypeArguments) + { + return new ReflectionTypeSymbol(_context, _module, _elementType.UnderlyingType.MakeGenericType(genericTypeArguments.Unpack())); + } + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbol.cs index 1ff52d680..6e33a9867 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbol.cs @@ -2,6 +2,8 @@ using System.Diagnostics.CodeAnalysis; using System.Reflection; +using IKVM.CoreLib.Reflection; + namespace IKVM.CoreLib.Symbols.Reflection { @@ -9,7 +11,13 @@ class ReflectionTypeSymbol : ReflectionMemberSymbol, IReflectionTypeSymbol { readonly Type _type; - ReflectionTypeImpl _impl; + + ReflectionMethodTable _methodTable; + ReflectionFieldTable _fieldTable; + ReflectionPropertyTable _propertyTable; + ReflectionEventTable _eventTable; + ReflectionGenericTypeParameterTable _genericTypeParameterTable; + ReflectionTypeSpecTable _specTable; /// /// Initializes a new instance. @@ -18,20 +26,108 @@ class ReflectionTypeSymbol : ReflectionMemberSymbol, IReflectionTypeSymbol /// /// public ReflectionTypeSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, Type type) : - base(context, resolvingModule, null, type) + base(context, resolvingModule, null) { _type = type ?? throw new ArgumentNullException(nameof(type)); - _impl = new ReflectionTypeImpl(this); + _methodTable = new ReflectionMethodTable(context, resolvingModule, this); + _fieldTable = new ReflectionFieldTable(context, resolvingModule, this); + _propertyTable = new ReflectionPropertyTable(context, resolvingModule, this); + _eventTable = new ReflectionEventTable(context, resolvingModule, this); + _genericTypeParameterTable = new ReflectionGenericTypeParameterTable(context, resolvingModule, this); + _specTable = new ReflectionTypeSpecTable(context, resolvingModule, this); } /// public Type UnderlyingType => _type; - /// - /// Resolves the symbol for the specified type. - /// - /// - /// + /// + public override MemberInfo UnderlyingMember => UnderlyingType; + + #region IReflectionTypeSymbol + + /// + public IReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) + { + return _methodTable.GetOrCreateConstructorSymbol(ctor); + } + + /// + public IReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method) + { + if (method is ConstructorInfo ctor) + return GetOrCreateConstructorSymbol(ctor); + else + return GetOrCreateMethodSymbol((MethodInfo)method); + } + + /// + public IReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) + { + if (method.IsMethodDefinition()) + return _methodTable.GetOrCreateMethodSymbol(method); + else + return ResolveMethodSymbol(method.GetGenericMethodDefinition()).GetOrCreateGenericMethodSymbol(method); + } + + /// + public IReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) + { + return _fieldTable.GetOrCreateFieldSymbol(field); + } + + /// + public IReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) + { + return _propertyTable.GetOrCreatePropertySymbol(property); + } + + /// + public IReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) + { + return _eventTable.GetOrCreateEventSymbol(@event); + } + + /// + public IReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type genericType) + { + return _genericTypeParameterTable.GetOrCreateGenericTypeParameterSymbol(genericType); + } + + /// + public IReflectionTypeSymbol GetOrCreateSZArrayTypeSymbol() + { + return _specTable.GetOrCreateSZArrayTypeSymbol(); + } + + /// + public IReflectionTypeSymbol GetOrCreateArrayTypeSymbol(int rank) + { + return _specTable.GetOrCreateArrayTypeSymbol(rank); + } + + /// + public IReflectionTypeSymbol GetOrCreatePointerTypeSymbol() + { + return _specTable.GetOrCreatePointerTypeSymbol(); + } + + /// + public IReflectionTypeSymbol GetOrCreateByRefTypeSymbol() + { + return _specTable.GetOrCreateByRefTypeSymbol(); + } + + /// + public IReflectionTypeSymbol GetOrCreateGenericTypeSymbol(Type[] genericTypeDefinition) + { + return _specTable.GetOrCreateGenericTypeSymbol(genericTypeDefinition); + } + + #endregion + + #region IReflectionSymbol + + /// [return: NotNullIfNotNull(nameof(type))] public override IReflectionTypeSymbol? ResolveTypeSymbol(Type? type) { @@ -41,506 +137,530 @@ public ReflectionTypeSymbol(ReflectionSymbolContext context, IReflectionModuleSy return base.ResolveTypeSymbol(type); } + #endregion + #region ITypeSymbol /// - public TypeAttributes Attributes => _impl.Attributes; + public IAssemblySymbol Assembly => ResolveAssemblySymbol(UnderlyingType.Assembly); /// - public IAssemblySymbol Assembly => _impl.Assembly; + public string? AssemblyQualifiedName => UnderlyingType.AssemblyQualifiedName; /// - public IMethodBaseSymbol? DeclaringMethod => _impl.DeclaringMethod; + public System.Reflection.TypeAttributes Attributes => (System.Reflection.TypeAttributes)UnderlyingType.Attributes; /// - public string? AssemblyQualifiedName => _impl.AssemblyQualifiedName; + public ITypeSymbol? BaseType => ResolveTypeSymbol(UnderlyingType.BaseType); /// - public string? FullName => _impl.FullName; + public bool ContainsGenericParameters => UnderlyingType.ContainsGenericParameters; /// - public string? Namespace => _impl.Namespace; + public IMethodBaseSymbol? DeclaringMethod => ResolveMethodBaseSymbol(UnderlyingType.DeclaringMethod); /// - public TypeCode TypeCode => _impl.TypeCode; + public string? FullName => UnderlyingType.FullName; /// - public ITypeSymbol? BaseType => _impl.BaseType; + public string? Namespace => UnderlyingType.Namespace; /// - public bool ContainsGenericParameters => _impl.ContainsGenericParameters; + public System.Reflection.GenericParameterAttributes GenericParameterAttributes => (System.Reflection.GenericParameterAttributes)UnderlyingType.GenericParameterAttributes; /// - public GenericParameterAttributes GenericParameterAttributes => _impl.GenericParameterAttributes; + public int GenericParameterPosition => UnderlyingType.GenericParameterPosition; /// - public int GenericParameterPosition => _impl.GenericParameterPosition; + public ITypeSymbol[] GenericTypeArguments => ResolveTypeSymbols(UnderlyingType.GenericTypeArguments); /// - public ITypeSymbol[] GenericTypeArguments => _impl.GenericTypeArguments; + public bool HasElementType => UnderlyingType.HasElementType; /// - public bool IsConstructedGenericType => _impl.IsConstructedGenericType; + public TypeCode TypeCode => Type.GetTypeCode(UnderlyingType); /// - public bool IsGenericType => _impl.IsGenericType; + public bool IsAbstract => UnderlyingType.IsAbstract; /// - public bool IsGenericTypeDefinition => _impl.IsGenericTypeDefinition; + public bool IsSZArray => UnderlyingType.IsSZArray(); /// - public bool IsGenericParameter => _impl.IsGenericParameter; + public bool IsArray => UnderlyingType.IsArray; /// - public bool IsAutoLayout => _impl.IsAutoLayout; + public bool IsAutoLayout => UnderlyingType.IsAutoLayout; /// - public bool IsExplicitLayout => _impl.IsExplicitLayout; + public bool IsExplicitLayout => UnderlyingType.IsExplicitLayout; /// - public bool IsLayoutSequential => _impl.IsLayoutSequential; + public bool IsByRef => UnderlyingType.IsByRef; /// - public bool HasElementType => _impl.HasElementType; + public bool IsClass => UnderlyingType.IsClass; /// - public bool IsClass => _impl.IsClass; + public bool IsEnum => UnderlyingType.IsEnum; /// - public bool IsValueType => _impl.IsValueType; + public bool IsInterface => UnderlyingType.IsInterface; /// - public bool IsInterface => _impl.IsInterface; + public bool IsConstructedGenericType => UnderlyingType.IsConstructedGenericType; /// - public bool IsPrimitive => _impl.IsPrimitive; + public bool IsGenericParameter => UnderlyingType.IsGenericParameter; /// - public bool IsSZArray => _impl.IsSZArray; + public bool IsGenericType => UnderlyingType.IsGenericType; /// - public bool IsArray => _impl.IsArray; + public bool IsGenericTypeDefinition => UnderlyingType.IsGenericTypeDefinition; /// - public bool IsEnum => _impl.IsEnum; + public bool IsLayoutSequential => UnderlyingType.IsLayoutSequential; /// - public bool IsPointer => _impl.IsPointer; + public bool IsNested => UnderlyingType.IsNested; /// - public bool IsFunctionPointer => _impl.IsFunctionPointer; + public bool IsNestedAssembly => UnderlyingType.IsNestedAssembly; /// - public bool IsUnmanagedFunctionPointer => _impl.IsUnmanagedFunctionPointer; + public bool IsNestedFamANDAssem => UnderlyingType.IsNestedFamANDAssem; /// - public bool IsByRef => _impl.IsByRef; + public bool IsNestedFamORAssem => UnderlyingType.IsNestedFamORAssem; /// - public bool IsAbstract => _impl.IsAbstract; + public bool IsNestedFamily => UnderlyingType.IsNestedFamily; /// - public bool IsSealed => _impl.IsSealed; + public bool IsNestedPrivate => UnderlyingType.IsNestedPrivate; /// - public bool IsVisible => _impl.IsVisible; + public bool IsNestedPublic => UnderlyingType.IsNestedPublic; /// - public bool IsPublic => _impl.IsPublic; + public bool IsNotPublic => UnderlyingType.IsNotPublic; /// - public bool IsNotPublic => _impl.IsNotPublic; + public bool IsPointer => UnderlyingType.IsPointer; + +#if NET8_0_OR_GREATER /// - public bool IsNested => _impl.IsNested; + public bool IsFunctionPointer => UnderlyingType.IsFunctionPointer; /// - public bool IsNestedAssembly => _impl.IsNestedAssembly; + public bool IsUnmanagedFunctionPointer => UnderlyingType.IsUnmanagedFunctionPointer; + +#else /// - public bool IsNestedFamANDAssem => _impl.IsNestedFamANDAssem; + public bool IsFunctionPointer => throw new NotImplementedException(); + + /// + public bool IsUnmanagedFunctionPointer => throw new NotImplementedException(); + +#endif /// - public bool IsNestedFamily => _impl.IsNestedFamily; + public bool IsPrimitive => UnderlyingType.IsPrimitive; /// - public bool IsNestedFamORAssem => _impl.IsNestedFamORAssem; + public bool IsPublic => UnderlyingType.IsPublic; /// - public bool IsNestedPrivate => _impl.IsNestedPrivate; + public bool IsSealed => UnderlyingType.IsSealed; /// - public bool IsNestedPublic => _impl.IsNestedPublic; + public bool IsSerializable => UnderlyingType.IsSerializable; /// - public bool IsSerializable => _impl.IsSerializable; + public bool IsValueType => UnderlyingType.IsValueType; /// - public bool IsSignatureType => _impl.IsSignatureType; + public bool IsVisible => UnderlyingType.IsVisible; /// - public bool IsSpecialName => _impl.IsSpecialName; + public bool IsSignatureType => throw new NotImplementedException(); /// - public IConstructorSymbol? TypeInitializer => throw new NotImplementedException(); + public bool IsSpecialName => UnderlyingType.IsSpecialName; + + /// + public IConstructorSymbol? TypeInitializer => ResolveConstructorSymbol(UnderlyingType.TypeInitializer); /// public int GetArrayRank() { - return _impl.GetArrayRank(); + return UnderlyingType.GetArrayRank(); } /// - public IMemberSymbol[] GetDefaultMembers() + public IConstructorSymbol? GetConstructor(System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) { - return _impl.GetDefaultMembers(); + return ResolveConstructorSymbol(UnderlyingType.GetConstructor((BindingFlags)bindingAttr, binder: null, types.Unpack(), modifiers: null)); } /// - public ITypeSymbol? GetElementType() + public IConstructorSymbol? GetConstructor(ITypeSymbol[] types) { - return _impl.GetElementType(); + return ResolveConstructorSymbol(UnderlyingType.GetConstructor(types.Unpack())); } /// - public string? GetEnumName(object value) + public IConstructorSymbol[] GetConstructors() { - return _impl.GetEnumName(value); + return ResolveConstructorSymbols(UnderlyingType.GetConstructors()); } /// - public string[] GetEnumNames() + public IConstructorSymbol[] GetConstructors(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetEnumNames(); + return ResolveConstructorSymbols(UnderlyingType.GetConstructors((BindingFlags)bindingAttr)); } /// - public ITypeSymbol GetEnumUnderlyingType() + public IMemberSymbol[] GetDefaultMembers() { - return _impl.GetEnumUnderlyingType(); + return ResolveMemberSymbols(UnderlyingType.GetDefaultMembers()); } /// - public ITypeSymbol[] GetGenericArguments() + public ITypeSymbol? GetElementType() { - return _impl.GetGenericArguments(); + return ResolveTypeSymbol(UnderlyingType.GetElementType()); } /// - public ITypeSymbol[] GetGenericParameterConstraints() + public string? GetEnumName(object value) { - return _impl.GetGenericParameterConstraints(); + return UnderlyingType.GetEnumName(value); } /// - public ITypeSymbol GetGenericTypeDefinition() + public string[] GetEnumNames() { - return _impl.GetGenericTypeDefinition(); + return UnderlyingType.GetEnumNames(); } /// - public ITypeSymbol? GetInterface(string name) + public ITypeSymbol GetEnumUnderlyingType() { - return _impl.GetInterface(name); + return ResolveTypeSymbol(UnderlyingType.GetEnumUnderlyingType()); } /// - public ITypeSymbol? GetInterface(string name, bool ignoreCase) + public Array GetEnumValues() { - return _impl.GetInterface(name, ignoreCase); + return UnderlyingType.GetEnumValues(); } /// - public ITypeSymbol[] GetInterfaces(bool inherit = true) + public IEventSymbol? GetEvent(string name) { - return _impl.GetInterfaces(inherit); + return ResolveEventSymbol(UnderlyingType.GetEvent(name)); } /// - public InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) + public IEventSymbol? GetEvent(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetInterfaceMap(interfaceType); + return ResolveEventSymbol(UnderlyingType.GetEvent(name, (BindingFlags)bindingAttr)); } /// - public IMemberSymbol[] GetMember(string name) + public IEventSymbol[] GetEvents() { - return _impl.GetMember(name); + return ResolveEventSymbols(UnderlyingType.GetEvents()); } /// - public IMemberSymbol[] GetMember(string name, BindingFlags bindingAttr) + public IEventSymbol[] GetEvents(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMember(name, bindingAttr); + return ResolveEventSymbols(UnderlyingType.GetEvents((BindingFlags)bindingAttr)); } /// - public IMemberSymbol[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) + public IFieldSymbol? GetField(string name) { - return _impl.GetMember(name, type, bindingAttr); + return ResolveFieldSymbol(UnderlyingType.GetField(name)); } /// - public IMemberSymbol[] GetMembers() + public IFieldSymbol? GetField(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMembers(); + return ResolveFieldSymbol(UnderlyingType.GetField(name, (BindingFlags)bindingAttr)); } /// - public IMemberSymbol[] GetMembers(BindingFlags bindingAttr) + public IFieldSymbol[] GetFields() { - return _impl.GetMembers(bindingAttr); + return ResolveFieldSymbols(UnderlyingType.GetFields()); } - public IConstructorSymbol? GetConstructor(ITypeSymbol[] types) + /// + public IFieldSymbol[] GetFields(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetConstructor(types); + return ResolveFieldSymbols(UnderlyingType.GetFields((BindingFlags)bindingAttr)); } /// - public IConstructorSymbol? GetConstructor(BindingFlags bindingAttr, ITypeSymbol[] types) + public ITypeSymbol[] GetGenericArguments() { - return _impl.GetConstructor(bindingAttr, types); + return ResolveTypeSymbols(UnderlyingType.GetGenericArguments()); } /// - public IConstructorSymbol[] GetConstructors() + public ITypeSymbol[] GetGenericParameterConstraints() { - return _impl.GetConstructors(); + return ResolveTypeSymbols(UnderlyingType.GetGenericParameterConstraints()); } /// - public IConstructorSymbol[] GetConstructors(BindingFlags bindingAttr) + public ITypeSymbol GetGenericTypeDefinition() { - return _impl.GetConstructors(bindingAttr); + return ResolveTypeSymbol(UnderlyingType.GetGenericTypeDefinition()); } /// - public IFieldSymbol? GetField(string name) + public ITypeSymbol? GetInterface(string name) { - return _impl.GetField(name); + return ResolveTypeSymbol(UnderlyingType.GetInterface(name)); } /// - public IFieldSymbol? GetField(string name, BindingFlags bindingAttr) + public ITypeSymbol? GetInterface(string name, bool ignoreCase) { - return _impl.GetField(name, bindingAttr); + return ResolveTypeSymbol(UnderlyingType.GetInterface(name, ignoreCase)); } /// - public IFieldSymbol[] GetFields() + public InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) + { + return ResolveInterfaceMapping(UnderlyingType.GetInterfaceMap(interfaceType.Unpack())); + } + + /// + public ITypeSymbol[] GetInterfaces(bool inherit = true) { - return _impl.GetFields(); + if (inherit) + return ResolveTypeSymbols(UnderlyingType.GetInterfaces()); + else + throw new NotImplementedException(); } /// - public IFieldSymbol[] GetFields(BindingFlags bindingAttr) + public IMemberSymbol[] GetMember(string name) { - return _impl.GetFields(bindingAttr); + return ResolveMemberSymbols(UnderlyingType.GetMember(name)); } /// - public IMethodSymbol? GetMethod(string name) + public IMemberSymbol[] GetMember(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMethod(name); + return ResolveMemberSymbols(UnderlyingType.GetMember(name, (BindingFlags)bindingAttr)); } /// - public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) + public IMemberSymbol[] GetMember(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMethod(name, types); + return ResolveMemberSymbols(UnderlyingType.GetMember(name, (MemberTypes)type, (BindingFlags)bindingAttr)); } /// - public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr) + public IMemberSymbol[] GetMembers(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMethod(name, bindingAttr); + return ResolveMemberSymbols(UnderlyingType.GetMembers((BindingFlags)bindingAttr)); } /// - public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types) + public IMemberSymbol[] GetMembers() { - return _impl.GetMethod(name, bindingAttr, types); + return ResolveMemberSymbols(UnderlyingType.GetMembers()); } /// - public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetMethod(name, bindingAttr, callConvention, types, modifiers); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr)); } /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) { - return _impl.GetMethod(name, genericParameterCount, bindingAttr, callConvention, types, modifiers); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, types.Unpack())); } /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, ITypeSymbol[] types, ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) { - return _impl.GetMethod(name, genericParameterCount, bindingAttr, types, modifiers); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), null)); } /// - public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types, ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name) { - return _impl.GetMethod(name, bindingAttr, types, modifiers); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name)); } /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return _impl.GetMethod(name, genericParameterCount, types, modifiers); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, (CallingConventions)callConvention, types.Unpack(), modifiers?.Unpack())); } /// - public IMethodSymbol[] GetMethods() + public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return _impl.GetMethods(); + throw new NotImplementedException(); } /// - public IMethodSymbol[] GetMethods(BindingFlags bindingAttr) + public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return _impl.GetMethods(bindingAttr); + throw new NotImplementedException(); } /// - public IPropertySymbol? GetProperty(string name) + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return _impl.GetProperty(name); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), modifiers?.Unpack())); } /// - public IPropertySymbol? GetProperty(string name, BindingFlags bindingAttr) + public IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return _impl.GetProperty(name, bindingAttr); + throw new NotImplementedException(); } /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol[] types) + public IMethodSymbol[] GetMethods(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetProperty(name, types); + return ResolveMethodSymbols(UnderlyingType.GetMethods((BindingFlags)bindingAttr)); } /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types) + public IMethodSymbol[] GetMethods() { - return _impl.GetProperty(name, returnType, types); + return ResolveMethodSymbols(UnderlyingType.GetMethods()); } /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) + public ITypeSymbol? GetNestedType(string name) { - return _impl.GetProperty(name, returnType); + return ResolveTypeSymbol(UnderlyingType.GetNestedType(name)); } /// - public IPropertySymbol[] GetProperties() + public ITypeSymbol? GetNestedType(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetProperties(); + return ResolveTypeSymbol(UnderlyingType.GetNestedType(name, (BindingFlags)bindingAttr)); } /// - public IPropertySymbol[] GetProperties(BindingFlags bindingAttr) + public ITypeSymbol[] GetNestedTypes() { - return _impl.GetProperties(bindingAttr); + return ResolveTypeSymbols(UnderlyingType.GetNestedTypes()); } /// - public IEventSymbol? GetEvent(string name) + public ITypeSymbol[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetEvent(name); + return ResolveTypeSymbols(UnderlyingType.GetNestedTypes((BindingFlags)bindingAttr)); } /// - public IEventSymbol? GetEvent(string name, BindingFlags bindingAttr) + public IPropertySymbol[] GetProperties() { - return _impl.GetEvent(name, bindingAttr); + return ResolvePropertySymbols(UnderlyingType.GetProperties()); } /// - public IEventSymbol[] GetEvents() + public IPropertySymbol[] GetProperties(System.Reflection.BindingFlags bindingAttr) { - return _impl.GetEvents(); + return ResolvePropertySymbols(UnderlyingType.GetProperties((BindingFlags)bindingAttr)); } /// - public IEventSymbol[] GetEvents(BindingFlags bindingAttr) + public IPropertySymbol? GetProperty(string name, ITypeSymbol[] types) { - return _impl.GetEvents(bindingAttr); + return ResolvePropertySymbol(UnderlyingType.GetProperty(name, types.Unpack())); } /// - public ITypeSymbol? GetNestedType(string name) + public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types) { - return _impl.GetNestedType(name); + return ResolvePropertySymbol(UnderlyingType.GetProperty(name, returnType?.Unpack(), types.Unpack())); } /// - public ITypeSymbol? GetNestedType(string name, BindingFlags bindingAttr) + public IPropertySymbol? GetProperty(string name, System.Reflection.BindingFlags bindingAttr) { - return _impl.GetNestedType(name, bindingAttr); + return ResolvePropertySymbol(UnderlyingType.GetProperty(name, (BindingFlags)bindingAttr)); } /// - public ITypeSymbol[] GetNestedTypes() + public IPropertySymbol? GetProperty(string name) { - return _impl.GetNestedTypes(); + return ResolvePropertySymbol(UnderlyingType.GetProperty(name)); } /// - public ITypeSymbol[] GetNestedTypes(BindingFlags bindingAttr) + public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) { - return _impl.GetNestedTypes(); + return ResolvePropertySymbol(UnderlyingType.GetProperty(name, returnType?.Unpack())); } /// public bool IsAssignableFrom(ITypeSymbol? c) { - return _impl.IsAssignableFrom(c); + return UnderlyingType.IsAssignableFrom(c?.Unpack()); } /// - public bool IsSubclassOf(ITypeSymbol c) + public bool IsEnumDefined(object value) { - return _impl.IsSubclassOf(c); + return UnderlyingType.IsEnumDefined(value); } /// - public bool IsEnumDefined(object value) + public bool IsSubclassOf(ITypeSymbol c) { - return _impl.IsEnumDefined(value); + return UnderlyingType.IsSubclassOf(c.Unpack()); } /// public ITypeSymbol MakeArrayType() { - return _impl.MakeArrayType(); + return ResolveTypeSymbol(UnderlyingType.MakeArrayType()); } /// public ITypeSymbol MakeArrayType(int rank) { - return _impl.MakeArrayType(rank); + return ResolveTypeSymbol(UnderlyingType.MakeArrayType(rank)); } /// - public ITypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments) + public ITypeSymbol MakeByRefType() { - return _impl.MakeGenericType(typeArguments); + return ResolveTypeSymbol(UnderlyingType.MakeByRefType()); } /// public ITypeSymbol MakePointerType() { - return _impl.MakePointerType(); + return ResolveTypeSymbol(UnderlyingType.MakePointerType()); } /// - public ITypeSymbol MakeByRefType() + public ITypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments) { - return _impl.MakeByRefType(); + return ResolveTypeSymbol(UnderlyingType.MakeGenericType(typeArguments.Unpack())); } #endregion diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeTable.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeTable.cs new file mode 100644 index 000000000..37cb46aec --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeTable.cs @@ -0,0 +1,75 @@ +using System; +using System.Reflection.Emit; +using System.Reflection.Metadata.Ecma335; +using System.Threading; + +using IKVM.CoreLib.Collections; +using IKVM.CoreLib.Reflection; +using IKVM.CoreLib.Symbols.Reflection.Emit; +using IKVM.CoreLib.Threading; + +namespace IKVM.CoreLib.Symbols.Reflection +{ + + struct ReflectionTypeTable + { + + readonly ReflectionSymbolContext _context; + readonly IReflectionModuleSymbol _module; + readonly IReflectionTypeSymbol? _type; + + IndexRangeDictionary _table = new(); + ReaderWriterLockSlim? _lock; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + public ReflectionTypeTable(ReflectionSymbolContext context, IReflectionModuleSymbol module, IReflectionTypeSymbol? type) + { + _context = context ?? throw new ArgumentNullException(nameof(context)); + _module = module ?? throw new ArgumentNullException(nameof(module)); + _type = type; + } + + /// + /// Gets or creates the cached for the module by type. + /// + /// + /// + public IReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) + { + if (type is null) + throw new ArgumentNullException(nameof(type)); + if (type.Module.MetadataToken != _module.MetadataToken) + throw new ArgumentException(nameof(type)); + if (type.IsGenericParameter) + throw new ArgumentException(nameof(type)); + if (type.IsTypeDefinition() == false) + throw new ArgumentException(nameof(type)); + + // create lock on demand + if (_lock == null) + Interlocked.CompareExchange(ref _lock, new ReaderWriterLockSlim(), null); + + using (_lock.CreateUpgradeableReadLock()) + { + var row = type.GetMetadataTokenRowNumberSafe(); + if (_table[row] == null) + using (_lock.CreateWriteLock()) + if (_table[row] == null) + if (type is TypeBuilder builder) + return _table[row] = new ReflectionTypeSymbolBuilder(_context, (IReflectionModuleSymbolBuilder)_module, builder); + else + return _table[row] = new ReflectionTypeSymbol(_context, _module, type); + + return _table[row] ?? throw new InvalidOperationException(); + } + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionUtil.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionUtil.cs index 26c53e898..2a8426e22 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionUtil.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionUtil.cs @@ -51,10 +51,40 @@ public static AssemblyName Unpack(this AssemblyNameInfo n) Name = n.Name, Version = n.Version, CultureName = n.CultureName, - Flags = n.Flags, + Flags = (AssemblyNameFlags)n.Flags, }; } + /// + /// Converts a set of to a set of . + /// + /// + /// + public static AssemblyName[] Unpack(this AssemblyNameInfo[] n) + { + if (n.Length == 0) + return []; + + var a = new AssemblyName[n.Length]; + for (int i = 0; i < n.Length; i++) + a[i] = n[i].Unpack(); + + return a; + } + + /// + /// Unpacks the symbol into their original assembly. + /// + /// + /// + public static Assembly Unpack(this IAssemblySymbol type) + { + if (type is IReflectionAssemblySymbol symbol) + return symbol.UnderlyingAssembly; + + throw new InvalidOperationException(); + } + /// /// Unpacks the symbol into their original type. /// @@ -282,6 +312,35 @@ public static PropertyInfo[] Unpack(this IPropertySymbol[] properties) return a; } + /// + /// Unpacks the parameter modifier. + /// + /// + /// + /// + public static ParameterModifier Unpack(this System.Reflection.ParameterModifier modifier) + { + throw new NotSupportedException(); + } + + /// + /// Unpacks the parameter modifier. + /// + /// + /// + /// + public static ParameterModifier[] Unpack(this System.Reflection.ParameterModifier[] modifiers) + { + if (modifiers.Length == 0) + return []; + + var a = new ParameterModifier[modifiers.Length]; + for (int i = 0; i < modifiers.Length; i++) + a[i] = modifiers[i].Unpack(); + + return a; + } + /// /// Unpacks the . /// @@ -343,6 +402,36 @@ public static CustomAttributeBuilder[] Unpack(this ICustomAttributeBuilder[] cus return a; } + /// + /// Returns true if the given type represents a type definition. + /// + /// + /// + public static bool IsTypeDefinition(this Type type) + { + if (type is null) + throw new ArgumentNullException(nameof(type)); + +#if NET + return type.IsTypeDefinition; +#else + return type.HasElementType == false && type.IsConstructedGenericType == false && type.IsGenericParameter == false; +#endif + } + + /// + /// Returns true if the given method represents a method definition. + /// + /// + /// + public static bool IsMethodDefinition(this MethodBase method) + { + if (method is null) + throw new ArgumentNullException(nameof(method)); + + return method.IsGenericMethod == false || method.IsGenericMethodDefinition; + } + } } diff --git a/src/IKVM.Reflection/Emit/MethodBuilder.cs b/src/IKVM.Reflection/Emit/MethodBuilder.cs index f0757a90d..c8d40f75f 100644 --- a/src/IKVM.Reflection/Emit/MethodBuilder.cs +++ b/src/IKVM.Reflection/Emit/MethodBuilder.cs @@ -47,7 +47,7 @@ public sealed class MethodBuilder : MethodInfo // user configurable values Type returnType; - Type[] parameterTypes; + Type[] parameterTypes = Array.Empty(); PackedCustomModifiers customModifiers; MethodAttributes attributes; MethodImplAttributes implFlags; @@ -87,6 +87,7 @@ internal MethodBuilder(TypeBuilder typeBuilder, string name, MethodAttributes at if ((attributes & MethodAttributes.Static) == 0) callingConvention |= CallingConventions.HasThis; this.callingConvention = callingConvention; + this.returnType = Module.Universe.System_Void; } public ILGenerator GetILGenerator() diff --git a/src/IKVM.Runtime/RuntimeArrayJavaType.cs b/src/IKVM.Runtime/RuntimeArrayJavaType.cs index 4ee9687a9..96e6eeff3 100644 --- a/src/IKVM.Runtime/RuntimeArrayJavaType.cs +++ b/src/IKVM.Runtime/RuntimeArrayJavaType.cs @@ -119,7 +119,7 @@ internal override ITypeSymbol TypeAsTBD while (arrayType == null) { bool prevFinished = finished; - var type = ArrayRank == 1 ? ultimateElementTypeWrapper.TypeAsArrayType.MakeArrayType() : ultimateElementTypeWrapper.TypeAsArrayType.MakeArrayType(ArrayRank); + var type = MakeArrayType(ultimateElementTypeWrapper.TypeAsArrayType, this.ArrayRank); if (prevFinished) { // We were already finished prior to the call to MakeArrayType, so we can safely diff --git a/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs b/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs index d064ee8df..d14dc4fef 100644 --- a/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs +++ b/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs @@ -1173,7 +1173,7 @@ Type GetCustomClassLoaderType() } var attribs = assembly.GetCustomAttribute(Context.Resolver.ResolveRuntimeType(typeof(CustomAssemblyClassLoaderAttribute).FullName), false); - if (attribs is not null) + if (attribs.HasValue) return ((ITypeSymbol)attribs.Value.ConstructorArguments[0].Value).AsReflection(); return null; diff --git a/src/IKVM.Runtime/RuntimeJavaType.cs b/src/IKVM.Runtime/RuntimeJavaType.cs index 197ad18ce..f09830f6c 100644 --- a/src/IKVM.Runtime/RuntimeJavaType.cs +++ b/src/IKVM.Runtime/RuntimeJavaType.cs @@ -920,7 +920,7 @@ internal ITypeSymbol TypeAsSignatureType return ((RuntimeUnloadableJavaType)this).MissingType ?? context.Types.Object; if (IsGhostArray) - return ArrayRank == 1 ? context.Types.Object.MakeArrayType() : context.Types.Object.MakeArrayType(ArrayRank); + return RuntimeArrayJavaType.MakeArrayType(context.Types.Object, ArrayRank); return TypeAsTBD; } @@ -944,7 +944,7 @@ internal ITypeSymbol TypeAsLocalOrStackType } if (IsGhostArray) - return ArrayRank == 1 ? context.Types.Object.MakeArrayType() : context.Types.Object.MakeArrayType(ArrayRank); + return RuntimeArrayJavaType.MakeArrayType(context.Types.Object, ArrayRank); return TypeAsTBD; } @@ -959,7 +959,7 @@ internal ITypeSymbol TypeAsArrayType return context.Types.Object; if (IsGhostArray) - return ArrayRank == 1 ? context.Types.Object.MakeArrayType() : context.Types.Object.MakeArrayType(ArrayRank); + return RuntimeArrayJavaType.MakeArrayType(context.Types.Object, ArrayRank); return TypeAsTBD; } @@ -1311,8 +1311,8 @@ internal virtual void EmitCheckcast(CodeEmitter ilgen) } ilgen.EmitLdc_I4(rank); - ilgen.Emit(System.Reflection.Emit.OpCodes.Call, tw.TypeAsTBD.GetMethod("CastArray")); - ilgen.Emit(System.Reflection.Emit.OpCodes.Castclass, rank == 1 ? context.Types.Object.MakeArrayType() : context.Types.Object.MakeArrayType(rank)); + ilgen.Emit(OpCodes.Call, tw.TypeAsTBD.GetMethod("CastArray")); + ilgen.Emit(OpCodes.Castclass, RuntimeArrayJavaType.MakeArrayType(context.Types.Object, rank)); } else { diff --git a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs index b78906140..0b5a93a43 100644 --- a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs @@ -1255,7 +1255,7 @@ internal override ITypeSymbol EnumType internal override string GetSourceFileName() { var attr = type.GetCustomAttribute(Context.Resolver.GetSymbol(typeof(SourceFileAttribute))); - if (attr != null && attr.Value.ConstructorArguments.Length > 0) + if (attr.HasValue && attr.Value.ConstructorArguments.Length > 0) return (string)attr.Value.ConstructorArguments[0].Value; if (DeclaringTypeWrapper != null) @@ -1273,11 +1273,12 @@ internal override string GetSourceFileName() internal override int GetSourceLineNumber(IMethodBaseSymbol mb, int ilOffset) { var attr = type.GetCustomAttribute(Context.Resolver.GetSymbol(typeof(LineNumberTableAttribute))); - if (attr != null && attr.Value.Constructor != null) + if (attr.HasValue && attr.Value.Constructor != null) return ((LineNumberTableAttribute)attr.Value.Constructor.AsReflection().Invoke(attr.Value.ConstructorArguments.Cast().ToArray())).GetLineNumber(ilOffset); return -1; } + #endif internal override bool IsFastClassLiteralSafe diff --git a/src/IKVM.Runtime/StubGen/StubGenerator.cs b/src/IKVM.Runtime/StubGen/StubGenerator.cs index 2706d4c18..9b6aa0198 100644 --- a/src/IKVM.Runtime/StubGen/StubGenerator.cs +++ b/src/IKVM.Runtime/StubGen/StubGenerator.cs @@ -951,7 +951,7 @@ object[] GetAnnotation(CustomAttribute cad) string GetAnnotationInterface(CustomAttribute cad) { var attr = cad.Constructor.DeclaringType.GetCustomAttribute(context.Resolver.ResolveRuntimeType(typeof(ImplementsAttribute).FullName), false); - if (attr != null) + if (attr.HasValue) { var interfaces = (string[])attr.Value.ConstructorArguments[0].Value; if (interfaces.Length == 1) diff --git a/src/IKVM.Tools.Importer/ImportClassLoader.cs b/src/IKVM.Tools.Importer/ImportClassLoader.cs index f7894b03c..72ccbb4a8 100644 --- a/src/IKVM.Tools.Importer/ImportClassLoader.cs +++ b/src/IKVM.Tools.Importer/ImportClassLoader.cs @@ -599,8 +599,6 @@ void Save() mb.AddReference(referencedAssemblies[i].MainAssembly); } - mb.Complete(); - AddJavaModuleAttribute(mb); // add a package list and export map @@ -621,6 +619,9 @@ void Save() } } + // complete the module and all types + mb.Complete(); + if (targetIsModule) { Diagnostics.GenericCompilerInfo($"CompilerClassLoader saving {assemblyFile} in {assemblyDir}"); diff --git a/src/ikvmstub/Properties/launchSettings.json b/src/ikvmstub/Properties/launchSettings.json index 7b5a3610e..42c5223ee 100644 --- a/src/ikvmstub/Properties/launchSettings.json +++ b/src/ikvmstub/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "ikvmstub": { "commandName": "Project", - "commandLineArgs": "--bootstrap --nostdlib --parameters --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Numerics.Vectors.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Runtime.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Runtime.Intrinsics.dll\" --reference:\"D:\\ikvm\\src\\IKVM.Java-ref\\obj\\Debug\\net8.0\\ref\\IKVM.Java.dll\" --reference:\"D:\\ikvm\\src\\IKVM.Runtime-ref\\obj\\Debug\\net8.0\\ref\\IKVM.Runtime.dll\" --out:\"System.Runtime.Intrinsics.jar\" \"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Runtime.Intrinsics.dll\"" + "commandLineArgs": "--bootstrap --nostdlib --non-public-types --parameters --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\Microsoft.Win32.Primitives.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Collections.Concurrent.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Collections.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Collections.NonGeneric.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Diagnostics.StackTrace.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Diagnostics.Tracing.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.IO.Compression.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.IO.MemoryMappedFiles.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Linq.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Memory.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Net.Primitives.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Numerics.Vectors.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Reflection.Emit.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Reflection.Emit.ILGeneration.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Reflection.Emit.Lightweight.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Reflection.Primitives.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Resources.Writer.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Runtime.CompilerServices.Unsafe.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Runtime.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Runtime.InteropServices.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Runtime.Intrinsics.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Runtime.Loader.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Security.Cryptography.Algorithms.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Security.Cryptography.Encoding.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Security.Cryptography.Primitives.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Security.Cryptography.X509Certificates.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Text.Encoding.Extensions.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Threading.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Threading.Overlapped.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Threading.ThreadPool.dll\" --reference:\"D:\\ikvm\\src\\IKVM.CoreLib\\obj\\Debug\\net6.0\\ref\\IKVM.CoreLib.dll\" --reference:\"D:\\ikvm\\src\\IKVM.Java\\bin\\Debug\\net6.0\\IKVM.Java.dll\" --reference:\"D:\\ikvm\\src\\IKVM.Reflection\\obj\\Debug\\net6.0\\ref\\IKVM.Reflection.dll\" --reference:\"D:\\ikvm\\src\\IKVM.Runtime-ref\\obj\\Debug\\net6.0\\ref\\IKVM.Runtime.dll\" --reference:\"D:\\packages\\NuGet\\cache\\ikvm.bytecode\\9.1.3\\lib\\net6.0\\IKVM.ByteCode.dll\" --reference:\"D:\\packages\\NuGet\\cache\\system.collections.immutable\\8.0.0\\lib\\net6.0\\System.Collections.Immutable.dll\" --reference:\"D:\\packages\\NuGet\\cache\\system.io.pipelines\\8.0.0\\lib\\net6.0\\System.IO.Pipelines.dll\" --reference:\"D:\\packages\\NuGet\\cache\\system.reflection.metadata\\8.0.0\\lib\\net6.0\\System.Reflection.Metadata.dll\" --reference:\"D:\\packages\\NuGet\\cache\\system.text.encodings.web\\8.0.0\\lib\\net6.0\\System.Text.Encodings.Web.dll\" --reference:\"D:\\packages\\NuGet\\cache\\system.text.json\\8.0.4\\lib\\net6.0\\System.Text.Json.dll\" --out:\"IKVM.Runtime.jar\" \"D:\\ikvm\\src\\IKVM.Runtime-ref\\obj\\Debug\\net6.0\\ref\\IKVM.Runtime.dll\"" } } } \ No newline at end of file diff --git a/src/ikvmstub/ikvmstub.csproj b/src/ikvmstub/ikvmstub.csproj index e66f94dc4..f3f5a4191 100644 --- a/src/ikvmstub/ikvmstub.csproj +++ b/src/ikvmstub/ikvmstub.csproj @@ -1,7 +1,7 @@  Exe - net8.0;net6.0;net472; + net6.0;net8.0;net472; $(_SupportedToolRuntimes) true true From 0c0660dde401797e16d3bcd41460c953b74034b6 Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Wed, 2 Oct 2024 18:41:14 -0500 Subject: [PATCH 21/51] Almost..... --- ...ectionGenericTypeParameterSymbolBuilder.cs | 2 +- .../Emit/IkvmReflectionModuleSymbolBuilder.cs | 4 +- .../Emit/IkvmReflectionTypeSymbolBuilder.cs | 2 +- .../IIkvmReflectionTypeSymbol.cs | 2 +- .../IkvmReflectionEventTable.cs | 66 +++++++----- .../IkvmReflectionFieldTable.cs | 44 ++++++-- ...kvmReflectionGenericTypeParameterSymbol.cs | 2 +- ...IkvmReflectionGenericTypeParameterTable.cs | 4 +- .../IkvmReflectionMethodTable.cs | 7 +- .../IkvmReflectionModuleSymbol.cs | 4 +- .../IkvmReflectionModuleTable.cs | 8 +- .../IkvmReflectionParameterTable.cs | 2 +- .../IkvmReflectionPropertyTable.cs | 44 ++++++-- .../IkvmReflection/IkvmReflectionSymbol.cs | 3 +- .../IkvmReflectionTypeSpecTable.cs | 6 +- .../IkvmReflectionTypeSymbol.cs | 2 +- .../IkvmReflection/IkvmReflectionTypeTable.cs | 56 ++++++++-- .../ReflectionConstructorSymbolBuilder.cs | 11 ++ ...ectionGenericTypeParameterSymbolBuilder.cs | 2 +- .../Emit/ReflectionMethodBaseSymbolBuilder.cs | 4 +- .../Emit/ReflectionMethodSymbolBuilder.cs | 2 +- .../Emit/ReflectionModuleSymbolBuilder.cs | 8 +- .../Emit/ReflectionTypeSymbolBuilder.cs | 2 +- .../Reflection/IReflectionTypeSymbol.cs | 2 +- .../ReflectionGenericTypeParameterSymbol.cs | 2 +- .../Reflection/ReflectionMethodSpecTable.cs | 10 +- .../Reflection/ReflectionMethodSymbol.cs | 2 +- .../Reflection/ReflectionModuleSymbol.cs | 2 +- .../Reflection/ReflectionTypeSpecTable.cs | 4 +- .../Reflection/ReflectionTypeSymbol.cs | 2 +- src/IKVM.Reflection/Universe.cs | 6 +- src/IKVM.Runtime/AttributeHelper.cs | 31 ++++-- src/IKVM.Runtime/IRuntimeSymbolResolver.cs | 8 ++ src/IKVM.Runtime/JVM.Resolver.cs | 42 +++++--- .../RuntimeByteCodeJavaType.FinishContext.cs | 3 +- .../ExportRuntimeSymbolResolver.cs | 14 +++ .../ImportAssemblyResolver.cs | 100 ++++++------------ .../ImportDiagnosticHandler.cs | 10 +- .../ImportRuntimeSymbolResolver.cs | 55 ++++++++-- src/IKVM.Tools.Importer/ImportTool.cs | 4 +- src/ikvmc/Properties/launchSettings.json | 12 +-- src/ikvmc/ikvmc.csproj | 2 +- 42 files changed, 388 insertions(+), 210 deletions(-) diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionGenericTypeParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionGenericTypeParameterSymbolBuilder.cs index 5e318922e..3e455d9d8 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionGenericTypeParameterSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionGenericTypeParameterSymbolBuilder.cs @@ -153,7 +153,7 @@ public IIkvmReflectionTypeSymbol GetOrCreateByRefTypeSymbol() } /// - public IIkvmReflectionTypeSymbol GetOrCreateGenericTypeSymbol(Type[] genericTypeDefinition) + public IIkvmReflectionTypeSymbol GetOrCreateGenericTypeSymbol(IIkvmReflectionTypeSymbol[] genericTypeDefinition) { return _specTable.GetOrCreateGenericTypeSymbol(genericTypeDefinition); } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionModuleSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionModuleSymbolBuilder.cs index 339bb88c2..a1ee9f91d 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionModuleSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionModuleSymbolBuilder.cs @@ -38,7 +38,7 @@ public IkvmReflectionModuleSymbolBuilder(IkvmReflectionSymbolContext context, II _builder = builder ?? throw new ArgumentNullException(nameof(builder)); _module = _builder; - _typeTable = new IkvmReflectionTypeTable(context, this, null); + _typeTable = new IkvmReflectionTypeTable(context, this); _methodTable = new IkvmReflectionMethodTable(context, this, null); _fieldTable = new IkvmReflectionFieldTable(context, this, null); } @@ -60,7 +60,7 @@ public IIkvmReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) if (type.IsTypeDefinition()) return _typeTable.GetOrCreateTypeSymbol(type); else if (type.IsGenericType) - return ResolveTypeSymbol(type.GetGenericTypeDefinition()).GetOrCreateGenericTypeSymbol(type.GetGenericArguments()); + return ResolveTypeSymbol(type.GetGenericTypeDefinition()).GetOrCreateGenericTypeSymbol(ResolveTypeSymbols(type.GetGenericArguments())); else if (type.IsSZArray) return ResolveTypeSymbol(type.GetElementType()).GetOrCreateSZArrayTypeSymbol(); else if (type.IsArray) diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionTypeSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionTypeSymbolBuilder.cs index 3ec41457e..6c899d7fe 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionTypeSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionTypeSymbolBuilder.cs @@ -126,7 +126,7 @@ public IIkvmReflectionTypeSymbol GetOrCreateByRefTypeSymbol() } /// - public IIkvmReflectionTypeSymbol GetOrCreateGenericTypeSymbol(Type[] genericTypeDefinition) + public IIkvmReflectionTypeSymbol GetOrCreateGenericTypeSymbol(IIkvmReflectionTypeSymbol[] genericTypeDefinition) { return _specTable.GetOrCreateGenericTypeSymbol(genericTypeDefinition); } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionTypeSymbol.cs index b2dac0f00..9c3e762dc 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionTypeSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IIkvmReflectionTypeSymbol.cs @@ -92,7 +92,7 @@ interface IIkvmReflectionTypeSymbol : IIkvmReflectionMemberSymbol, ITypeSymbol /// /// /// - IIkvmReflectionTypeSymbol GetOrCreateGenericTypeSymbol(Type[] genericTypeDefinition); + IIkvmReflectionTypeSymbol GetOrCreateGenericTypeSymbol(IIkvmReflectionTypeSymbol[] genericTypeDefinition); } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionEventTable.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionEventTable.cs index c131d4927..1574b0f65 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionEventTable.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionEventTable.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Reflection.Metadata.Ecma335; using System.Threading; @@ -21,6 +22,8 @@ struct IkvmReflectionEventTable IndexRangeDictionary _table = new(); ReaderWriterLockSlim? _lock; + ConcurrentDictionary? _byToken; + /// /// Initializes a new instance. /// @@ -47,46 +50,61 @@ public IIkvmReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) if (@event.Module.MetadataToken != _module.MetadataToken) throw new ArgumentException(nameof(@event)); + var token = @event is EventBuilder b ? b.GetEventToken().Token : @event.MetadataToken; + if (token == 0) + throw new InvalidOperationException(); + + // pseudo tokens: since IKVM.Reflection does not remove pseudo tokens after creation, we can keep using these + // but they are non-sequential per-type, so we need to use a real dictionary + if (token < 0) + { + // we fall back to lookup by name if there is no valid metadata token + if (_byToken == null) + Interlocked.CompareExchange(ref _byToken, new(), null); + + var value = (_context, _module, _type, @event); + return _byToken.GetOrAdd(token, _ => CreateEventSymbol(value._context, value._module, value._type, value.@event)); + } + // create lock on demand if (_lock == null) - Interlocked.CompareExchange(ref _lock, new ReaderWriterLockSlim(), null); + Interlocked.CompareExchange(ref _lock, new(), null); using (_lock.CreateUpgradeableReadLock()) { - var row = MetadataTokens.GetRowNumber(MetadataTokens.EventDefinitionHandle(@event.MetadataToken)); + var row = MetadataTokens.GetRowNumber(MetadataTokens.EventDefinitionHandle(token)); if (_table[row] == null) using (_lock.CreateWriteLock()) - return _table[row] ??= new IkvmReflectionEventSymbol(_context, _module, _type, @event); - else - return _table[row] ?? throw new InvalidOperationException(); + _table[row] ??= CreateEventSymbol(_context, _module, _type, @event); + + return _table[row] ?? throw new InvalidOperationException(); } } /// - /// Gets or creates the cached for the type by event. + /// Creates a new symbol. /// + /// + /// + /// /// /// - public IIkvmReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event) + static IIkvmReflectionEventSymbol CreateEventSymbol(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol module, IIkvmReflectionTypeSymbol type, EventInfo @event) { - if (@event is null) - throw new ArgumentNullException(nameof(@event)); - if (@event.Module.MetadataToken != _module.MetadataToken) - throw new ArgumentException(nameof(@event)); - - // create lock on demand - if (_lock == null) - Interlocked.CompareExchange(ref _lock, new ReaderWriterLockSlim(), null); + if (@event is EventBuilder builder) + return new IkvmReflectionEventSymbolBuilder(context, (IIkvmReflectionModuleSymbolBuilder)module, (IIkvmReflectionTypeSymbolBuilder)type, builder); + else + return new IkvmReflectionEventSymbol(context, module, type, @event); + } - using (_lock.CreateUpgradeableReadLock()) - { - var row = MetadataTokens.GetRowNumber(MetadataTokens.EventDefinitionHandle(@event.GetEventToken().Token)); - if (_table[row] == null) - using (_lock.CreateWriteLock()) - return (IIkvmReflectionEventSymbolBuilder)(_table[row] ??= new IkvmReflectionEventSymbolBuilder(_context, (IIkvmReflectionModuleSymbolBuilder)_module, (IIkvmReflectionTypeSymbolBuilder)_type, @event)); - else - return (IIkvmReflectionEventSymbolBuilder?)_table[row] ?? throw new InvalidOperationException(); - } + /// + /// Gets or creates the cached for the type by property. + /// + /// + /// + public IIkvmReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder property) + { + return (IIkvmReflectionEventSymbolBuilder)GetOrCreateEventSymbol((EventInfo)property); } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionFieldTable.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionFieldTable.cs index 9158d9d19..d493f35fa 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionFieldTable.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionFieldTable.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Reflection.Metadata.Ecma335; using System.Threading; @@ -21,6 +22,8 @@ struct IkvmReflectionFieldTable IndexRangeDictionary _table = new(); ReaderWriterLockSlim? _lock; + ConcurrentDictionary? _byToken; + /// /// Initializes a new instance. /// @@ -47,24 +50,51 @@ public IIkvmReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) if (field.Module.MetadataToken != _module.MetadataToken) throw new ArgumentException(nameof(field)); + var token = field.MetadataToken; + if (token == 0) + throw new InvalidOperationException(); + + // pseudo tokens: since IKVM.Reflection does not remove pseudo tokens after creation, we can keep using these + // but they are non-sequential per-type, so we need to use a real dictionary + if (token < 0) + { + // we fall back to lookup by name if there is no valid metadata token + if (_byToken == null) + Interlocked.CompareExchange(ref _byToken, new(), null); + + var value = (_context, _module, _type, field); + return _byToken.GetOrAdd(token, _ => CreateFieldSymbol(value._context, value._module, value._type, value.field)); + } + // create lock on demand if (_lock == null) Interlocked.CompareExchange(ref _lock, new ReaderWriterLockSlim(), null); using (_lock.CreateUpgradeableReadLock()) { - var row = MetadataTokens.GetRowNumber(MetadataTokens.FieldDefinitionHandle(field.MetadataToken)); + var row = MetadataTokens.GetRowNumber(MetadataTokens.FieldDefinitionHandle(token)); if (_table[row] == null) using (_lock.CreateWriteLock()) - if (field is FieldBuilder builder) - return _table[row] ??= new IkvmReflectionFieldSymbolBuilder(_context, (IIkvmReflectionModuleSymbolBuilder)_module, (IIkvmReflectionTypeSymbolBuilder?)_type, builder); - else - return _table[row] ??= new IkvmReflectionFieldSymbol(_context, _module, _type, field); - else - return _table[row] ?? throw new InvalidOperationException(); + _table[row] ??= CreateFieldSymbol(_context, _module, _type, field); + + return _table[row] ?? throw new InvalidOperationException(); } } + /// + /// Creates a new symbol. + /// + /// + /// + /// + static IIkvmReflectionFieldSymbol CreateFieldSymbol(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol module, IIkvmReflectionTypeSymbol? type, FieldInfo field) + { + if (field is FieldBuilder builder) + return new IkvmReflectionFieldSymbolBuilder(context, (IIkvmReflectionModuleSymbolBuilder)module, (IIkvmReflectionTypeSymbolBuilder?)type, builder); + else + return new IkvmReflectionFieldSymbol(context, module, type, field); + } + /// /// Gets or creates the cached for the type by field. /// diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionGenericTypeParameterSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionGenericTypeParameterSymbol.cs index ec027dd93..1b92b0131 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionGenericTypeParameterSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionGenericTypeParameterSymbol.cs @@ -126,7 +126,7 @@ public IIkvmReflectionTypeSymbol GetOrCreateByRefTypeSymbol() } /// - public IIkvmReflectionTypeSymbol GetOrCreateGenericTypeSymbol(Type[] genericTypeDefinition) + public IIkvmReflectionTypeSymbol GetOrCreateGenericTypeSymbol(IIkvmReflectionTypeSymbol[] genericTypeDefinition) { return _specTable.GetOrCreateGenericTypeSymbol(genericTypeDefinition); } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionGenericTypeParameterTable.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionGenericTypeParameterTable.cs index 9bff410a3..78633cd9f 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionGenericTypeParameterTable.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionGenericTypeParameterTable.cs @@ -57,9 +57,9 @@ public IIkvmReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type gene if (_table[pos] == null) using (_lock.CreateWriteLock()) if (genericTypeParameter is GenericTypeParameterBuilder builder) - return _table[pos] ??= new IkvmReflectionGenericTypeParameterSymbolBuilder(_context, (IIkvmReflectionModuleSymbolBuilder)_module, (IIkvmReflectionMemberSymbolBuilder)_member, builder); + _table[pos] ??= new IkvmReflectionGenericTypeParameterSymbolBuilder(_context, (IIkvmReflectionModuleSymbolBuilder)_module, (IIkvmReflectionMemberSymbolBuilder)_member, builder); else - return _table[pos] ??= new IkvmReflectionGenericTypeParameterSymbol(_context, _module, _member, genericTypeParameter); + _table[pos] ??= new IkvmReflectionGenericTypeParameterSymbol(_context, _module, _member, genericTypeParameter); return _table[pos] ?? throw new InvalidOperationException(); } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodTable.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodTable.cs index ec6a02017..bab5adf60 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodTable.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodTable.cs @@ -75,11 +75,12 @@ public IIkvmReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase me using (_lock.CreateUpgradeableReadLock()) { - if (_table[token] == null) + var row = MetadataTokens.GetRowNumber(MetadataTokens.MethodDefinitionHandle(token)); + if (_table[row] == null) using (_lock.CreateWriteLock()) - return _table[token] ??= CreateMethodBaseSymbol(_context, _module, _type, method); + _table[row] ??= CreateMethodBaseSymbol(_context, _module, _type, method); - return _table[token] ?? throw new InvalidOperationException(); + return _table[row] ?? throw new InvalidOperationException(); } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs index 806f0cb7c..7c6fddcae 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs @@ -34,7 +34,7 @@ public IkvmReflectionModuleSymbol(IkvmReflectionSymbolContext context, IIkvmRefl _resolvingAssembly = resolvingAssembly ?? throw new ArgumentNullException(nameof(resolvingAssembly)); _module = module ?? throw new ArgumentNullException(nameof(module)); - _typeTable = new IkvmReflectionTypeTable(context, this, null); + _typeTable = new IkvmReflectionTypeTable(context, this); _methodTable = new IkvmReflectionMethodTable(context, this, null); _fieldTable = new IkvmReflectionFieldTable(context, this, null); } @@ -251,7 +251,7 @@ public IIkvmReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) if (type.IsTypeDefinition()) return _typeTable.GetOrCreateTypeSymbol(type); else if (type.IsGenericType) - return ResolveTypeSymbol(type.GetGenericTypeDefinition()).GetOrCreateGenericTypeSymbol(type.GetGenericArguments()); + return ResolveTypeSymbol(type.GetGenericTypeDefinition()).GetOrCreateGenericTypeSymbol(ResolveTypeSymbols(type.GetGenericArguments())); else if (type.IsSZArray) return ResolveTypeSymbol(type.GetElementType()).GetOrCreateSZArrayTypeSymbol(); else if (type.IsArray) diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleTable.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleTable.cs index bb0407174..393695e15 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleTable.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleTable.cs @@ -51,11 +51,11 @@ public IIkvmReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) if (_moduleSymbols[row] == null) using (_moduleLock.CreateWriteLock()) if (module is ModuleBuilder builder) - return _moduleSymbols[row] = new IkvmReflectionModuleSymbolBuilder(_context, _assembly, builder); + _moduleSymbols[row] = new IkvmReflectionModuleSymbolBuilder(_context, _assembly, builder); else - return _moduleSymbols[row] = new IkvmReflectionModuleSymbol(_context, _assembly, module); - else - return _moduleSymbols[row] ?? throw new InvalidOperationException(); + _moduleSymbols[row] = new IkvmReflectionModuleSymbol(_context, _assembly, module); + + return _moduleSymbols[row] ?? throw new InvalidOperationException(); } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterTable.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterTable.cs index 9f4452ec4..87094d0df 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterTable.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterTable.cs @@ -60,7 +60,7 @@ public IIkvmReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo p if (_table[position] == null) using (_lock.CreateWriteLock()) - return _table[position] ??= new IkvmReflectionParameterSymbol(_context, _module, _member, parameter); + _table[position] ??= new IkvmReflectionParameterSymbol(_context, _module, _member, parameter); return _table[position] ?? throw new InvalidOperationException(); } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionPropertyTable.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionPropertyTable.cs index 6718e0898..6e2c77442 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionPropertyTable.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionPropertyTable.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Reflection.Metadata.Ecma335; using System.Threading; @@ -21,6 +22,8 @@ struct IkvmReflectionPropertyTable IndexRangeDictionary _table = new(); ReaderWriterLockSlim? _lock; + ConcurrentDictionary? _byToken; + /// /// Initializes a new instance. /// @@ -47,24 +50,51 @@ public IIkvmReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo prop if (property.Module.MetadataToken != _module.MetadataToken) throw new ArgumentException(nameof(property)); + var token = property.MetadataToken; + if (token == 0) + throw new InvalidOperationException(); + + // pseudo tokens: since IKVM.Reflection does not remove pseudo tokens after creation, we can keep using these + // but they are non-sequential per-type, so we need to use a real dictionary + if (token < 0) + { + // we fall back to lookup by name if there is no valid metadata token + if (_byToken == null) + Interlocked.CompareExchange(ref _byToken, new(), null); + + var value = (_context, _module, _type, property); + return _byToken.GetOrAdd(token, _ => CreatePropertySymbol(value._context, value._module, value._type, value.property)); + } + // create lock on demand if (_lock == null) Interlocked.CompareExchange(ref _lock, new ReaderWriterLockSlim(), null); using (_lock.CreateUpgradeableReadLock()) { - var row = MetadataTokens.GetRowNumber(MetadataTokens.PropertyDefinitionHandle(property.MetadataToken)); + var row = MetadataTokens.GetRowNumber(MetadataTokens.PropertyDefinitionHandle(token)); if (_table[row] == null) using (_lock.CreateWriteLock()) - if (property is PropertyBuilder builder) - return _table[row] ??= new IkvmReflectionPropertySymbolBuilder(_context, (IIkvmReflectionModuleSymbolBuilder)_module, (IIkvmReflectionTypeSymbolBuilder)_type, builder); - else - return _table[row] ??= new IkvmReflectionPropertySymbol(_context, _module, _type, property); - else - return _table[row] ?? throw new InvalidOperationException(); + _table[row] ??= CreatePropertySymbol(_context, _module, _type, property); + + return _table[row] ?? throw new InvalidOperationException(); } } + /// + /// Creates a new symbol. + /// + /// + /// + /// + static IIkvmReflectionPropertySymbol CreatePropertySymbol(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol module, IIkvmReflectionTypeSymbol type, PropertyInfo property) + { + if (property is PropertyBuilder builder) + return new IkvmReflectionPropertySymbolBuilder(context, (IIkvmReflectionModuleSymbolBuilder)module, (IIkvmReflectionTypeSymbolBuilder)type, builder); + else + return new IkvmReflectionPropertySymbol(context, module, type, property); + } + /// /// Gets or creates the cached for the type by property. /// diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs index fb4f446f2..4d7ca6c37 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs @@ -446,8 +446,7 @@ public virtual IIkvmReflectionPropertySymbolBuilder ResolvePropertySymbol(Proper var a = new CustomAttribute[attributes.Count]; for (int i = 0; i < attributes.Count; i++) - if (ResolveCustomAttribute(attributes[i]) is { } v) - a[i] = v; + a[i] = ResolveCustomAttribute(attributes[i]) ?? throw new InvalidOperationException(); return a; } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSpecTable.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSpecTable.cs index f52e96eb4..2f69be22f 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSpecTable.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSpecTable.cs @@ -5,8 +5,6 @@ using IKVM.CoreLib.Collections; using IKVM.CoreLib.Threading; -using Type = IKVM.Reflection.Type; - namespace IKVM.CoreLib.Symbols.IkvmReflection { @@ -101,7 +99,7 @@ public IIkvmReflectionTypeSymbol GetOrCreateByRefTypeSymbol() /// /// /// - public IIkvmReflectionTypeSymbol GetOrCreateGenericTypeSymbol(Type[] genericTypeArguments) + public IIkvmReflectionTypeSymbol GetOrCreateGenericTypeSymbol(IIkvmReflectionTypeSymbol[] genericTypeArguments) { if (genericTypeArguments is null) throw new ArgumentNullException(nameof(genericTypeArguments)); @@ -112,7 +110,7 @@ public IIkvmReflectionTypeSymbol GetOrCreateGenericTypeSymbol(Type[] genericType if (_genericTypeSymbols == null) Interlocked.CompareExchange(ref _genericTypeSymbols, new(TypeSymbolListEqualityComparer.Instance), null); - return _genericTypeSymbols.GetOrAdd(_module.ResolveTypeSymbols(genericTypeArguments), CreateGenericTypeSymbol); + return _genericTypeSymbols.GetOrAdd(genericTypeArguments, CreateGenericTypeSymbol); } /// diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs index 7a984642f..f9ab22f98 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs @@ -119,7 +119,7 @@ public IIkvmReflectionTypeSymbol GetOrCreateByRefTypeSymbol() } /// - public IIkvmReflectionTypeSymbol GetOrCreateGenericTypeSymbol(Type[] genericTypeDefinition) + public IIkvmReflectionTypeSymbol GetOrCreateGenericTypeSymbol(IIkvmReflectionTypeSymbol[] genericTypeDefinition) { return _specTable.GetOrCreateGenericTypeSymbol(genericTypeDefinition); } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeTable.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeTable.cs index d089438c7..706ffe012 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeTable.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeTable.cs @@ -1,10 +1,12 @@ using System; +using System.Collections.Concurrent; using System.Reflection.Metadata.Ecma335; using System.Threading; using IKVM.CoreLib.Collections; using IKVM.CoreLib.Symbols.IkvmReflection.Emit; using IKVM.CoreLib.Threading; +using IKVM.Reflection; using IKVM.Reflection.Emit; using Type = IKVM.Reflection.Type; @@ -17,23 +19,23 @@ struct IkvmReflectionTypeTable readonly IkvmReflectionSymbolContext _context; readonly IIkvmReflectionModuleSymbol _module; - readonly IIkvmReflectionTypeSymbol? _type; IndexRangeDictionary _table = new(); ReaderWriterLockSlim? _lock; + ConcurrentDictionary _byName; + ConcurrentDictionary? _byToken; + /// /// Initializes a new instance. /// /// /// - /// /// - public IkvmReflectionTypeTable(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol module, IIkvmReflectionTypeSymbol? type) + public IkvmReflectionTypeTable(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol module) { _context = context ?? throw new ArgumentNullException(nameof(context)); _module = module ?? throw new ArgumentNullException(nameof(module)); - _type = type; } /// @@ -52,6 +54,32 @@ public IIkvmReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) if (type.IsTypeDefinition() == false) throw new ArgumentException(nameof(type)); + // IKVM.Reflection may deliver a missing type, without a token, so we are forced to index this by name + if (type.__IsMissing) + { + if (_byName == null) + Interlocked.CompareExchange(ref _byName, new(), null); + + var value = (_context, _module, type); + return _byName.GetOrAdd(type.FullName, _ => CreateTypeSymbol(value._context, value._module, value.type)); + } + + var token = type.MetadataToken; + if (token == 0) + throw new InvalidOperationException(); + + // pseudo tokens: since IKVM.Reflection does not remove pseudo tokens after creation, we can keep using these + // but they are non-sequential per-type, so we need to use a real dictionary + if (token < 0) + { + // we fall back to lookup by name if there is no valid metadata token + if (_byToken == null) + Interlocked.CompareExchange(ref _byToken, new(), null); + + var value = (_context, _module, type); + return _byToken.GetOrAdd(token, _ => CreateTypeSymbol(value._context, value._module, value.type)); + } + // create lock on demand if (_lock == null) Interlocked.CompareExchange(ref _lock, new ReaderWriterLockSlim(), null); @@ -61,16 +89,26 @@ public IIkvmReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) var row = MetadataTokens.GetRowNumber(MetadataTokens.TypeDefinitionHandle(type.MetadataToken)); if (_table[row] == null) using (_lock.CreateWriteLock()) - if (_table[row] == null) - if (type is TypeBuilder builder) - return _table[row] = new IkvmReflectionTypeSymbolBuilder(_context, (IIkvmReflectionModuleSymbolBuilder)_module, builder); - else - return _table[row] = new IkvmReflectionTypeSymbol(_context, _module, type); + _table[row] ??= CreateTypeSymbol(_context, _module, type); return _table[row] ?? throw new InvalidOperationException(); } } + /// + /// Creates a new symbol. + /// + /// + /// + /// + static IIkvmReflectionTypeSymbol CreateTypeSymbol(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol module, Type type) + { + if (type is TypeBuilder builder) + return new IkvmReflectionTypeSymbolBuilder(context, (IIkvmReflectionModuleSymbolBuilder)module, builder); + else + return new IkvmReflectionTypeSymbol(context, module, type); + } + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionConstructorSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionConstructorSymbolBuilder.cs index ba6d7c8b8..414a329ef 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionConstructorSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionConstructorSymbolBuilder.cs @@ -89,6 +89,17 @@ public override void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAtt #endregion + #region IMethodBaseSymbol + + /// + public override ITypeSymbol[] GetGenericArguments() + { + // constructor never has generic arguments + return []; + } + + #endregion + /// public override void OnComplete() { diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionGenericTypeParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionGenericTypeParameterSymbolBuilder.cs index 17651ec77..6bced14f4 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionGenericTypeParameterSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionGenericTypeParameterSymbolBuilder.cs @@ -152,7 +152,7 @@ public IReflectionTypeSymbol GetOrCreateByRefTypeSymbol() } /// - public IReflectionTypeSymbol GetOrCreateGenericTypeSymbol(Type[] genericTypeDefinition) + public IReflectionTypeSymbol GetOrCreateGenericTypeSymbol(IReflectionTypeSymbol[] genericTypeDefinition) { return _specTable.GetOrCreateGenericTypeSymbol(genericTypeDefinition); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodBaseSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodBaseSymbolBuilder.cs index 03cd589a4..ac5e72337 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodBaseSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodBaseSymbolBuilder.cs @@ -124,10 +124,10 @@ public IReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBui public bool IsSpecialName => UnderlyingMethodBase.IsSpecialName; /// - public System.Reflection.MethodImplAttributes MethodImplementationFlags => (System.Reflection.MethodImplAttributes)UnderlyingMethodBase.MethodImplementationFlags; + public MethodImplAttributes MethodImplementationFlags => UnderlyingMethodBase.MethodImplementationFlags; /// - public ITypeSymbol[] GetGenericArguments() + public virtual ITypeSymbol[] GetGenericArguments() { return ResolveTypeSymbols(UnderlyingMethodBase.GetGenericArguments()); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs index 43ab72c52..dc5b528dd 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs @@ -65,7 +65,7 @@ public IReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type genericT /// public IReflectionMethodSymbol GetOrCreateGenericMethodSymbol(MethodInfo method) { - return _specTable.GetOrCreateGenericMethodSymbol(method.GetGenericArguments()); + return _specTable.GetOrCreateGenericMethodSymbol(ResolveTypeSymbols(method.GetGenericArguments())); } #endregion diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionModuleSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionModuleSymbolBuilder.cs index b671cc5e6..9882c333a 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionModuleSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionModuleSymbolBuilder.cs @@ -59,7 +59,7 @@ public IReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) if (type.IsTypeDefinition()) return _typeTable.GetOrCreateTypeSymbol(type); else if (type.IsGenericType) - return ResolveTypeSymbol(type.GetGenericTypeDefinition()).GetOrCreateGenericTypeSymbol(type.GetGenericArguments()); + return ResolveTypeSymbol(type.GetGenericTypeDefinition()).GetOrCreateGenericTypeSymbol(ResolveTypeSymbols(type.GetGenericArguments())); else if (type.IsSZArray()) return ResolveTypeSymbol(type.GetElementType()!).GetOrCreateSZArrayTypeSymbol(); else if (type.IsArray) @@ -212,7 +212,7 @@ public IReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeParame public void DefineManifestResource(string name, Stream stream, System.Reflection.ResourceAttributes attribute) { #if NETFRAMEWORK - UnderlyingModuleBuilder.DefineManifestResource(name, stream, attribute); + UnderlyingModuleBuilder.DefineManifestResource(name, stream, attribute); #else throw new NotSupportedException(); #endif @@ -222,7 +222,7 @@ public void DefineManifestResource(string name, Stream stream, System.Reflection public IResourceWriter DefineResource(string name, string description) { #if NETFRAMEWORK - return UnderlyingModuleBuilder.DefineResource(name, description); + return UnderlyingModuleBuilder.DefineResource(name, description); #else throw new NotImplementedException(); #endif @@ -232,7 +232,7 @@ public IResourceWriter DefineResource(string name, string description) public IResourceWriter DefineResource(string name, string description, System.Reflection.ResourceAttributes attribute) { #if NETFRAMEWORK - return UnderlyingModuleBuilder.DefineResource(name, description, attribute); + return UnderlyingModuleBuilder.DefineResource(name, description, attribute); #else throw new NotImplementedException(); #endif diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs index 92a173aad..176f7d60c 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs @@ -125,7 +125,7 @@ public IReflectionTypeSymbol GetOrCreateByRefTypeSymbol() } /// - public IReflectionTypeSymbol GetOrCreateGenericTypeSymbol(Type[] genericTypeDefinition) + public IReflectionTypeSymbol GetOrCreateGenericTypeSymbol(IReflectionTypeSymbol[] genericTypeDefinition) { return _specTable.GetOrCreateGenericTypeSymbol(genericTypeDefinition); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionTypeSymbol.cs index 464cc4a3d..edc48697a 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionTypeSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionTypeSymbol.cs @@ -91,7 +91,7 @@ interface IReflectionTypeSymbol : IReflectionMemberSymbol, ITypeSymbol /// /// /// - IReflectionTypeSymbol GetOrCreateGenericTypeSymbol(Type[] genericTypeDefinition); + IReflectionTypeSymbol GetOrCreateGenericTypeSymbol(IReflectionTypeSymbol[] genericTypeDefinition); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericTypeParameterSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericTypeParameterSymbol.cs index 3fdc602d8..853b5e4f9 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericTypeParameterSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericTypeParameterSymbol.cs @@ -125,7 +125,7 @@ public IReflectionTypeSymbol GetOrCreateByRefTypeSymbol() } /// - public IReflectionTypeSymbol GetOrCreateGenericTypeSymbol(Type[] genericTypeDefinition) + public IReflectionTypeSymbol GetOrCreateGenericTypeSymbol(IReflectionTypeSymbol[] genericTypeDefinition) { return _specTable.GetOrCreateGenericTypeSymbol(genericTypeDefinition); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSpecTable.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSpecTable.cs index a01078ab0..63c4da0ec 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSpecTable.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSpecTable.cs @@ -13,7 +13,7 @@ struct ReflectionMethodSpecTable readonly IReflectionTypeSymbol? _type; readonly IReflectionMethodSymbol _method; - ConcurrentDictionary? _genericMethodSymbols; + ConcurrentDictionary? _genericMethodSymbols; /// /// Initializes a new instance. @@ -36,7 +36,7 @@ public ReflectionMethodSpecTable(ReflectionSymbolContext context, IReflectionMod /// /// /// - public IReflectionMethodSymbol GetOrCreateGenericMethodSymbol(Type[] genericTypeArguments) + public IReflectionMethodSymbol GetOrCreateGenericMethodSymbol(IReflectionTypeSymbol[] genericTypeArguments) { if (genericTypeArguments is null) throw new ArgumentNullException(nameof(genericTypeArguments)); @@ -45,7 +45,7 @@ public IReflectionMethodSymbol GetOrCreateGenericMethodSymbol(Type[] genericType throw new InvalidOperationException(); if (_genericMethodSymbols == null) - Interlocked.CompareExchange(ref _genericMethodSymbols, new(TypeListEqualityComparer.Instance), null); + Interlocked.CompareExchange(ref _genericMethodSymbols, new(TypeSymbolListEqualityComparer.Instance), null); return _genericMethodSymbols.GetOrAdd(genericTypeArguments, CreateGenericMethodSymbol); } @@ -55,9 +55,9 @@ public IReflectionMethodSymbol GetOrCreateGenericMethodSymbol(Type[] genericType /// /// /// - readonly IReflectionMethodSymbol CreateGenericMethodSymbol(Type[] genericTypeArguments) + readonly IReflectionMethodSymbol CreateGenericMethodSymbol(IReflectionTypeSymbol[] genericTypeArguments) { - return new ReflectionMethodSymbol(_context, _module, _type, _method.UnderlyingMethod.MakeGenericMethod(genericTypeArguments)); + return new ReflectionMethodSymbol(_context, _module, _type, _method.UnderlyingMethod.MakeGenericMethod(genericTypeArguments.Unpack())); } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs index 0b5004856..ada2a5653 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs @@ -44,7 +44,7 @@ public IReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type genericT /// public IReflectionMethodSymbol GetOrCreateGenericMethodSymbol(MethodInfo method) { - return _specTable.GetOrCreateGenericMethodSymbol(method.GetGenericArguments()); + return _specTable.GetOrCreateGenericMethodSymbol(ResolveTypeSymbols(method.GetGenericArguments())); } #endregion diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs index c596f370e..9bb62cf7c 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs @@ -244,7 +244,7 @@ public IReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) if (type.IsTypeDefinition()) return _typeTable.GetOrCreateTypeSymbol(type); else if (type.IsGenericType) - return ResolveTypeSymbol(type.GetGenericTypeDefinition()).GetOrCreateGenericTypeSymbol(type.GetGenericArguments()); + return ResolveTypeSymbol(type.GetGenericTypeDefinition()).GetOrCreateGenericTypeSymbol(ResolveTypeSymbols(type.GetGenericArguments())); else if (type.IsSZArray()) return ResolveTypeSymbol(type.GetElementType()!).GetOrCreateSZArrayTypeSymbol(); else if (type.IsArray) diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSpecTable.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSpecTable.cs index 0f98f8180..b83bdff39 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSpecTable.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSpecTable.cs @@ -99,7 +99,7 @@ public IReflectionTypeSymbol GetOrCreateByRefTypeSymbol() /// /// /// - public IReflectionTypeSymbol GetOrCreateGenericTypeSymbol(Type[] genericTypeArguments) + public IReflectionTypeSymbol GetOrCreateGenericTypeSymbol(IReflectionTypeSymbol[] genericTypeArguments) { if (genericTypeArguments is null) throw new ArgumentNullException(nameof(genericTypeArguments)); @@ -110,7 +110,7 @@ public IReflectionTypeSymbol GetOrCreateGenericTypeSymbol(Type[] genericTypeArgu if (_genericTypeSymbols == null) Interlocked.CompareExchange(ref _genericTypeSymbols, new(TypeSymbolListEqualityComparer.Instance), null); - return _genericTypeSymbols.GetOrAdd(_module.ResolveTypeSymbols(genericTypeArguments), CreateGenericTypeSymbol); + return _genericTypeSymbols.GetOrAdd(genericTypeArguments, CreateGenericTypeSymbol); } /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbol.cs index 6e33a9867..1880246ba 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbol.cs @@ -118,7 +118,7 @@ public IReflectionTypeSymbol GetOrCreateByRefTypeSymbol() } /// - public IReflectionTypeSymbol GetOrCreateGenericTypeSymbol(Type[] genericTypeDefinition) + public IReflectionTypeSymbol GetOrCreateGenericTypeSymbol(IReflectionTypeSymbol[] genericTypeDefinition) { return _specTable.GetOrCreateGenericTypeSymbol(genericTypeDefinition); } diff --git a/src/IKVM.Reflection/Universe.cs b/src/IKVM.Reflection/Universe.cs index 2c71d0993..bddb9da49 100644 --- a/src/IKVM.Reflection/Universe.cs +++ b/src/IKVM.Reflection/Universe.cs @@ -584,10 +584,10 @@ internal Assembly Load(string refname, Module requestingModule, bool throwOnErro if (asm != null) { + // cache assembly by both the lookup name and the resolved name var defname = asm.FullName; - if (refname != defname) - assembliesByName.Add(refname, asm); - + assembliesByName[refname] = asm; + assembliesByName[defname] = asm; return asm; } diff --git a/src/IKVM.Runtime/AttributeHelper.cs b/src/IKVM.Runtime/AttributeHelper.cs index ebdec4ceb..46f8e86aa 100644 --- a/src/IKVM.Runtime/AttributeHelper.cs +++ b/src/IKVM.Runtime/AttributeHelper.cs @@ -38,10 +38,6 @@ Jeroen Frijters using IKVM.CoreLib.Symbols.Emit; using IKVM.CoreLib.Symbols.Reflection; -#if IMPORTER -using IKVM.Tools.Importer; -#endif - namespace IKVM.Runtime { @@ -1048,18 +1044,33 @@ internal bool IsJavaModule(IModuleSymbol mod) internal object[] GetJavaModuleAttributes(IModuleSymbol mod) { - var attrs = new List(); + var l = mod.GetCustomAttributes(TypeOfJavaModuleAttribute); + var a = new object[l.Length]; - foreach (var cad in mod.GetCustomAttributes(TypeOfJavaModuleAttribute)) + for (int i = 0; i < l.Length; i++) { - var args = cad.ConstructorArguments; + JavaModuleAttribute attr; + + var args = l[i].ConstructorArguments; if (args.Length == 0) - attrs.Add(new JavaModuleAttribute()); + attr = new JavaModuleAttribute(); else - attrs.Add(new JavaModuleAttribute(DecodeArray(args[0]))); + attr = new JavaModuleAttribute(DecodeArray(args[0])); + + foreach (var arg in l[i].NamedArguments) + { + switch (arg.MemberName) + { + case nameof(JavaModuleAttribute.Jars): + attr.Jars = DecodeArray(arg.TypedValue); + break; + } + } + + a[i] = attr; } - return attrs.ToArray(); + return a; } internal bool IsNoPackagePrefix(ITypeSymbol type) diff --git a/src/IKVM.Runtime/IRuntimeSymbolResolver.cs b/src/IKVM.Runtime/IRuntimeSymbolResolver.cs index 3d89c7c9a..335c60117 100644 --- a/src/IKVM.Runtime/IRuntimeSymbolResolver.cs +++ b/src/IKVM.Runtime/IRuntimeSymbolResolver.cs @@ -49,6 +49,14 @@ interface IRuntimeSymbolResolver : ISymbolResolver /// ITypeSymbol ResolveRuntimeType(string typeName); + /// + /// Attempts to resolve the named type from the IKVM runtime assembly. + /// + /// + /// + /// + bool TryResolveRuntimeType(string typeName, out ITypeSymbol? type); + /// /// Resolves the known Java base assembly. /// diff --git a/src/IKVM.Runtime/JVM.Resolver.cs b/src/IKVM.Runtime/JVM.Resolver.cs index 83d23d67b..d1603aa51 100644 --- a/src/IKVM.Runtime/JVM.Resolver.cs +++ b/src/IKVM.Runtime/JVM.Resolver.cs @@ -1,4 +1,6 @@ -using System; +#nullable enable + +using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.ComponentModel; @@ -44,16 +46,16 @@ static IEnumerable GetSystemAssemblies() readonly ReflectionSymbolContext _symbols = new(); IAssemblySymbol _coreAssembly; - readonly ConcurrentDictionary _coreTypeCache = new(); + readonly ConcurrentDictionary _coreTypeCache = new(); IAssemblySymbol[] _systemAssemblies; - readonly ConcurrentDictionary _systemTypeCache = new(); + readonly ConcurrentDictionary _systemTypeCache = new(); IAssemblySymbol _runtimeAssembly; - readonly ConcurrentDictionary _runtimeTypeCache = new(); + readonly ConcurrentDictionary _runtimeTypeCache = new(); IAssemblySymbol _baseAssembly; - readonly ConcurrentDictionary _baseTypeCache = new(); + readonly ConcurrentDictionary _baseTypeCache = new(); /// /// Initializes a new instance. @@ -84,7 +86,7 @@ public IAssemblySymbol GetCoreAssembly() /// public ITypeSymbol ResolveCoreType(string typeName) { - return _coreTypeCache.GetOrAdd(typeName, ResolveCoreTypeImpl); + return _coreTypeCache.GetOrAdd(typeName, ResolveCoreTypeImpl) ?? throw new InvalidOperationException(); } /// @@ -92,7 +94,7 @@ public ITypeSymbol ResolveCoreType(string typeName) /// /// /// - ITypeSymbol ResolveCoreTypeImpl(string typeName) + ITypeSymbol? ResolveCoreTypeImpl(string typeName) { return _coreAssembly.GetType(typeName); } @@ -100,7 +102,7 @@ ITypeSymbol ResolveCoreTypeImpl(string typeName) /// public ITypeSymbol ResolveSystemType(string typeName) { - return _systemTypeCache.GetOrAdd(typeName, ResolveSystemTypeImpl); + return _systemTypeCache.GetOrAdd(typeName, FindSystemType) ?? throw new InvalidOperationException(); } /// @@ -108,7 +110,7 @@ public ITypeSymbol ResolveSystemType(string typeName) /// /// /// - ITypeSymbol ResolveSystemTypeImpl(string typeName) + ITypeSymbol? FindSystemType(string typeName) { foreach (var assembly in _systemAssemblies) if (assembly.GetType(typeName) is ITypeSymbol t) @@ -126,7 +128,21 @@ public IAssemblySymbol GetRuntimeAssembly() /// public ITypeSymbol ResolveRuntimeType(string typeName) { - return _runtimeTypeCache.GetOrAdd(typeName, ResolveRuntimeTypeImpl); + return _runtimeTypeCache.GetOrAdd(typeName, FindRuntimeType) ?? throw new InvalidOperationException(); + } + + /// + public bool TryResolveRuntimeType(string typeName, out ITypeSymbol? type) + { + var t = _runtimeTypeCache.GetOrAdd(typeName, FindRuntimeType); + if (t != null) + { + type = t; + return true; + } + + type = null; + return false; } /// @@ -134,7 +150,7 @@ public ITypeSymbol ResolveRuntimeType(string typeName) /// /// /// - ITypeSymbol ResolveRuntimeTypeImpl(string typeName) + ITypeSymbol? FindRuntimeType(string typeName) { return _runtimeAssembly.GetType(typeName); } @@ -148,11 +164,11 @@ public IAssemblySymbol GetBaseAssembly() /// public ITypeSymbol ResolveBaseType(string typeName) { - return _baseAssembly.GetType(typeName); + return _baseAssembly.GetType(typeName) ?? throw new InvalidOperationException(); } /// - public ITypeSymbol ResolveType(string typeName) + public ITypeSymbol? ResolveType(string typeName) { foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) if (assembly.GetType(typeName) is Type t) diff --git a/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishContext.cs b/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishContext.cs index a300dae6e..06f473f1f 100644 --- a/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishContext.cs +++ b/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishContext.cs @@ -388,8 +388,7 @@ internal ITypeSymbol FinishImpl() #if IMPORTER // see if there exists a "managed JNI" class for this type - var nativeCodeType = context.Resolver.ResolveRuntimeType("IKVM.Java.Externs." + classFile.Name.Replace("$", "+")); - if (nativeCodeType != null) + if (context.Resolver.TryResolveRuntimeType("IKVM.Java.Externs." + classFile.Name.Replace("$", "+"), out var nativeCodeType)) { if (!m.IsStatic) nargs = ArrayUtil.Concat(wrapper, args); diff --git a/src/IKVM.Tools.Exporter/ExportRuntimeSymbolResolver.cs b/src/IKVM.Tools.Exporter/ExportRuntimeSymbolResolver.cs index d99416986..ebbcf5ed5 100644 --- a/src/IKVM.Tools.Exporter/ExportRuntimeSymbolResolver.cs +++ b/src/IKVM.Tools.Exporter/ExportRuntimeSymbolResolver.cs @@ -172,6 +172,20 @@ public ITypeSymbol ResolveRuntimeType(string typeName) return _runtimeTypeCache.GetOrAdd(typeName, FindRuntimeType) ?? throw new DiagnosticEventException(DiagnosticEvent.CriticalClassNotFound(typeName)); } + /// + public bool TryResolveRuntimeType(string typeName, out ITypeSymbol? type) + { + var t = _runtimeTypeCache.GetOrAdd(typeName, FindRuntimeType); + if (t != null) + { + type = t; + return true; + } + + type = null; + return false; + } + /// /// Attempts to load the specified runtime type. /// diff --git a/src/IKVM.Tools.Importer/ImportAssemblyResolver.cs b/src/IKVM.Tools.Importer/ImportAssemblyResolver.cs index b51a8be78..89c9df5c2 100644 --- a/src/IKVM.Tools.Importer/ImportAssemblyResolver.cs +++ b/src/IKVM.Tools.Importer/ImportAssemblyResolver.cs @@ -1,27 +1,4 @@ -/* - Copyright (C) 2010-2013 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; +using System; using System.Collections.Generic; using System.IO; @@ -32,7 +9,7 @@ namespace IKVM.Tools.Importer { /// - /// Resolves assemblies from the universe of types. + /// Resolves assemblies for the universe of types. /// class ImportAssemblyResolver { @@ -41,7 +18,6 @@ class ImportAssemblyResolver readonly ImportOptions options; readonly IDiagnosticHandler diagnostics; readonly List libpaths = new List(); - readonly Version coreLibVersion; /// /// Initializes a new instance. @@ -69,12 +45,6 @@ public ImportAssemblyResolver(Universe universe, ImportOptions options, IDiagnos // add LIB environmental variable AddLibraryPaths(Environment.GetEnvironmentVariable("LIB") ?? "", false); - - // either load the corelib from the references, or from what already exists - if (options.NoStdLib) - coreLibVersion = LoadCoreLib(options.References).GetName().Version; - else - coreLibVersion = universe.Load(universe.CoreLibName).GetName().Version; } /// @@ -88,45 +58,30 @@ public ImportAssemblyResolver(Universe universe, ImportOptions options, IDiagnos /// /// /// - internal Assembly LoadFile(string path) + Assembly LoadFile(string path) { - string ex = null; - try { - using (var module = universe.OpenRawModule(path)) - { - if (coreLibVersion != null) - { - // to avoid problems (i.e. weird exceptions), we don't allow assemblies to load that reference a newer version of the corelib - foreach (var asmref in module.GetReferencedAssemblies()) - if (asmref.Name == universe.CoreLibName && asmref.Version > coreLibVersion) - throw new DiagnosticEventException(DiagnosticEvent.CoreAssemblyVersionMismatch(asmref.Name, universe.CoreLibName)); - } - - var asm = universe.LoadAssembly(module); - if (asm.Location != module.Location && CanonicalizePath(asm.Location) != CanonicalizePath(module.Location)) - diagnostics.AssemblyLocationIgnored(path, asm.Location, asm.FullName); + using var module = universe.OpenRawModule(path); + var asm = universe.LoadAssembly(module); + if (asm.Location != module.Location && CanonicalizePath(asm.Location) != CanonicalizePath(module.Location)) + diagnostics.AssemblyLocationIgnored(path, asm.Location, asm.FullName); - return asm; - } + return asm; } - catch (IOException x) + catch (IOException e) { - ex = x.Message; + diagnostics.ErrorReadingFile(path, e.Message); } - catch (UnauthorizedAccessException x) + catch (UnauthorizedAccessException e) { - ex = x.Message; + diagnostics.ErrorReadingFile(path, e.Message); } - catch (IKVM.Reflection.BadImageFormatException x) + catch (IKVM.Reflection.BadImageFormatException e) { - ex = x.Message; + diagnostics.ErrorReadingFile(path, e.Message); } - // TODO - Console.Error.WriteLine("Error: unable to load assembly '{0}'" + Environment.NewLine + " ({1})", path, ex); - Environment.Exit(1); return null; } @@ -177,14 +132,6 @@ static string CanonicalizePath(string path) return path; } - internal Assembly LoadWithPartialName(string name) - { - foreach (string path in FindAssemblyPath(name + ".dll")) - return LoadFile(path); - - return null; - } - internal bool ResolveReference(Dictionary cache, List references, string reference) { var files = Array.Empty(); @@ -250,6 +197,10 @@ public Assembly AssemblyResolve(object sender, IKVM.Reflection.ResolveEventArgs if (Match(asm.GetName(), name)) return asm; + // try to locate from library paths + foreach (var lib in FindAssemblyPath(name.Name + ".dll")) + return LoadFile(lib); + if (args.RequestingAssembly != null) return universe.CreateMissingAssembly(args.Name); @@ -318,8 +269,6 @@ Assembly LoadCoreLib(IList references) foreach (var coreLib in FindAssemblyPath(universe.CoreLibName + ".dll")) return LoadFile(coreLib); - Console.Error.WriteLine($"Error: unable to find '{universe.CoreLibName}.dll'."); - Environment.Exit(1); return null; } @@ -337,6 +286,19 @@ IEnumerable FindAssemblyPath(string path) } else { + // check that named assembly exists in references + foreach (var reference in options.References) + { + if (File.Exists(reference) && Path.GetFileName(reference) == path) + yield return reference; + + // for legacy compat, we try again after appending .dll + var p = path + ".dll"; + if (File.Exists(reference) && Path.GetFileName(reference) == p) + yield return reference; + } + + // check for files in libpaths foreach (var libpath in libpaths) { var p = Path.Combine(libpath, path); diff --git a/src/IKVM.Tools.Importer/ImportDiagnosticHandler.cs b/src/IKVM.Tools.Importer/ImportDiagnosticHandler.cs index 53d32a8a1..474603051 100644 --- a/src/IKVM.Tools.Importer/ImportDiagnosticHandler.cs +++ b/src/IKVM.Tools.Importer/ImportDiagnosticHandler.cs @@ -30,12 +30,14 @@ public ImportDiagnosticHandler(ImportOptions options, string spec, DiagnosticFor /// public override bool IsEnabled(Diagnostic diagnostic) { - //if (diagnostic.Level is DiagnosticLevel.Trace or DiagnosticLevel.Info) - // return false; - - if (diagnostic.Level == DiagnosticLevel.Warning && _options.NoWarn.Any(i => i.Id == diagnostic.Id)) + // trace messages aren't useful for the command line + if (diagnostic.Level is DiagnosticLevel.Trace) return false; + // nowarn empty means all + if (diagnostic.Level == DiagnosticLevel.Warning && _options.NoWarn != null) + return _options.NoWarn.Length == 0 || _options.NoWarn.Any(i => i == diagnostic) == false; + return true; } diff --git a/src/IKVM.Tools.Importer/ImportRuntimeSymbolResolver.cs b/src/IKVM.Tools.Importer/ImportRuntimeSymbolResolver.cs index eed653511..c0e42bdb2 100644 --- a/src/IKVM.Tools.Importer/ImportRuntimeSymbolResolver.cs +++ b/src/IKVM.Tools.Importer/ImportRuntimeSymbolResolver.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.IO; using System.Linq; using IKVM.CoreLib.Diagnostics; @@ -40,7 +41,7 @@ static IEnumerable GetSystemTypeNames() readonly IDiagnosticHandler _diagnostics; readonly Universe _universe; readonly IkvmReflectionSymbolContext _symbols; - readonly bool _bootstrap; + readonly ImportOptions _options; IAssemblySymbol? _coreAssembly; readonly ConcurrentDictionary _coreTypeCache = new(); @@ -67,7 +68,7 @@ public ImportRuntimeSymbolResolver(IDiagnosticHandler diagnostics, Universe univ _diagnostics = diagnostics ?? throw new ArgumentNullException(nameof(diagnostics)); _universe = universe ?? throw new ArgumentNullException(nameof(universe)); _symbols = symbols ?? throw new ArgumentNullException(nameof(symbols)); - _bootstrap = options.Bootstrap; + _options = options ?? throw new ArgumentNullException(nameof(options)); } /// @@ -90,10 +91,26 @@ public IAssemblySymbol GetRuntimeAssembly() /// IAssemblySymbol? FindRuntimeAssembly() { + // search for already loaded runtime foreach (var assembly in _universe.GetAssemblies()) if (assembly.GetType("IKVM.Runtime.JVM") is Type) return GetSymbol(assembly); + // user explicitly specified path to runtime + if (_options.Runtime != null) + if (_options.Runtime.Exists) + return GetSymbol(_universe.LoadFile(_options.Runtime.FullName)); + + // fallback to resolution against universe + try + { + return GetSymbol(_universe.Load("IKVM.Runtime")); + } + catch (FileNotFoundException) + { + // ignore, we tried + } + return null; } @@ -101,7 +118,7 @@ public IAssemblySymbol GetRuntimeAssembly() public IAssemblySymbol? GetBaseAssembly() { // bootstrap mode is used for builing the main assembly, and thus should not return the existing base assembly - if (_bootstrap) + if (_options.Bootstrap) return null; return (_baseAssembly ??= FindBaseAssembly()) ?? throw new DiagnosticEventException(DiagnosticEvent.BootstrapClassesMissing()); @@ -116,6 +133,16 @@ public IAssemblySymbol GetRuntimeAssembly() if (assembly.GetType("java.lang.Object") is Type) return GetSymbol(assembly); + // fallback to resolution against universe + try + { + return GetSymbol(_universe.Load("IKVM.Java")); + } + catch (FileNotFoundException) + { + // ignore, we tried + } + return null; } @@ -167,15 +194,29 @@ public ITypeSymbol ResolveSystemType(string typeName) } /// - public ITypeSymbol? ResolveRuntimeType(string typeName) + public ITypeSymbol ResolveRuntimeType(string typeName) + { + return GetRuntimeAssembly().GetType(typeName) ?? throw new TypeLoadException(); + } + + /// + public bool TryResolveRuntimeType(string typeName, out ITypeSymbol? type) { - return GetRuntimeAssembly().GetType(typeName); + var t = GetRuntimeAssembly().GetType(typeName); + if (t != null) + { + type = t; + return true; + } + + type = null; + return false; } /// - public ITypeSymbol? ResolveBaseType(string typeName) + public ITypeSymbol ResolveBaseType(string typeName) { - return GetBaseAssembly().GetType(typeName); + return GetBaseAssembly()?.GetType(typeName) ?? throw new TypeLoadException(); } /// diff --git a/src/IKVM.Tools.Importer/ImportTool.cs b/src/IKVM.Tools.Importer/ImportTool.cs index 6dd53d232..c853fdd92 100644 --- a/src/IKVM.Tools.Importer/ImportTool.cs +++ b/src/IKVM.Tools.Importer/ImportTool.cs @@ -152,8 +152,8 @@ ImportAssemblyResolver CreateResolver(IDiagnosticHandler diagnostics, ImportOpti // warn when unable to resolve a member universe.ResolvedMissingMember += (Module requestingModule, MemberInfo member) => { - if (requestingModule != null && member is IKVM.Reflection.Type) - diagnostics.UnableToResolveType(requestingModule.Name, ((IKVM.Reflection.Type)member).FullName, member.Module.FullyQualifiedName); + if (requestingModule != null && member is IKVM.Reflection.Type type) + diagnostics.UnableToResolveType(requestingModule.Name, type.FullName, member.Module.FullyQualifiedName); }; // enable embedded symbol writer diff --git a/src/ikvmc/Properties/launchSettings.json b/src/ikvmc/Properties/launchSettings.json index 02b8e637e..65eabd577 100644 --- a/src/ikvmc/Properties/launchSettings.json +++ b/src/ikvmc/Properties/launchSettings.json @@ -1,8 +1,8 @@ { - "profiles": { - "ikvmc": { - "commandName": "Project", - "commandLineArgs": "@D:\\ikvm\\src\\IKVM.Java.runtime.win\\obj\\Debug\\net8.0\\IKVM.Java.runtime.win.ikvmc.rsp" - } + "profiles": { + "ikvmc": { + "commandName": "Project", + "commandLineArgs": "@D:\\ikvm\\src\\IKVM.Java\\obj\\Debug\\net472\\IKVM.Java.ikvmc.rsp" } -} + } +} \ No newline at end of file diff --git a/src/ikvmc/ikvmc.csproj b/src/ikvmc/ikvmc.csproj index 939ff4bbc..89cfd5c00 100644 --- a/src/ikvmc/ikvmc.csproj +++ b/src/ikvmc/ikvmc.csproj @@ -1,7 +1,7 @@  Exe - net8.0;net472;net6.0 + net472;net8.0;net6.0 $(_SupportedToolRuntimes) true true From 5b464a51c18555d0a079e6922009d28e473be940 Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Wed, 2 Oct 2024 21:09:56 -0500 Subject: [PATCH 22/51] Formatting. --- src/IKVM.Runtime/JVM.Properties.cs | 691 ++++++++++++++--------------- 1 file changed, 345 insertions(+), 346 deletions(-) diff --git a/src/IKVM.Runtime/JVM.Properties.cs b/src/IKVM.Runtime/JVM.Properties.cs index 589833449..f97f9f49e 100644 --- a/src/IKVM.Runtime/JVM.Properties.cs +++ b/src/IKVM.Runtime/JVM.Properties.cs @@ -11,122 +11,122 @@ namespace IKVM.Runtime { - static partial class JVM - { - - /// - /// Property values loaded into the JVM from various sources. - /// - public static class Properties - { - - /// - /// Represents an entry in the IKVM properties. - /// - internal record struct IkvmPropEntry(string BasePath, string Value); - - static readonly IDictionary user = new Dictionary(); - static readonly Lazy> ikvm = new Lazy>(GetIkvmProperties); - static readonly Lazy> init = new Lazy>(GetInitProperties); - static readonly Lazy homePath = new Lazy(GetHomePath); - - /// - /// Gets the set of properties that are set by the user before initialization. Modification of values in this - /// dictionary must happen early in the program's initialization before any Java code has been accessed or - /// run. - /// - public static IDictionary User => user; - - /// - /// Gets the set of properties that are set in the 'ikvm.properties' file before initialization. - /// - internal static IReadOnlyDictionary Ikvm => ikvm.Value; - - /// - /// Gets the set of properties that are initialized with the JVM and provided to the JDK. - /// - internal static IReadOnlyDictionary Init => init.Value; - - /// - /// Gets the home path. - /// - internal static string HomePath => homePath.Value; - - /// - /// Gets the raw search paths to examine for ikvm.properties. - /// - /// - static IEnumerable GetIkvmPropertiesSearchPathsIter() - { - if (AppContext.BaseDirectory is string basePath && !string.IsNullOrEmpty(basePath)) - yield return basePath; - - if (AppDomain.CurrentDomain.BaseDirectory is string appBasePath && !string.IsNullOrEmpty(appBasePath)) - yield return appBasePath; - - // search upwards from the location of IKVM.Runtime - // we do this because IKVM.Runtime may be in runtimes/{rid}/lib - if (typeof(Properties).Assembly.Location is string runtimeAssemblyPath && !string.IsNullOrEmpty(runtimeAssemblyPath)) - foreach (var parent in GetParentDirs(runtimeAssemblyPath)) - yield return parent; - } - - /// - /// Returns an iteration of each parent path of the given path until the root. - /// - /// - /// - static IEnumerable GetParentDirs(string path) - { - while (string.IsNullOrWhiteSpace(path = Path.GetDirectoryName(path)) == false) - yield return path; - } - - /// - /// Gets the unique search paths to examine for ikvm.properties. - /// - /// - static IEnumerable GetIkvmPropertiesSearchPaths() - { - return GetIkvmPropertiesSearchPathsIter().Distinct(); - } - - /// - /// Gets the set of properties loaded from any companion 'ikvm.properties' file. - /// - /// - static Dictionary GetIkvmProperties() - { - var props = new Dictionary(); - - foreach (var basePath in GetIkvmPropertiesSearchPaths()) - { - var ikvmPropertiesPath = Path.Combine(basePath, "ikvm.properties"); - if (File.Exists(ikvmPropertiesPath)) - { - LoadProperties(basePath, File.ReadAllLines(ikvmPropertiesPath), props); - break; - } - } - - return props; - } - - /// - /// Gets the home path for IKVM. - /// - /// - static string GetHomePath() - { - // user value takes priority - if (User.TryGetValue("ikvm.home", out var userHomePath) && !string.IsNullOrWhiteSpace(userHomePath)) - if (Directory.Exists(Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, userHomePath)))) - return Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, userHomePath)); - - // ikvm properties value comes next - if (Ikvm.TryGetValue("ikvm.home", out var ikvmHomeEntry) && !string.IsNullOrWhiteSpace(ikvmHomeEntry.Value)) - if (Directory.Exists(Path.GetFullPath(Path.Combine(ikvmHomeEntry.BasePath, ikvmHomeEntry.Value)))) - return Path.GetFullPath(Path.Combine(ikvmHomeEntry.BasePath, ikvmHomeEntry.Value)); + static partial class JVM + { + + /// + /// Property values loaded into the JVM from various sources. + /// + public static class Properties + { + + /// + /// Represents an entry in the IKVM properties. + /// + internal record struct IkvmPropEntry(string BasePath, string Value); + + static readonly IDictionary user = new Dictionary(); + static readonly Lazy> ikvm = new Lazy>(GetIkvmProperties); + static readonly Lazy> init = new Lazy>(GetInitProperties); + static readonly Lazy homePath = new Lazy(GetHomePath); + + /// + /// Gets the set of properties that are set by the user before initialization. Modification of values in this + /// dictionary must happen early in the program's initialization before any Java code has been accessed or + /// run. + /// + public static IDictionary User => user; + + /// + /// Gets the set of properties that are set in the 'ikvm.properties' file before initialization. + /// + internal static IReadOnlyDictionary Ikvm => ikvm.Value; + + /// + /// Gets the set of properties that are initialized with the JVM and provided to the JDK. + /// + internal static IReadOnlyDictionary Init => init.Value; + + /// + /// Gets the home path. + /// + internal static string HomePath => homePath.Value; + + /// + /// Gets the raw search paths to examine for ikvm.properties. + /// + /// + static IEnumerable GetIkvmPropertiesSearchPathsIter() + { + if (AppContext.BaseDirectory is string basePath && !string.IsNullOrEmpty(basePath)) + yield return basePath; + + if (AppDomain.CurrentDomain.BaseDirectory is string appBasePath && !string.IsNullOrEmpty(appBasePath)) + yield return appBasePath; + + // search upwards from the location of IKVM.Runtime + // we do this because IKVM.Runtime may be in runtimes/{rid}/lib + if (typeof(Properties).Assembly.Location is string runtimeAssemblyPath && !string.IsNullOrEmpty(runtimeAssemblyPath)) + foreach (var parent in GetParentDirs(runtimeAssemblyPath)) + yield return parent; + } + + /// + /// Returns an iteration of each parent path of the given path until the root. + /// + /// + /// + static IEnumerable GetParentDirs(string path) + { + while (string.IsNullOrWhiteSpace(path = Path.GetDirectoryName(path)) == false) + yield return path; + } + + /// + /// Gets the unique search paths to examine for ikvm.properties. + /// + /// + static IEnumerable GetIkvmPropertiesSearchPaths() + { + return GetIkvmPropertiesSearchPathsIter().Distinct(); + } + + /// + /// Gets the set of properties loaded from any companion 'ikvm.properties' file. + /// + /// + static Dictionary GetIkvmProperties() + { + var props = new Dictionary(); + + foreach (var basePath in GetIkvmPropertiesSearchPaths()) + { + var ikvmPropertiesPath = Path.Combine(basePath, "ikvm.properties"); + if (File.Exists(ikvmPropertiesPath)) + { + LoadProperties(basePath, File.ReadAllLines(ikvmPropertiesPath), props); + break; + } + } + + return props; + } + + /// + /// Gets the home path for IKVM. + /// + /// + static string GetHomePath() + { + // user value takes priority + if (User.TryGetValue("ikvm.home", out var userHomePath) && !string.IsNullOrWhiteSpace(userHomePath)) + if (Directory.Exists(Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, userHomePath)))) + return Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, userHomePath)); + + // ikvm properties value comes next + if (Ikvm.TryGetValue("ikvm.home", out var ikvmHomeEntry) && !string.IsNullOrWhiteSpace(ikvmHomeEntry.Value)) + if (Directory.Exists(Path.GetFullPath(Path.Combine(ikvmHomeEntry.BasePath, ikvmHomeEntry.Value)))) + return Path.GetFullPath(Path.Combine(ikvmHomeEntry.BasePath, ikvmHomeEntry.Value)); #if NET // specified home directory in runtime.json, where path is relative to application @@ -150,15 +150,15 @@ static string GetHomePath() } #endif - // find first occurance of home root - if (User.TryGetValue("ikvm.home.root", out var userHomeRoot) && !string.IsNullOrWhiteSpace(userHomeRoot)) - if (ResolveHomePathFromRoot(Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, userHomeRoot))) is string userHomeRootPath) - return userHomeRootPath; + // find first occurance of home root + if (User.TryGetValue("ikvm.home.root", out var userHomeRoot) && !string.IsNullOrWhiteSpace(userHomeRoot)) + if (ResolveHomePathFromRoot(Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, userHomeRoot))) is string userHomeRootPath) + return userHomeRootPath; - // ikvm properties value comes next - if (Ikvm.TryGetValue("ikvm.home.root", out var ikvmHomeRootEntry) && !string.IsNullOrWhiteSpace(ikvmHomeRootEntry.Value)) - if (ResolveHomePathFromRoot(Path.GetFullPath(Path.Combine(ikvmHomeRootEntry.BasePath, ikvmHomeRootEntry.Value))) is string ikvmHomeRootPath) - return ikvmHomeRootPath; + // ikvm properties value comes next + if (Ikvm.TryGetValue("ikvm.home.root", out var ikvmHomeRootEntry) && !string.IsNullOrWhiteSpace(ikvmHomeRootEntry.Value)) + if (ResolveHomePathFromRoot(Path.GetFullPath(Path.Combine(ikvmHomeRootEntry.BasePath, ikvmHomeRootEntry.Value))) is string ikvmHomeRootPath) + return ikvmHomeRootPath; #if NET // specified home root directory in runtime.json, where path is relative to application @@ -182,106 +182,105 @@ static string GetHomePath() } #endif - // fallback to directory in base dir - if (string.IsNullOrWhiteSpace(AppContext.BaseDirectory) == false) - if (ResolveHomePathFromRoot(Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "ikvm"))) is string appHomeRootPath) - return appHomeRootPath; - - // fallback to directory in base dir - if (string.IsNullOrWhiteSpace(AppDomain.CurrentDomain.BaseDirectory) == false) - if (ResolveHomePathFromRoot(Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ikvm"))) is string domainHomeRootPath) - return domainHomeRootPath; - - throw new InternalException("Could not locate ikvm home path."); - } - - /// - /// Scans the given root path for the home for the currently executing runtime. - /// - /// - /// - static string ResolveHomePathFromRoot(string homePathRoot) - { - // calculate ikvm.home from ikvm.home.root - if (Directory.Exists(homePathRoot)) - { - foreach (var rid in RuntimeUtil.SupportedRuntimeIdentifiers) - { - var ikvmHomePath = Path.GetFullPath(Path.Combine(homePathRoot, rid)); - if (Directory.Exists(ikvmHomePath)) - return ikvmHomePath; - } - } - - return null; - } - - /// - /// Reads the property lines from the specified file into the dictionary. - /// - /// - /// - static void LoadProperties(string basePath, IEnumerable lines, Dictionary props) - { - foreach (var l in lines) - { - var a = l.Split(new[] { '=' }, 2, StringSplitOptions.RemoveEmptyEntries); - if (a.Length >= 2) - props[a[0].Trim()] = new IkvmPropEntry(basePath, a[1]?.Trim() ?? ""); - } - } - - /// - /// Gets the set of init properties. - /// - /// - static Dictionary GetInitProperties() - { + // fallback to directory in base dir + if (string.IsNullOrWhiteSpace(AppContext.BaseDirectory) == false) + if (ResolveHomePathFromRoot(Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "ikvm"))) is string appHomeRootPath) + return appHomeRootPath; + + // fallback to directory in base dir + if (string.IsNullOrWhiteSpace(AppDomain.CurrentDomain.BaseDirectory) == false) + if (ResolveHomePathFromRoot(Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ikvm"))) is string domainHomeRootPath) + return domainHomeRootPath; + + throw new InternalException("Could not locate ikvm home path."); + } + + /// + /// Scans the given root path for the home for the currently executing runtime. + /// + /// + /// + static string ResolveHomePathFromRoot(string homePathRoot) + { + // calculate ikvm.home from ikvm.home.root + if (Directory.Exists(homePathRoot)) + { + foreach (var rid in RuntimeUtil.SupportedRuntimeIdentifiers) + { + var ikvmHomePath = Path.GetFullPath(Path.Combine(homePathRoot, rid)); + if (Directory.Exists(ikvmHomePath)) + return ikvmHomePath; + } + } + + return null; + } + + /// + /// Reads the property lines from the specified file into the dictionary. + /// + /// + /// + static void LoadProperties(string basePath, IEnumerable lines, Dictionary props) + { + foreach (var l in lines) + { + var a = l.Split(new[] { '=' }, 2, StringSplitOptions.RemoveEmptyEntries); + if (a.Length >= 2) + props[a[0].Trim()] = new IkvmPropEntry(basePath, a[1]?.Trim() ?? ""); + } + } + + /// + /// Gets the set of init properties. + /// + /// + static Dictionary GetInitProperties() + { #if FIRST_PASS || IMPORTER || EXPORTER throw new NotImplementedException(); #else - var p = new Dictionary(); - InitSystemProperties(p); - return p; + var p = new Dictionary(); + InitSystemProperties(p); + return p; #endif - } - - /// - /// Initialize system properties key and value. - /// - /// - static void InitSystemProperties(Dictionary p) - { + } + + /// + /// Initialize system properties key and value. + /// + /// + static void InitSystemProperties(Dictionary p) + { #if FIRST_PASS || IMPORTER || EXPORTER - throw new NotImplementedException(); + throw new NotImplementedException(); #else - p["openjdk.version"] = Constants.openjdk_version; - p["java.vm.name"] = Constants.java_vm_name; - p["java.vm.version"] = Constants.java_vm_version; - p["java.vm.vendor"] = Constants.java_vm_vendor; - p["java.vm.specification.name"] = "Java Virtual Machine Specification"; - p["java.vm.specification.version"] = Constants.java_vm_specification_version; - p["java.vm.specification.vendor"] = Constants.java_vm_specification_vendor; - p["java.vm.info"] = "compiled mode"; - p["java.runtime.name"] = Constants.java_runtime_name; - p["java.runtime.version"] = Constants.java_runtime_version; - - // various directory paths - p["ikvm.home"] = HomePath; - p["java.home"] = HomePath; - p["java.library.path"] = GetLibraryPath(); - p["java.ext.dirs"] = Path.Combine(HomePath, "lib", "ext"); - p["java.endorsed.dirs"] = Path.Combine(HomePath, "lib", "endorsed"); - p["sun.boot.library.path"] = GetBootLibraryPath(); - p["sun.boot.class.path"] = VfsTable.GetAssemblyClassesPath(Vfs.Context, Context.Resolver.ResolveBaseAssembly().AsReflection(), HomePath); - p["sun.cds.enableSharedLookupCache"] = "false"; - - // unlimited direct memory - p["sun.nio.MaxDirectMemorySize"] = "-1"; - - // default to FORK on OSX, instead of posix_spawn with jspawnhelper - if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) - p["jdk.lang.Process.launchMechanism"] = "FORK"; + p["openjdk.version"] = Constants.openjdk_version; + p["java.vm.name"] = Constants.java_vm_name; + p["java.vm.version"] = Constants.java_vm_version; + p["java.vm.vendor"] = Constants.java_vm_vendor; + p["java.vm.specification.name"] = "Java Virtual Machine Specification"; + p["java.vm.specification.version"] = Constants.java_vm_specification_version; + p["java.vm.specification.vendor"] = Constants.java_vm_specification_vendor; + p["java.vm.info"] = "compiled mode"; + p["java.runtime.name"] = Constants.java_runtime_name; + p["java.runtime.version"] = Constants.java_runtime_version; + + // various directory paths + p["java.home"] = HomePath; + p["java.library.path"] = GetLibraryPath(); + p["java.ext.dirs"] = Path.Combine(HomePath, "lib", "ext"); + p["java.endorsed.dirs"] = Path.Combine(HomePath, "lib", "endorsed"); + p["sun.boot.library.path"] = GetBootLibraryPath(); + p["sun.boot.class.path"] = VfsTable.GetAssemblyClassesPath(Vfs.Context, Context.Resolver.GetBaseAssembly().AsReflection(), HomePath); + p["sun.cds.enableSharedLookupCache"] = "false"; + + // unlimited direct memory + p["sun.nio.MaxDirectMemorySize"] = "-1"; + + // default to FORK on OSX, instead of posix_spawn with jspawnhelper + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + p["jdk.lang.Process.launchMechanism"] = "FORK"; #if NETFRAMEWORK // read properties from app.config @@ -310,138 +309,138 @@ static void InitSystemProperties(Dictionary p) } #endif - // set the properties that were specfied - if (user != null) - foreach (var kvp in user) - p[kvp.Key] = kvp.Value; + // set the properties that were specfied + if (user != null) + foreach (var kvp in user) + p[kvp.Key] = kvp.Value; #endif - } - - /// - /// Gets the path string for loading native libraries. - /// - /// - static string GetLibraryPath() - { + } + + /// + /// Gets the path string for loading native libraries. + /// + /// + static string GetLibraryPath() + { #if FIRST_PASS || IMPORTER || EXPORTER throw new NotImplementedException(); #else - var libraryPath = new List(); - - if (RuntimeUtil.IsWindows) - { - // see /hotspot/src/os/windows/vm/os_windows.cpp for the comment that describes how we build the path - var windir = SafeGetEnvironmentVariable("SystemRoot"); - if (windir != null) - libraryPath.Add(Path.Combine(windir, "Sun", "Java", "bin")); - - try - { - libraryPath.Add(Environment.SystemDirectory); - } - catch (SecurityException) - { - - } - - if (windir != null) - libraryPath.Add(windir); - - var path = SafeGetEnvironmentVariable("PATH"); - if (path != null) - foreach (var i in path.Split(Path.PathSeparator)) - libraryPath.Add(i); - } - - if (RuntimeUtil.IsLinux) - { - // on Linux we have some hardcoded paths (from /hotspot/src/os/linux/vm/os_linux.cpp) - // and we can only guess the cpu arch based on bitness (that means only x86 and x64) - libraryPath.Add(Path.Combine("/usr/java/packages/lib/", IntPtr.Size == 4 ? "i386" : "amd64")); - libraryPath.Add("/lib"); - libraryPath.Add("/usr/lib"); - - // prefix with LD_LIBRARY_PATH - var ld_library_path = SafeGetEnvironmentVariable("LD_LIBRARY_PATH"); - if (ld_library_path != null) - foreach (var i in ld_library_path.Split(Path.PathSeparator).Reverse()) - libraryPath.Insert(0, i); - } - - if (RuntimeUtil.IsOSX) - { - var home = SafeGetEnvironmentVariable("HOME"); - if (home != null) - libraryPath.Add(Path.Combine(home, "Library/Java/Extensions")); - - libraryPath.Add("/Library/Java/Extensions"); - libraryPath.Add("/Network/Library/Java/Extensions"); - libraryPath.Add("/System/Library/Java/Extensions"); - libraryPath.Add("/usr/lib/java"); - - // prefix with JAVA_LIBRARY_PATH - var javaLibraryPath = SafeGetEnvironmentVariable("JAVA_LIBRARY_PATH"); - if (javaLibraryPath != null) - foreach (var i in javaLibraryPath.Split(Path.PathSeparator)) - libraryPath.Add(i); - - // prefix with DYLD_LIBRARY_PATH - var dyldLibraryPath = SafeGetEnvironmentVariable("DYLD_LIBRARY_PATH"); - if (dyldLibraryPath != null) - foreach (var i in dyldLibraryPath.Split(Path.PathSeparator)) - libraryPath.Add(i); - - if (home != null) - libraryPath.Add(home); - - libraryPath.Add("."); - } - - try - { - var l = new List(); - - foreach (var d in GetIkvmPropertiesSearchPaths()) - { - l.Add(d); - foreach (var rid in RuntimeUtil.SupportedRuntimeIdentifiers) - l.Add(Path.Combine(d, "runtimes", rid, "native")); - } - - libraryPath.InsertRange(0, l); - } - catch (Exception) - { - // ignore - } - - if (RuntimeUtil.IsWindows) - libraryPath.Add("."); - - return string.Join(Path.PathSeparator.ToString(), libraryPath.Distinct()); + var libraryPath = new List(); + + if (RuntimeUtil.IsWindows) + { + // see /hotspot/src/os/windows/vm/os_windows.cpp for the comment that describes how we build the path + var windir = SafeGetEnvironmentVariable("SystemRoot"); + if (windir != null) + libraryPath.Add(Path.Combine(windir, "Sun", "Java", "bin")); + + try + { + libraryPath.Add(Environment.SystemDirectory); + } + catch (SecurityException) + { + + } + + if (windir != null) + libraryPath.Add(windir); + + var path = SafeGetEnvironmentVariable("PATH"); + if (path != null) + foreach (var i in path.Split(Path.PathSeparator)) + libraryPath.Add(i); + } + + if (RuntimeUtil.IsLinux) + { + // on Linux we have some hardcoded paths (from /hotspot/src/os/linux/vm/os_linux.cpp) + // and we can only guess the cpu arch based on bitness (that means only x86 and x64) + libraryPath.Add(Path.Combine("/usr/java/packages/lib/", IntPtr.Size == 4 ? "i386" : "amd64")); + libraryPath.Add("/lib"); + libraryPath.Add("/usr/lib"); + + // prefix with LD_LIBRARY_PATH + var ld_library_path = SafeGetEnvironmentVariable("LD_LIBRARY_PATH"); + if (ld_library_path != null) + foreach (var i in ld_library_path.Split(Path.PathSeparator).Reverse()) + libraryPath.Insert(0, i); + } + + if (RuntimeUtil.IsOSX) + { + var home = SafeGetEnvironmentVariable("HOME"); + if (home != null) + libraryPath.Add(Path.Combine(home, "Library/Java/Extensions")); + + libraryPath.Add("/Library/Java/Extensions"); + libraryPath.Add("/Network/Library/Java/Extensions"); + libraryPath.Add("/System/Library/Java/Extensions"); + libraryPath.Add("/usr/lib/java"); + + // prefix with JAVA_LIBRARY_PATH + var javaLibraryPath = SafeGetEnvironmentVariable("JAVA_LIBRARY_PATH"); + if (javaLibraryPath != null) + foreach (var i in javaLibraryPath.Split(Path.PathSeparator)) + libraryPath.Add(i); + + // prefix with DYLD_LIBRARY_PATH + var dyldLibraryPath = SafeGetEnvironmentVariable("DYLD_LIBRARY_PATH"); + if (dyldLibraryPath != null) + foreach (var i in dyldLibraryPath.Split(Path.PathSeparator)) + libraryPath.Add(i); + + if (home != null) + libraryPath.Add(home); + + libraryPath.Add("."); + } + + try + { + var l = new List(); + + foreach (var d in GetIkvmPropertiesSearchPaths()) + { + l.Add(d); + foreach (var rid in RuntimeUtil.SupportedRuntimeIdentifiers) + l.Add(Path.Combine(d, "runtimes", rid, "native")); + } + + libraryPath.InsertRange(0, l); + } + catch (Exception) + { + // ignore + } + + if (RuntimeUtil.IsWindows) + libraryPath.Add("."); + + return string.Join(Path.PathSeparator.ToString(), libraryPath.Distinct()); #endif - } - - /// - /// Gets the boot library paths. - /// - /// - static IEnumerable GetBootLibraryPathsIter() - { - yield return Path.Combine(HomePath, "bin"); - } - - /// - /// Gets the boot library paths - /// - /// - static string GetBootLibraryPath() - { - return string.Join(Path.PathSeparator.ToString(), GetBootLibraryPathsIter()); - } - - } - - } + } + + /// + /// Gets the boot library paths. + /// + /// + static IEnumerable GetBootLibraryPathsIter() + { + yield return Path.Combine(HomePath, "bin"); + } + + /// + /// Gets the boot library paths + /// + /// + static string GetBootLibraryPath() + { + return string.Join(Path.PathSeparator.ToString(), GetBootLibraryPathsIter()); + } + + } + + } } From c6f5b095cea6450ac01a9fa6bb99afb26175787c Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Thu, 3 Oct 2024 00:12:52 -0500 Subject: [PATCH 23/51] Remove debug stuff. --- Directory.Build.props | 4 ---- src/ikvmc/Properties/launchSettings.json | 8 -------- src/ikvmstub/Properties/launchSettings.json | 8 -------- 3 files changed, 20 deletions(-) delete mode 100644 src/ikvmc/Properties/launchSettings.json delete mode 100644 src/ikvmstub/Properties/launchSettings.json diff --git a/Directory.Build.props b/Directory.Build.props index bc21f1c58..bde86f5e5 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -7,10 +7,6 @@ win-x64;win-x86;win-arm64;linux-x64;linux-arm;linux-arm64;linux-musl-x64;linux-musl-arm;linux-musl-arm64;osx-x64;osx-arm64 $(SupportedImageRuntimes) - win-x64;win-x86 - win-x64;win-x86 - win-x64;win-x86 - <_SupportedRuntimes>;$(SupportedRuntimes); <_EnabledRuntimes>;$(EnabledRuntimes); <_SupportedToolRuntimes>;$(SupportedToolRuntimes); diff --git a/src/ikvmc/Properties/launchSettings.json b/src/ikvmc/Properties/launchSettings.json deleted file mode 100644 index 65eabd577..000000000 --- a/src/ikvmc/Properties/launchSettings.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "profiles": { - "ikvmc": { - "commandName": "Project", - "commandLineArgs": "@D:\\ikvm\\src\\IKVM.Java\\obj\\Debug\\net472\\IKVM.Java.ikvmc.rsp" - } - } -} \ No newline at end of file diff --git a/src/ikvmstub/Properties/launchSettings.json b/src/ikvmstub/Properties/launchSettings.json deleted file mode 100644 index 42c5223ee..000000000 --- a/src/ikvmstub/Properties/launchSettings.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "profiles": { - "ikvmstub": { - "commandName": "Project", - "commandLineArgs": "--bootstrap --nostdlib --non-public-types --parameters --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\Microsoft.Win32.Primitives.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Collections.Concurrent.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Collections.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Collections.NonGeneric.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Diagnostics.StackTrace.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Diagnostics.Tracing.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.IO.Compression.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.IO.MemoryMappedFiles.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Linq.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Memory.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Net.Primitives.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Numerics.Vectors.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Reflection.Emit.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Reflection.Emit.ILGeneration.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Reflection.Emit.Lightweight.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Reflection.Primitives.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Resources.Writer.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Runtime.CompilerServices.Unsafe.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Runtime.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Runtime.InteropServices.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Runtime.Intrinsics.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Runtime.Loader.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Security.Cryptography.Algorithms.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Security.Cryptography.Encoding.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Security.Cryptography.Primitives.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Security.Cryptography.X509Certificates.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Text.Encoding.Extensions.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Threading.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Threading.Overlapped.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\6.0.33\\ref\\net6.0\\System.Threading.ThreadPool.dll\" --reference:\"D:\\ikvm\\src\\IKVM.CoreLib\\obj\\Debug\\net6.0\\ref\\IKVM.CoreLib.dll\" --reference:\"D:\\ikvm\\src\\IKVM.Java\\bin\\Debug\\net6.0\\IKVM.Java.dll\" --reference:\"D:\\ikvm\\src\\IKVM.Reflection\\obj\\Debug\\net6.0\\ref\\IKVM.Reflection.dll\" --reference:\"D:\\ikvm\\src\\IKVM.Runtime-ref\\obj\\Debug\\net6.0\\ref\\IKVM.Runtime.dll\" --reference:\"D:\\packages\\NuGet\\cache\\ikvm.bytecode\\9.1.3\\lib\\net6.0\\IKVM.ByteCode.dll\" --reference:\"D:\\packages\\NuGet\\cache\\system.collections.immutable\\8.0.0\\lib\\net6.0\\System.Collections.Immutable.dll\" --reference:\"D:\\packages\\NuGet\\cache\\system.io.pipelines\\8.0.0\\lib\\net6.0\\System.IO.Pipelines.dll\" --reference:\"D:\\packages\\NuGet\\cache\\system.reflection.metadata\\8.0.0\\lib\\net6.0\\System.Reflection.Metadata.dll\" --reference:\"D:\\packages\\NuGet\\cache\\system.text.encodings.web\\8.0.0\\lib\\net6.0\\System.Text.Encodings.Web.dll\" --reference:\"D:\\packages\\NuGet\\cache\\system.text.json\\8.0.4\\lib\\net6.0\\System.Text.Json.dll\" --out:\"IKVM.Runtime.jar\" \"D:\\ikvm\\src\\IKVM.Runtime-ref\\obj\\Debug\\net6.0\\ref\\IKVM.Runtime.dll\"" - } - } -} \ No newline at end of file From 672d456782ab5d9d21d1a9b8a3c6de445b782fb3 Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Fri, 4 Oct 2024 16:21:16 -0500 Subject: [PATCH 24/51] Allow GetMethods when incomplete. --- .../IkvmReflectionSymbolTests.cs | 61 ++++++++---- .../Reflection/ReflectionSymbolTests.cs | 28 ++++++ src/IKVM.CoreLib/Symbols/IMethodSymbol.cs | 4 +- .../Emit/IkvmReflectionTypeSymbolBuilder.cs | 70 ++++++++++++-- .../IkvmReflectionAssemblySymbol.cs | 2 +- .../IkvmReflectionMemberSymbol.cs | 2 +- .../IkvmReflectionModuleSymbol.cs | 2 +- .../IkvmReflectionParameterSymbol.cs | 2 +- .../Emit/ReflectionMemberSymbolBuilder.cs | 2 +- .../Emit/ReflectionMethodSymbolBuilder.cs | 1 + .../Emit/ReflectionTypeSymbolBuilder.cs | 69 ++++++++++++-- .../Reflection/ReflectionAssemblySymbol.cs | 3 + .../Reflection/ReflectionMemberSymbol.cs | 2 + .../Reflection/ReflectionModuleSymbol.cs | 3 + .../Reflection/ReflectionParameterSymbol.cs | 3 + src/IKVM.CoreLib/Symbols/SymbolUtil.cs | 94 +++++++++++++++++++ .../java/lang/invoke/MethodHandleTests.java | 84 +++++------------ src/IKVM.Runtime/ByteCodeHelper.cs | 1 + src/IKVM.Runtime/ReflectUtil.cs | 4 +- .../java/lang/invoke/MethodHandleTests.cs | 25 ++++- src/ikvmc/Properties/launchSettings.json | 8 ++ src/ikvmc/ikvmc.csproj | 2 +- 22 files changed, 364 insertions(+), 108 deletions(-) create mode 100644 src/IKVM.CoreLib/Symbols/SymbolUtil.cs create mode 100644 src/ikvmc/Properties/launchSettings.json diff --git a/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs b/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs index ab284d995..721eefcd6 100644 --- a/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs +++ b/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs @@ -4,6 +4,7 @@ using FluentAssertions; +using IKVM.CoreLib.Symbols; using IKVM.CoreLib.Symbols.IkvmReflection; using IKVM.CoreLib.Symbols.IkvmReflection.Emit; using IKVM.Reflection; @@ -251,7 +252,7 @@ class ClassWithAttributeWithType [TestMethod] public void CanReadCustomAttributes() { - var c = new IkvmReflectionSymbolContext(universe); + var c = new IkvmReflectionSymbolContext(universe!); var s = c.GetOrCreateTypeSymbol(thisAssembly.GetType("IKVM.CoreLib.Tests.Symbols.IkvmReflection.IkvmReflectionSymbolTests+ClassWithAttributeWithType")); var a = s.GetCustomAttribute(c.GetOrCreateTypeSymbol(thisAssembly.GetType("IKVM.CoreLib.Tests.Symbols.IkvmReflection.IkvmReflectionSymbolTests+AttributeWithType"))); var v = a.Value.ConstructorArguments[0].Value; @@ -261,7 +262,7 @@ public void CanReadCustomAttributes() [TestMethod] public void CanResolveAssemblyBuilder() { - var c = new IkvmReflectionSymbolContext(universe); + var c = new IkvmReflectionSymbolContext(universe!); var a = universe.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Save); var assemblySymbol = c.GetOrCreateAssemblySymbol(a); assemblySymbol.Should().BeOfType(); @@ -271,7 +272,7 @@ public void CanResolveAssemblyBuilder() [TestMethod] public void CanResolveModuleBuilder() { - var c = new IkvmReflectionSymbolContext(universe); + var c = new IkvmReflectionSymbolContext(universe!); var a = universe.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Save); var m = a.DefineDynamicModule("DynamicModule", "DynamicModule.dll"); var moduleSymbol = c.GetOrCreateModuleSymbol(m); @@ -282,7 +283,7 @@ public void CanResolveModuleBuilder() [TestMethod] public void CanResolveTypeBuilder() { - var c = new IkvmReflectionSymbolContext(universe); + var c = new IkvmReflectionSymbolContext(universe!); var a = universe.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Save); var m = a.DefineDynamicModule("DynamicModule", "DynamicModule.dll"); @@ -295,7 +296,7 @@ public void CanResolveTypeBuilder() [TestMethod] public void CanResolveMultipleTypeBuilders() { - var c = new IkvmReflectionSymbolContext(universe); + var c = new IkvmReflectionSymbolContext(universe!); var a = universe.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Save); var m = a.DefineDynamicModule("DynamicModule", "DynamicModule.dll"); @@ -314,7 +315,7 @@ public void CanResolveMultipleTypeBuilders() [TestMethod] public void CanResolveMethodBuilder() { - var c = new IkvmReflectionSymbolContext(universe); + var c = new IkvmReflectionSymbolContext(universe!); var a = universe.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Save); var m = a.DefineDynamicModule("DynamicModule", "DynamicModule.dll"); var t = m.DefineType("DynamicType"); @@ -328,7 +329,7 @@ public void CanResolveMethodBuilder() [TestMethod] public void CanResolveMultipleMethodBuilders() { - var c = new IkvmReflectionSymbolContext(universe); + var c = new IkvmReflectionSymbolContext(universe!); var a = universe.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Save); var m = a.DefineDynamicModule("DynamicModule", "DynamicModule.dll"); var t = m.DefineType("DynamicType"); @@ -347,7 +348,7 @@ public void CanResolveMultipleMethodBuilders() [TestMethod] public void CanResolveFieldBuilder() { - var c = new IkvmReflectionSymbolContext(universe); + var c = new IkvmReflectionSymbolContext(universe!); var a = universe.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Save); var m = a.DefineDynamicModule("DynamicModule", "DynamicModule.dll"); var t = m.DefineType("DynamicType"); @@ -361,7 +362,7 @@ public void CanResolveFieldBuilder() [TestMethod] public void CanResolveMultipleFieldBuilders() { - var c = new IkvmReflectionSymbolContext(universe); + var c = new IkvmReflectionSymbolContext(universe!); var a = universe.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Save); var m = a.DefineDynamicModule("DynamicModule", "DynamicModule.dll"); var t = m.DefineType("DynamicType"); @@ -380,7 +381,7 @@ public void CanResolveMultipleFieldBuilders() [TestMethod] public void CanResolvePropertyBuilder() { - var c = new IkvmReflectionSymbolContext(universe); + var c = new IkvmReflectionSymbolContext(universe!); var a = universe.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Save); var m = a.DefineDynamicModule("DynamicModule", "DynamicModule.dll"); var t = m.DefineType("DynamicType"); @@ -394,12 +395,12 @@ public void CanResolvePropertyBuilder() [TestMethod] public void CanResolveMultiplePropertyBuilders() { - var c = new IkvmReflectionSymbolContext(universe); + var c = new IkvmReflectionSymbolContext(universe!); var a = universe.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Save); var m = a.DefineDynamicModule("DynamicModule", "DynamicModule.dll"); var t = m.DefineType("DynamicType"); - var property1 = t.DefineProperty("DynamicProperty1", PropertyAttributes.None, coreAssembly.GetType("System.Object"), []); + var property1 = t.DefineProperty("DynamicProperty1", PropertyAttributes.None, coreAssembly!.GetType("System.Object"), []); var property1Symbol = c.GetOrCreatePropertySymbol(property1); property1Symbol.Should().BeOfType(); property1Symbol.Should().BeSameAs(c.GetOrCreatePropertySymbol(property1)); @@ -413,12 +414,12 @@ public void CanResolveMultiplePropertyBuilders() [TestMethod] public void CanResolveEventBuilder() { - var c = new IkvmReflectionSymbolContext(universe); + var c = new IkvmReflectionSymbolContext(universe!); var a = universe.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Save); var m = a.DefineDynamicModule("DynamicModule", "DynamicModule.dll"); var t = m.DefineType("DynamicType"); - var event1 = t.DefineEvent("DynamicEvent", EventAttributes.None, coreAssembly.GetType("System.EventHandler")); + var event1 = t.DefineEvent("DynamicEvent", EventAttributes.None, coreAssembly!.GetType("System.EventHandler")); var event1Symbol = c.GetOrCreateEventSymbol(event1); event1Symbol.Should().BeOfType(); event1Symbol.Should().BeSameAs(c.GetOrCreateEventSymbol(event1)); @@ -427,12 +428,12 @@ public void CanResolveEventBuilder() [TestMethod] public void CanResolveMultipleEventBuilders() { - var c = new IkvmReflectionSymbolContext(universe); + var c = new IkvmReflectionSymbolContext(universe!); var a = universe.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Save); var m = a.DefineDynamicModule("DynamicModule", "DynamicModule.dll"); var t = m.DefineType("DynamicType"); - var event1 = t.DefineEvent("DynamicEvent", EventAttributes.None, coreAssembly.GetType("System.EventHandler")); + var event1 = t.DefineEvent("DynamicEvent", EventAttributes.None, coreAssembly!.GetType("System.EventHandler")); var event1Symbol = c.GetOrCreateEventSymbol(event1); event1Symbol.Should().BeOfType(); event1Symbol.Should().BeSameAs(c.GetOrCreateEventSymbol(event1)); @@ -443,6 +444,34 @@ public void CanResolveMultipleEventBuilders() event2Symbol.Should().BeSameAs(c.GetOrCreateEventSymbol(event2)); } + [TestMethod] + public void CanGetMethodsFromTypeBuilder() + { + var c = new IkvmReflectionSymbolContext(universe!); + var a = c.DefineAssembly(new AssemblyNameInfo("DynamicAssembly")); + var m = a.DefineModule("DynamicModule", "DynamicModule.dll"); + var type = m.DefineType("DynamicType"); + + var method = type.DefineMethod("DynamicMethod1", System.Reflection.MethodAttributes.Public | System.Reflection.MethodAttributes.Static); + var il = method.GetILGenerator(); + il.Emit(System.Reflection.Emit.OpCodes.Ret); + + // before complete + type.GetMethods().Should().HaveCount(5); + var incompleteMethod = type.GetMethod("DynamicMethod1"); + + // complete the type + type.Complete(); + + // after complete + type.GetMethods().Should().HaveCount(5); + var completeMethod = type.GetMethod("DynamicMethod1"); + + // all the methods should be the same + incompleteMethod.Should().BeSameAs(completeMethod); + incompleteMethod.Should().BeSameAs(method); + } + } } diff --git a/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs b/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs index 5d01df942..f0219bf6f 100644 --- a/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs +++ b/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs @@ -421,6 +421,34 @@ public void CanCompleteTypeBuilder() moduleSymbol.GetType("DynamicType1").Should().BeSameAs(type1Symbol); } + [TestMethod] + public void CanGetMethodsFromTypeBuilder() + { + var c = new ReflectionSymbolContext(); + var a = c.DefineAssembly(new AssemblyNameInfo("DynamicAssembly")); + var m = a.DefineModule("DynamicModule", "DynamicModule.dll"); + var type = m.DefineType("DynamicType"); + + var method = type.DefineMethod("DynamicMethod1", System.Reflection.MethodAttributes.Public | System.Reflection.MethodAttributes.Static); + var il = method.GetILGenerator(); + il.Emit(OpCodes.Ret); + + // before complete + type.GetMethods().Should().HaveCount(5); + var incompleteMethod = type.GetMethod("DynamicMethod1"); + + // complete the type + type.Complete(); + + // after complete + type.GetMethods().Should().HaveCount(5); + var completeMethod = type.GetMethod("DynamicMethod1"); + + // all the methods should be the same + incompleteMethod.Should().BeSameAs(completeMethod); + incompleteMethod.Should().BeSameAs(method); + } + } } diff --git a/src/IKVM.CoreLib/Symbols/IMethodSymbol.cs b/src/IKVM.CoreLib/Symbols/IMethodSymbol.cs index 06709a367..c3c8d5c9e 100644 --- a/src/IKVM.CoreLib/Symbols/IMethodSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IMethodSymbol.cs @@ -1,6 +1,4 @@ -using IKVM.CoreLib.Symbols.Emit; - -namespace IKVM.CoreLib.Symbols +namespace IKVM.CoreLib.Symbols { /// diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionTypeSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionTypeSymbolBuilder.cs index 6c899d7fe..c59ad4507 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionTypeSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionTypeSymbolBuilder.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Linq; using System.Runtime.InteropServices; using IKVM.CoreLib.Symbols.Emit; @@ -23,6 +25,8 @@ class IkvmReflectionTypeSymbolBuilder : IkvmReflectionMemberSymbolBuilder, IIkvm IkvmReflectionGenericTypeParameterTable _genericTypeParameterTable; IkvmReflectionTypeSpecTable _specTable; + List? _incompleteMethods; + /// /// Initializes a new instance. /// @@ -237,31 +241,46 @@ public IFieldSymbolBuilder DefineField(string fieldName, ITypeSymbol type, IType /// public IMethodSymbolBuilder DefineMethod(string name, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers) { - return ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, (MethodAttributes)attributes, (CallingConventions)callingConvention, returnType?.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack())); + var m = ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, (MethodAttributes)attributes, (CallingConventions)callingConvention, returnType?.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack())); + _incompleteMethods ??= []; + _incompleteMethods.Add(m); + return m; } /// public IMethodSymbolBuilder DefineMethod(string name, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes) { - return ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, (MethodAttributes)attributes, (CallingConventions)callingConvention, returnType?.Unpack(), parameterTypes?.Unpack())); + var m = ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, (MethodAttributes)attributes, (CallingConventions)callingConvention, returnType?.Unpack(), parameterTypes?.Unpack())); + _incompleteMethods ??= []; + _incompleteMethods.Add(m); + return m; } /// public IMethodSymbolBuilder DefineMethod(string name, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention) { - return ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, (MethodAttributes)attributes, (CallingConventions)callingConvention)); + var m = ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, (MethodAttributes)attributes, (CallingConventions)callingConvention)); + _incompleteMethods ??= []; + _incompleteMethods.Add(m); + return m; } /// public IMethodSymbolBuilder DefineMethod(string name, System.Reflection.MethodAttributes attributes) { - return ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, (MethodAttributes)attributes)); + var m = ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, (MethodAttributes)attributes)); + _incompleteMethods ??= []; + _incompleteMethods.Add(m); + return m; } /// public IMethodSymbolBuilder DefineMethod(string name, System.Reflection.MethodAttributes attributes, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes) { - return ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, (MethodAttributes)attributes, returnType?.Unpack(), parameterTypes?.Unpack())); + var m = ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, (MethodAttributes)attributes, returnType?.Unpack(), parameterTypes?.Unpack())); + _incompleteMethods ??= []; + _incompleteMethods.Add(m); + return m; } /// @@ -516,6 +535,9 @@ public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) /// public IConstructorSymbol? TypeInitializer => ResolveConstructorSymbol(UnderlyingType.TypeInitializer); + /// + public override bool IsComplete => _builder == null; + /// public int GetArrayRank() { @@ -726,13 +748,19 @@ public IMemberSymbol[] GetMembers() /// public IMethodSymbol? GetMethod(string name) { - return ResolveMethodSymbol(UnderlyingType.GetMethod(name)); + if (IsComplete) + return ResolveMethodSymbol(UnderlyingType.GetMethod(name)); + else + return GetIncompleteMethods().FirstOrDefault(i => i.Name == name); } /// public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, (CallingConventions)callConvention, types.Unpack(), modifiers?.Unpack())); + if (IsComplete) + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, (CallingConventions)callConvention, types.Unpack(), modifiers?.Unpack())); + else + throw new NotImplementedException(); } /// @@ -750,7 +778,10 @@ public IMemberSymbol[] GetMembers() /// public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), modifiers?.Unpack())); + if (IsComplete) + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), modifiers?.Unpack())); + else + throw new NotImplementedException(); } /// @@ -762,13 +793,31 @@ public IMemberSymbol[] GetMembers() /// public IMethodSymbol[] GetMethods(System.Reflection.BindingFlags bindingAttr) { - return ResolveMethodSymbols(UnderlyingType.GetMethods((BindingFlags)bindingAttr)); + if (IsComplete) + return ResolveMethodSymbols(UnderlyingType.GetMethods((BindingFlags)bindingAttr)); + else + return GetIncompleteMethods(bindingAttr); } /// public IMethodSymbol[] GetMethods() { - return ResolveMethodSymbols(UnderlyingType.GetMethods()); + if (IsComplete) + return ResolveMethodSymbols(UnderlyingType.GetMethods()); + else + return GetIncompleteMethods(); + } + + /// + /// Gets the set of incomplete methods. + /// + /// + IMethodSymbol[] GetIncompleteMethods(System.Reflection.BindingFlags bindingAttr = System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Instance) + { + if (_incompleteMethods == null) + return []; + else + return SymbolUtil.FilterMethods(this, _incompleteMethods, bindingAttr).Cast().ToArray(); } /// @@ -897,6 +946,7 @@ public void Complete() { _type = _builder.CreateType(); _builder = null; + _incompleteMethods = null; } // force module to reresolve diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs index b5c1d3dd1..2feec1bc0 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs @@ -181,7 +181,7 @@ public bool IsDefined(ITypeSymbol attributeType, bool inherit = false) #endregion /// - public override string ToString() => UnderlyingAssembly.ToString(); + public override string? ToString() => UnderlyingAssembly.ToString(); } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs index b9d322232..f491b412a 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs @@ -209,7 +209,7 @@ public virtual bool IsDefined(ITypeSymbol attributeType, bool inherit = false) #endregion /// - public override string ToString() => UnderlyingMember.ToString()!; + public override string? ToString() => UnderlyingMember.ToString(); } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs index 7c6fddcae..bdd3567c0 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs @@ -327,7 +327,7 @@ public IIkvmReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo p #endregion /// - public override string ToString() => UnderlyingModule.ToString()!; + public override string? ToString() => UnderlyingModule.ToString(); } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterSymbol.cs index 98fb45d39..99e290581 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterSymbol.cs @@ -122,7 +122,7 @@ public ITypeSymbol[] GetRequiredCustomModifiers() #endregion /// - public override string ToString() => UnderlyingParameter.ToString()!; + public override string? ToString() => UnderlyingParameter.ToString(); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMemberSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMemberSymbolBuilder.cs index d3c13c205..b0ee71636 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMemberSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMemberSymbolBuilder.cs @@ -298,7 +298,7 @@ public override IReflectionEventSymbolBuilder ResolveEventSymbol(EventBuilder @e public virtual System.Reflection.MemberTypes MemberType => (System.Reflection.MemberTypes)UnderlyingMember.MemberType; /// - public virtual int MetadataToken => UnderlyingMember.MetadataToken; + public virtual int MetadataToken => UnderlyingMember.GetMetadataTokenSafe(); /// public virtual string Name => UnderlyingMember.Name; diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs index dc5b528dd..c071e4f5f 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs @@ -2,6 +2,7 @@ using System.Reflection; using System.Reflection.Emit; +using IKVM.CoreLib.Reflection; using IKVM.CoreLib.Symbols.Emit; namespace IKVM.CoreLib.Symbols.Reflection.Emit diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs index 176f7d60c..7eede6c1d 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.InteropServices; @@ -22,6 +24,8 @@ class ReflectionTypeSymbolBuilder : ReflectionMemberSymbolBuilder, IReflectionTy ReflectionGenericTypeParameterTable _genericTypeParameterTable; ReflectionTypeSpecTable _specTable; + List? _incompleteMethods; + /// /// Initializes a new instance. /// @@ -236,31 +240,46 @@ public IFieldSymbolBuilder DefineField(string fieldName, ITypeSymbol type, IType /// public IMethodSymbolBuilder DefineMethod(string name, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers) { - return ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, (MethodAttributes)attributes, (CallingConventions)callingConvention, returnType?.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack())); + var m = ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, (MethodAttributes)attributes, (CallingConventions)callingConvention, returnType?.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack())); + _incompleteMethods ??= []; + _incompleteMethods.Add(m); + return m; } /// public IMethodSymbolBuilder DefineMethod(string name, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes) { - return ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, (MethodAttributes)attributes, (CallingConventions)callingConvention, returnType?.Unpack(), parameterTypes?.Unpack())); + var m = ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, (MethodAttributes)attributes, (CallingConventions)callingConvention, returnType?.Unpack(), parameterTypes?.Unpack())); + _incompleteMethods ??= []; + _incompleteMethods.Add(m); + return m; } /// public IMethodSymbolBuilder DefineMethod(string name, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention) { - return ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, (MethodAttributes)attributes, (CallingConventions)callingConvention)); + var m = ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, (MethodAttributes)attributes, (CallingConventions)callingConvention)); + _incompleteMethods ??= []; + _incompleteMethods.Add(m); + return m; } /// public IMethodSymbolBuilder DefineMethod(string name, System.Reflection.MethodAttributes attributes) { - return ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, (MethodAttributes)attributes)); + var m = ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, (MethodAttributes)attributes)); + _incompleteMethods ??= []; + _incompleteMethods.Add(m); + return m; } /// public IMethodSymbolBuilder DefineMethod(string name, System.Reflection.MethodAttributes attributes, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes) { - return ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, (MethodAttributes)attributes, returnType?.Unpack(), parameterTypes?.Unpack())); + var m = ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, (MethodAttributes)attributes, returnType?.Unpack(), parameterTypes?.Unpack())); + _incompleteMethods ??= []; + _incompleteMethods.Add(m); + return m; } /// @@ -527,6 +546,9 @@ public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) /// public IConstructorSymbol? TypeInitializer => ResolveConstructorSymbol(UnderlyingType.TypeInitializer); + /// + public override bool IsComplete => _builder == null; + /// public int GetArrayRank() { @@ -737,13 +759,19 @@ public IMemberSymbol[] GetMembers() /// public IMethodSymbol? GetMethod(string name) { - return ResolveMethodSymbol(UnderlyingType.GetMethod(name)); + if (IsComplete) + return ResolveMethodSymbol(UnderlyingType.GetMethod(name)); + else + return GetIncompleteMethods().FirstOrDefault(i => i.Name == name); } /// public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, (CallingConventions)callConvention, types.Unpack(), modifiers?.Unpack())); + if (IsComplete) + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, (CallingConventions)callConvention, types.Unpack(), modifiers?.Unpack())); + else + throw new NotImplementedException(); } /// @@ -761,7 +789,10 @@ public IMemberSymbol[] GetMembers() /// public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { - return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), modifiers?.Unpack())); + if (IsComplete) + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), modifiers?.Unpack())); + else + throw new NotImplementedException(); } /// @@ -773,13 +804,31 @@ public IMemberSymbol[] GetMembers() /// public IMethodSymbol[] GetMethods(System.Reflection.BindingFlags bindingAttr) { - return ResolveMethodSymbols(UnderlyingType.GetMethods((BindingFlags)bindingAttr)); + if (IsComplete) + return ResolveMethodSymbols(UnderlyingType.GetMethods((BindingFlags)bindingAttr)); + else + return GetIncompleteMethods(bindingAttr); } /// public IMethodSymbol[] GetMethods() { - return ResolveMethodSymbols(UnderlyingType.GetMethods()); + if (IsComplete) + return ResolveMethodSymbols(UnderlyingType.GetMethods()); + else + return GetIncompleteMethods(); + } + + /// + /// Gets the set of incomplete methods. + /// + /// + IMethodSymbol[] GetIncompleteMethods(System.Reflection.BindingFlags bindingAttr = System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Instance) + { + if (_incompleteMethods == null) + return []; + else + return SymbolUtil.FilterMethods(this, _incompleteMethods, bindingAttr).Cast().ToArray(); } /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs index c922a5b4d..f589ea11d 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs @@ -177,6 +177,9 @@ public bool IsDefined(ITypeSymbol attributeType, bool inherit = false) #endregion + /// + public override string? ToString() => UnderlyingAssembly.ToString(); + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs index 3baf997db..b97fa7aa7 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs @@ -208,6 +208,8 @@ public virtual bool IsDefined(ITypeSymbol attributeType, bool inherit = false) #endregion + public override string? ToString() => UnderlyingMember.ToString(); + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs index 9bb62cf7c..7f1bd1ed1 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs @@ -319,6 +319,9 @@ public IReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo param #endregion + /// + public override string? ToString() => UnderlyingModule.ToString(); + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterSymbol.cs index cffe5c8ec..23bfcf04c 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterSymbol.cs @@ -126,6 +126,9 @@ public ITypeSymbol[] GetRequiredCustomModifiers() #endregion + /// + public override string? ToString() => UnderlyingParameter.ToString(); + } } diff --git a/src/IKVM.CoreLib/Symbols/SymbolUtil.cs b/src/IKVM.CoreLib/Symbols/SymbolUtil.cs new file mode 100644 index 000000000..7727345ac --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/SymbolUtil.cs @@ -0,0 +1,94 @@ +using System.Collections.Generic; + +namespace IKVM.CoreLib.Symbols +{ + + static class SymbolUtil + { + + /// + /// Returns true if the given binding flags match, combined with the specified state. + /// + /// + /// + /// + /// + /// + static bool BindingFlagsMatch(bool state, System.Reflection.BindingFlags flags, System.Reflection.BindingFlags trueFlag, System.Reflection.BindingFlags falseFlag) + { + return (state && (flags & trueFlag) == trueFlag) || (!state && (flags & falseFlag) == falseFlag); + } + + /// + /// Evaluates whether the specified would match the . + /// + /// + /// + /// + public static bool BindingFlagsMatch(IMethodSymbol member, System.Reflection.BindingFlags flags) + { + return BindingFlagsMatch(member.IsPublic, flags, System.Reflection.BindingFlags.Public, System.Reflection.BindingFlags.NonPublic) + && BindingFlagsMatch(member.IsStatic, flags, System.Reflection.BindingFlags.Static, System.Reflection.BindingFlags.Instance); + } + + /// + /// Evaluates whether the specified would match the . + /// + /// + /// + /// + public static bool BindingFlagsMatchInherited(IMethodSymbol method, System.Reflection.BindingFlags flags) + { + return BindingFlagsMatch(method.IsPublic, flags, System.Reflection.BindingFlags.Public, System.Reflection.BindingFlags.NonPublic) + && BindingFlagsMatch(method.IsStatic, flags, System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.FlattenHierarchy, System.Reflection.BindingFlags.Instance); + } + + /// + /// Filters the set of methods by the binding attributes. + /// + /// + public static IEnumerable FilterMethods(ITypeSymbol type, IEnumerable methods, System.Reflection.BindingFlags bindingAttr = System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Instance) + { + var list = new HashSet(); + + foreach (var mb in methods) + { + var mi = mb as IMethodSymbol; + if (mi != null && BindingFlagsMatch(mi, bindingAttr)) + if (list.Add(mi)) + yield return mi; + } + + if ((bindingAttr & System.Reflection.BindingFlags.DeclaredOnly) == 0) + { + var baseMethods = new List(); + foreach (var mi in list) + if (mi.IsVirtual) + baseMethods.Add(mi.GetBaseDefinition()); + + for (var baseType = type.BaseType; baseType != null; baseType = baseType.BaseType) + { + foreach (var mi in baseType.GetMethods(System.Reflection.BindingFlags.DeclaredOnly | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Instance)) + { + if (BindingFlagsMatchInherited(mi, bindingAttr)) + { + if (mi.IsVirtual) + { + baseMethods ??= []; + if (baseMethods.Contains(mi.GetBaseDefinition())) + continue; + + baseMethods.Add(mi.GetBaseDefinition()); + } + + if (list.Add(mi)) + yield return mi; + } + } + } + } + } + + } + +} diff --git a/src/IKVM.Java.Tests/java/lang/invoke/MethodHandleTests.java b/src/IKVM.Java.Tests/java/lang/invoke/MethodHandleTests.java index 1a74e96b2..40b6ae0c4 100644 --- a/src/IKVM.Java.Tests/java/lang/invoke/MethodHandleTests.java +++ b/src/IKVM.Java.Tests/java/lang/invoke/MethodHandleTests.java @@ -19,75 +19,39 @@ public static String addStringStatic(String a, String b) { } - interface AddItf { - void apply(List st, int idx, Object v) throws Throwable; - } - @cli.Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute.Annotation() - public void canInvokeVirtual() throws Throwable { - MethodHandles.Lookup lookup = MethodHandles.lookup(); - MethodType mt = MethodType.methodType(String.class, String.class, String.class); - MethodHandle mh = lookup.findVirtual(TestClass.class, "addString", mt); - String s = (String)mh.invoke(new TestClass(), (Object)"a", (Object)"b"); + public void canInvokeExactVirtual() throws Throwable { + MethodHandles.Lookup lookup = getLookup(); + MethodType mt = getMethodType(); + MethodHandle mh = getMethodHandle(lookup, mt); + String s = invokeIt(mh); if (!s.equals("ab")) { throw new Exception(s); } } - @cli.Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute.Annotation() - public void canInvokeStatic() throws Throwable { - MethodHandles.Lookup lookup = MethodHandles.lookup(); - MethodType mt = MethodType.methodType(String.class, String.class, String.class); - MethodHandle mh = lookup.findStatic(TestClass.class, "addStringStatic", mt); - String s = (String)mh.invoke((Object)"a", (Object)"b"); - if (!s.equals("ab")) { - throw new Exception(s); - } + @cli.System.Runtime.CompilerServices.MethodImplAttribute.Annotation(value = cli.System.Runtime.CompilerServices.MethodImplOptions.__Enum.NoInlining) + MethodHandles.Lookup getLookup() throws Throwable + { + return MethodHandles.lookup(); } - - @cli.Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute.Annotation() - public void canInvokeExactVirtual() throws Throwable { - MethodHandles.Lookup lookup = MethodHandles.lookup(); - MethodType mt = MethodType.methodType(String.class, String.class, String.class); - MethodHandle mh = lookup.findVirtual(TestClass.class, "addString", mt); - String s = (String)mh.invokeExact(new TestClass(), "a", "b"); - if (!s.equals("ab")) { - throw new Exception(s); - } + + @cli.System.Runtime.CompilerServices.MethodImplAttribute.Annotation(value = cli.System.Runtime.CompilerServices.MethodImplOptions.__Enum.NoInlining) + MethodType getMethodType() throws Throwable + { + return MethodType.methodType(String.class, String.class, String.class); } - - @cli.Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute.Annotation() - public void canInvokeExactStatic() throws Throwable { - MethodHandles.Lookup lookup = MethodHandles.lookup(); - MethodType mt = MethodType.methodType(String.class, String.class, String.class); - MethodHandle mh = lookup.findStatic(TestClass.class, "addStringStatic", mt); - String s = (String)mh.invokeExact("a", "b"); - if (!s.equals("ab")) { - throw new Exception(s); - } + + @cli.System.Runtime.CompilerServices.MethodImplAttribute.Annotation(value = cli.System.Runtime.CompilerServices.MethodImplOptions.__Enum.NoInlining) + MethodHandle getMethodHandle(MethodHandles.Lookup lookup, MethodType mt) throws Throwable + { + return lookup.findVirtual(TestClass.class, "addString", mt); } - - @cli.Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute.Annotation() - public void canInvokeStaticMethodThatReturnsVoid() throws Throwable { - MethodHandles.Lookup lookup = MethodHandles.lookup(); - MethodType pmt = MethodType.methodType(void.class, int.class, Object.class); - MethodHandle pms = lookup.findVirtual(List.class, "add", pmt); - List list = new ArrayList<>(); - pms.invoke(list, 0, "Hi"); - AddItf pf2 = pms::invoke; - pf2.apply(list, 1, "there"); - AddItf pf3 = pms::invokeExact; - pf3.apply(list, 2, "you"); - - if (!list.get(0).equals("Hi")) { - throw new Exception(list.get(0)); - }; - if (!list.get(1).equals("there")) { - throw new Exception(list.get(1)); - }; - if (!list.get(2).equals("you")) { - throw new Exception(list.get(2)); - }; + + @cli.System.Runtime.CompilerServices.MethodImplAttribute.Annotation(value = cli.System.Runtime.CompilerServices.MethodImplOptions.__Enum.NoInlining) + String invokeIt(MethodHandle mh) throws Throwable + { + return (String)mh.invokeExact(new TestClass(), "a", "b"); } } diff --git a/src/IKVM.Runtime/ByteCodeHelper.cs b/src/IKVM.Runtime/ByteCodeHelper.cs index 942f28550..5ba3bd635 100644 --- a/src/IKVM.Runtime/ByteCodeHelper.cs +++ b/src/IKVM.Runtime/ByteCodeHelper.cs @@ -1112,6 +1112,7 @@ public static Exception DynamicMapException(Exception x, MapFlags mode, global:: #endif } + [MethodImpl(MethodImplOptions.NoInlining)] public static T GetDelegateForInvokeExact(object methodHandle) where T : class, Delegate { diff --git a/src/IKVM.Runtime/ReflectUtil.cs b/src/IKVM.Runtime/ReflectUtil.cs index beca070d4..a87e8132c 100644 --- a/src/IKVM.Runtime/ReflectUtil.cs +++ b/src/IKVM.Runtime/ReflectUtil.cs @@ -97,13 +97,13 @@ internal static bool ContainsTypeBuilder(ITypeSymbol type) type = type.GetElementType(); if (!type.IsGenericType || type.IsGenericTypeDefinition) - return type.AsReflection() is TypeBuilder; + return type is ITypeSymbolBuilder; foreach (var arg in type.GetGenericArguments()) if (ContainsTypeBuilder(arg)) return true; - return type.GetGenericTypeDefinition().AsReflection() is TypeBuilder; + return type.GetGenericTypeDefinition() is ITypeSymbolBuilder; } internal static bool IsDynamicMethod(IMethodSymbol method) diff --git a/src/IKVM.Tests/Java/java/lang/invoke/MethodHandleTests.cs b/src/IKVM.Tests/Java/java/lang/invoke/MethodHandleTests.cs index e6a594c06..29ed96107 100644 --- a/src/IKVM.Tests/Java/java/lang/invoke/MethodHandleTests.cs +++ b/src/IKVM.Tests/Java/java/lang/invoke/MethodHandleTests.cs @@ -1,4 +1,9 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; +using IKVM.Runtime; + +using java.lang; +using java.lang.invoke; + +using Microsoft.VisualStudio.TestTools.UnitTesting; namespace IKVM.Tests.Java.java.lang.invoke { @@ -7,7 +12,25 @@ namespace IKVM.Tests.Java.java.lang.invoke public class MethodHandleTests { + class TestClass + { + + public int Int32Method() + { + return 1; + } + + } + [TestMethod] + public void CanInvokeExactForVirtualWithReturn() + { + var lookup = MethodHandles.lookup(); + var mt = MethodType.methodType(JVM.Context.PrimitiveJavaTypeFactory.INT.ClassObject); + var mh = lookup.findVirtual((Class)ClassLiteral.Value, "Int32Method", mt); + var d = ByteCodeHelper.GetDelegateForInvokeExact>(mh); + var s = d.Invoke(new TestClass()); + } } diff --git a/src/ikvmc/Properties/launchSettings.json b/src/ikvmc/Properties/launchSettings.json new file mode 100644 index 000000000..150606624 --- /dev/null +++ b/src/ikvmc/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "ikvmc": { + "commandName": "Project", + "commandLineArgs": "@D:\\ikvm\\src\\IKVM.Java.Tests\\obj\\Debug\\net8.0\\IKVM.Java.Tests.ikvmc.rsp" + } + } +} \ No newline at end of file diff --git a/src/ikvmc/ikvmc.csproj b/src/ikvmc/ikvmc.csproj index 89cfd5c00..939ff4bbc 100644 --- a/src/ikvmc/ikvmc.csproj +++ b/src/ikvmc/ikvmc.csproj @@ -1,7 +1,7 @@  Exe - net472;net8.0;net6.0 + net8.0;net472;net6.0 $(_SupportedToolRuntimes) true true From 0f1f1be10a60c4fa9236f96ba0fb9df8e0b2edde Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Fri, 4 Oct 2024 17:12:26 -0500 Subject: [PATCH 25/51] Remove invoking base generic type definition for delegate invoke method. Instead, we now support GetMethod properly on the delegate type itself using _incompleteMethods. --- .../IkvmReflectionSymbolTests.cs | 24 +++++++++++++++++++ src/IKVM.Runtime/MethodHandleUtil.compiler.cs | 9 +------ 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs b/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs index 721eefcd6..0e7d5b5a8 100644 --- a/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs +++ b/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs @@ -472,6 +472,30 @@ public void CanGetMethodsFromTypeBuilder() incompleteMethod.Should().BeSameAs(method); } + [TestMethod] + public void CanGetGenericDelegateInvoke() + { + var c = new IkvmReflectionSymbolContext(universe!); + var a = c.DefineAssembly(new AssemblyNameInfo("DynamicAssembly")); + var m = a.DefineModule("DynamicModule", "DynamicModule.dll"); + + var tb = m.DefineType("DynamicGenericDelegate", System.Reflection.TypeAttributes.NotPublic | System.Reflection.TypeAttributes.Sealed, c.GetOrCreateTypeSymbol(coreAssembly!.GetType("System.MulticastDelegate"))); + var gtp = tb.DefineGenericParameters("T1"); + var mb = tb.DefineMethod("Invoke", System.Reflection.MethodAttributes.Public | System.Reflection.MethodAttributes.NewSlot | System.Reflection.MethodAttributes.Virtual, null, [gtp[0]]); + mb.SetImplementationFlags(System.Reflection.MethodImplAttributes.Runtime); + + var type = m.DefineType("DynamicType2"); + var method = type.DefineMethod("CallDelegate", System.Reflection.MethodAttributes.Public | System.Reflection.MethodAttributes.Static); + var il = method.GetILGenerator(); + il.Emit(System.Reflection.Emit.OpCodes.Ldind_I4, 0); + il.Emit(System.Reflection.Emit.OpCodes.Ldnull); + il.Emit(System.Reflection.Emit.OpCodes.Castclass, tb); + il.EmitCall(System.Reflection.Emit.OpCodes.Callvirt, mb, null); + + tb.Complete(); + type.Complete(); + } + } } diff --git a/src/IKVM.Runtime/MethodHandleUtil.compiler.cs b/src/IKVM.Runtime/MethodHandleUtil.compiler.cs index 606793ebf..b4e2f1d71 100644 --- a/src/IKVM.Runtime/MethodHandleUtil.compiler.cs +++ b/src/IKVM.Runtime/MethodHandleUtil.compiler.cs @@ -39,14 +39,7 @@ private void WrapArgs(CodeEmitter ilgen, ITypeSymbol type) internal IMethodSymbol GetDelegateInvokeMethod(ITypeSymbol delegateType) { - if (ReflectUtil.ContainsTypeBuilder(delegateType)) - { - return delegateType.GetGenericTypeDefinition().GetMethod("Invoke"); - } - else - { - return delegateType.GetMethod("Invoke"); - } + return delegateType.GetMethod("Invoke"); } internal IConstructorSymbol GetDelegateConstructor(ITypeSymbol delegateType) From dc36f8cff8eceb25ace9da29b56ea9009046644c Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Fri, 4 Oct 2024 17:16:40 -0500 Subject: [PATCH 26/51] Implment few more. --- .../Emit/IkvmReflectionTypeSymbolBuilder.cs | 15 ++++- .../Emit/ReflectionTypeSymbolBuilder.cs | 59 +++++++++++-------- 2 files changed, 46 insertions(+), 28 deletions(-) diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionTypeSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionTypeSymbolBuilder.cs index c59ad4507..babaa086a 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionTypeSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionTypeSymbolBuilder.cs @@ -730,19 +730,28 @@ public IMemberSymbol[] GetMembers() /// public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr) { - return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr)); + if (IsComplete) + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr)); + else + return GetIncompleteMethods(bindingAttr).FirstOrDefault(i => i.Name == name); } /// public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) { - return ResolveMethodSymbol(UnderlyingType.GetMethod(name, types.Unpack())); + if (IsComplete) + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, types.Unpack())); + else + throw new NotImplementedException(); } /// public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) { - return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), null)); + if (IsComplete) + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), null)); + else + throw new NotImplementedException(); } /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs index 7eede6c1d..31c468853 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs @@ -556,7 +556,7 @@ public int GetArrayRank() } /// - public IConstructorSymbol? GetConstructor(System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) + public IConstructorSymbol? GetConstructor(BindingFlags bindingAttr, ITypeSymbol[] types) { return ResolveConstructorSymbol(UnderlyingType.GetConstructor((BindingFlags)bindingAttr, binder: null, types.Unpack(), modifiers: null)); } @@ -574,7 +574,7 @@ public IConstructorSymbol[] GetConstructors() } /// - public IConstructorSymbol[] GetConstructors(System.Reflection.BindingFlags bindingAttr) + public IConstructorSymbol[] GetConstructors(BindingFlags bindingAttr) { return ResolveConstructorSymbols(UnderlyingType.GetConstructors((BindingFlags)bindingAttr)); } @@ -622,7 +622,7 @@ public Array GetEnumValues() } /// - public IEventSymbol? GetEvent(string name, System.Reflection.BindingFlags bindingAttr) + public IEventSymbol? GetEvent(string name, BindingFlags bindingAttr) { return ResolveEventSymbol(UnderlyingType.GetEvent(name, (BindingFlags)bindingAttr)); } @@ -634,7 +634,7 @@ public IEventSymbol[] GetEvents() } /// - public IEventSymbol[] GetEvents(System.Reflection.BindingFlags bindingAttr) + public IEventSymbol[] GetEvents(BindingFlags bindingAttr) { return ResolveEventSymbols(UnderlyingType.GetEvents((BindingFlags)bindingAttr)); } @@ -646,7 +646,7 @@ public IEventSymbol[] GetEvents(System.Reflection.BindingFlags bindingAttr) } /// - public IFieldSymbol? GetField(string name, System.Reflection.BindingFlags bindingAttr) + public IFieldSymbol? GetField(string name, BindingFlags bindingAttr) { return ResolveFieldSymbol(UnderlyingType.GetField(name, (BindingFlags)bindingAttr)); } @@ -658,7 +658,7 @@ public IFieldSymbol[] GetFields() } /// - public IFieldSymbol[] GetFields(System.Reflection.BindingFlags bindingAttr) + public IFieldSymbol[] GetFields(BindingFlags bindingAttr) { return ResolveFieldSymbols(UnderlyingType.GetFields((BindingFlags)bindingAttr)); } @@ -715,19 +715,19 @@ public IMemberSymbol[] GetMember(string name) } /// - public IMemberSymbol[] GetMember(string name, System.Reflection.BindingFlags bindingAttr) + public IMemberSymbol[] GetMember(string name, BindingFlags bindingAttr) { return ResolveMemberSymbols(UnderlyingType.GetMember(name, (BindingFlags)bindingAttr)); } /// - public IMemberSymbol[] GetMember(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) + public IMemberSymbol[] GetMember(string name, System.Reflection.MemberTypes type, BindingFlags bindingAttr) { return ResolveMemberSymbols(UnderlyingType.GetMember(name, (MemberTypes)type, (BindingFlags)bindingAttr)); } /// - public IMemberSymbol[] GetMembers(System.Reflection.BindingFlags bindingAttr) + public IMemberSymbol[] GetMembers(BindingFlags bindingAttr) { return ResolveMemberSymbols(UnderlyingType.GetMembers((BindingFlags)bindingAttr)); } @@ -739,21 +739,30 @@ public IMemberSymbol[] GetMembers() } /// - public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr) + public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr) { - return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr)); + if (IsComplete) + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, bindingAttr)); + else + return GetIncompleteMethods(bindingAttr).FirstOrDefault(i => i.Name == name); } /// public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) { - return ResolveMethodSymbol(UnderlyingType.GetMethod(name, types.Unpack())); + if (IsComplete) + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, types.Unpack())); + else + throw new NotImplementedException(); } /// - public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) + public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types) { - return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), null)); + if (IsComplete) + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, bindingAttr, null, types.Unpack(), null)); + else + throw new NotImplementedException(); } /// @@ -766,28 +775,28 @@ public IMemberSymbol[] GetMembers() } /// - public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers) { if (IsComplete) - return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, (CallingConventions)callConvention, types.Unpack(), modifiers?.Unpack())); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, bindingAttr, null, callConvention, types.Unpack(), modifiers?.Unpack())); else throw new NotImplementedException(); } /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers) { throw new NotImplementedException(); } /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { throw new NotImplementedException(); } /// - public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { if (IsComplete) return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), modifiers?.Unpack())); @@ -802,7 +811,7 @@ public IMemberSymbol[] GetMembers() } /// - public IMethodSymbol[] GetMethods(System.Reflection.BindingFlags bindingAttr) + public IMethodSymbol[] GetMethods(BindingFlags bindingAttr) { if (IsComplete) return ResolveMethodSymbols(UnderlyingType.GetMethods((BindingFlags)bindingAttr)); @@ -823,7 +832,7 @@ public IMethodSymbol[] GetMethods() /// Gets the set of incomplete methods. /// /// - IMethodSymbol[] GetIncompleteMethods(System.Reflection.BindingFlags bindingAttr = System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Instance) + IMethodSymbol[] GetIncompleteMethods(BindingFlags bindingAttr = BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance) { if (_incompleteMethods == null) return []; @@ -838,7 +847,7 @@ IMethodSymbol[] GetIncompleteMethods(System.Reflection.BindingFlags bindingAttr } /// - public ITypeSymbol? GetNestedType(string name, System.Reflection.BindingFlags bindingAttr) + public ITypeSymbol? GetNestedType(string name, BindingFlags bindingAttr) { return ResolveTypeSymbol(UnderlyingType.GetNestedType(name, (BindingFlags)bindingAttr)); } @@ -850,7 +859,7 @@ public ITypeSymbol[] GetNestedTypes() } /// - public ITypeSymbol[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr) + public ITypeSymbol[] GetNestedTypes(BindingFlags bindingAttr) { return ResolveTypeSymbols(UnderlyingType.GetNestedTypes((BindingFlags)bindingAttr)); } @@ -862,7 +871,7 @@ public IPropertySymbol[] GetProperties() } /// - public IPropertySymbol[] GetProperties(System.Reflection.BindingFlags bindingAttr) + public IPropertySymbol[] GetProperties(BindingFlags bindingAttr) { return ResolvePropertySymbols(UnderlyingType.GetProperties((BindingFlags)bindingAttr)); } @@ -880,7 +889,7 @@ public IPropertySymbol[] GetProperties(System.Reflection.BindingFlags bindingAtt } /// - public IPropertySymbol? GetProperty(string name, System.Reflection.BindingFlags bindingAttr) + public IPropertySymbol? GetProperty(string name, BindingFlags bindingAttr) { return ResolvePropertySymbol(UnderlyingType.GetProperty(name, (BindingFlags)bindingAttr)); } From 6667f5fd3e0dd12e45368f1b12803f185b4eeda0 Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Fri, 4 Oct 2024 17:19:34 -0500 Subject: [PATCH 27/51] Revert. --- .../java/lang/invoke/MethodHandleTests.java | 86 +++++++++++++------ 1 file changed, 61 insertions(+), 25 deletions(-) diff --git a/src/IKVM.Java.Tests/java/lang/invoke/MethodHandleTests.java b/src/IKVM.Java.Tests/java/lang/invoke/MethodHandleTests.java index 40b6ae0c4..422db2bc5 100644 --- a/src/IKVM.Java.Tests/java/lang/invoke/MethodHandleTests.java +++ b/src/IKVM.Java.Tests/java/lang/invoke/MethodHandleTests.java @@ -19,39 +19,75 @@ public static String addStringStatic(String a, String b) { } + interface AddItf { + void apply(List st, int idx, Object v) throws Throwable; + } + @cli.Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute.Annotation() - public void canInvokeExactVirtual() throws Throwable { - MethodHandles.Lookup lookup = getLookup(); - MethodType mt = getMethodType(); - MethodHandle mh = getMethodHandle(lookup, mt); - String s = invokeIt(mh); + public void canInvokeVirtual() throws Throwable { + MethodHandles.Lookup lookup = MethodHandles.lookup(); + MethodType mt = MethodType.methodType(String.class, String.class, String.class); + MethodHandle mh = lookup.findVirtual(TestClass.class, "addString", mt); + String s = (String)mh.invoke(new TestClass(), (Object)"a", (Object)"b"); if (!s.equals("ab")) { throw new Exception(s); } } - @cli.System.Runtime.CompilerServices.MethodImplAttribute.Annotation(value = cli.System.Runtime.CompilerServices.MethodImplOptions.__Enum.NoInlining) - MethodHandles.Lookup getLookup() throws Throwable - { - return MethodHandles.lookup(); + @cli.Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute.Annotation() + public void canInvokeStatic() throws Throwable { + MethodHandles.Lookup lookup = MethodHandles.lookup(); + MethodType mt = MethodType.methodType(String.class, String.class, String.class); + MethodHandle mh = lookup.findStatic(TestClass.class, "addStringStatic", mt); + String s = (String)mh.invoke((Object)"a", (Object)"b"); + if (!s.equals("ab")) { + throw new Exception(s); + } } - - @cli.System.Runtime.CompilerServices.MethodImplAttribute.Annotation(value = cli.System.Runtime.CompilerServices.MethodImplOptions.__Enum.NoInlining) - MethodType getMethodType() throws Throwable - { - return MethodType.methodType(String.class, String.class, String.class); + + @cli.Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute.Annotation() + public void canInvokeExactVirtual() throws Throwable { + MethodHandles.Lookup lookup = MethodHandles.lookup(); + MethodType mt = MethodType.methodType(String.class, String.class, String.class); + MethodHandle mh = lookup.findVirtual(TestClass.class, "addString", mt); + String s = (String)mh.invokeExact(new TestClass(), "a", "b"); + if (!s.equals("ab")) { + throw new Exception(s); + } } - - @cli.System.Runtime.CompilerServices.MethodImplAttribute.Annotation(value = cli.System.Runtime.CompilerServices.MethodImplOptions.__Enum.NoInlining) - MethodHandle getMethodHandle(MethodHandles.Lookup lookup, MethodType mt) throws Throwable - { - return lookup.findVirtual(TestClass.class, "addString", mt); + + @cli.Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute.Annotation() + public void canInvokeExactStatic() throws Throwable { + MethodHandles.Lookup lookup = MethodHandles.lookup(); + MethodType mt = MethodType.methodType(String.class, String.class, String.class); + MethodHandle mh = lookup.findStatic(TestClass.class, "addStringStatic", mt); + String s = (String)mh.invokeExact("a", "b"); + if (!s.equals("ab")) { + throw new Exception(s); + } } - - @cli.System.Runtime.CompilerServices.MethodImplAttribute.Annotation(value = cli.System.Runtime.CompilerServices.MethodImplOptions.__Enum.NoInlining) - String invokeIt(MethodHandle mh) throws Throwable - { - return (String)mh.invokeExact(new TestClass(), "a", "b"); + + @cli.Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute.Annotation() + public void canInvokeStaticMethodThatReturnsVoid() throws Throwable { + MethodHandles.Lookup lookup = MethodHandles.lookup(); + MethodType pmt = MethodType.methodType(void.class, int.class, Object.class); + MethodHandle pms = lookup.findVirtual(List.class, "add", pmt); + List list = new ArrayList<>(); + pms.invoke(list, 0, "Hi"); + AddItf pf2 = pms::invoke; + pf2.apply(list, 1, "there"); + AddItf pf3 = pms::invokeExact; + pf3.apply(list, 2, "you"); + + if (!list.get(0).equals("Hi")) { + throw new Exception(list.get(0)); + }; + if (!list.get(1).equals("there")) { + throw new Exception(list.get(1)); + }; + if (!list.get(2).equals("you")) { + throw new Exception(list.get(2)); + }; } -} +} \ No newline at end of file From 326cd18322516f0a9705158bd7215d13248ffcc9 Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Fri, 4 Oct 2024 19:53:14 -0500 Subject: [PATCH 28/51] Assert. Allow fileName to be null. --- .../Reflection/Emit/ReflectionAssemblySymbolBuilder.cs | 10 ++++++++-- src/IKVM.Runtime/RuntimeJavaType.cs | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs index 1ae5eba59..5d6469917 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs @@ -67,7 +67,10 @@ public IModuleSymbolBuilder DefineModule(string name) public IModuleSymbolBuilder DefineModule(string name, string fileName) { #if NETFRAMEWORK - return GetOrCreateModuleSymbol(UnderlyingAssemblyBuilder.DefineDynamicModule(name, fileName)); + if (fileName == null) + return GetOrCreateModuleSymbol(UnderlyingAssemblyBuilder.DefineDynamicModule(name)); + else + return GetOrCreateModuleSymbol(UnderlyingAssemblyBuilder.DefineDynamicModule(name, fileName)); #else return GetOrCreateModuleSymbol(UnderlyingAssemblyBuilder.DefineDynamicModule(name)); #endif @@ -77,7 +80,10 @@ public IModuleSymbolBuilder DefineModule(string name, string fileName) public IModuleSymbolBuilder DefineModule(string name, string fileName, bool emitSymbolInfo) { #if NETFRAMEWORK - return GetOrCreateModuleSymbol(UnderlyingAssemblyBuilder.DefineDynamicModule(name, fileName, emitSymbolInfo)); + if (fileName == null) + return GetOrCreateModuleSymbol(UnderlyingAssemblyBuilder.DefineDynamicModule(name, emitSymbolInfo)); + else + return GetOrCreateModuleSymbol(UnderlyingAssemblyBuilder.DefineDynamicModule(name, fileName, emitSymbolInfo)); #else return GetOrCreateModuleSymbol(UnderlyingAssemblyBuilder.DefineDynamicModule(name)); #endif diff --git a/src/IKVM.Runtime/RuntimeJavaType.cs b/src/IKVM.Runtime/RuntimeJavaType.cs index f09830f6c..abb8df974 100644 --- a/src/IKVM.Runtime/RuntimeJavaType.cs +++ b/src/IKVM.Runtime/RuntimeJavaType.cs @@ -1193,7 +1193,7 @@ internal static void AssertFinished(ITypeSymbol type) while (type.HasElementType) type = type.GetElementType(); - Debug.Assert(!(type.AsReflection() is TypeBuilder)); + Debug.Assert(type.IsComplete); } } From d3e85201ee4ca4c2d1bbeeea1d0680695d02ddf0 Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Sat, 5 Oct 2024 16:33:34 -0500 Subject: [PATCH 29/51] Rename AssemblyNameInfo to Assemblyidentity. Fix up some equality stuff. Remove DefineTypeInitializer from ReflectionUtil now that symbols do it. --- .../IkvmReflectionSymbolTests.cs | 4 +- .../Reflection/ReflectionSymbolTests.cs | 2 +- src/IKVM.CoreLib/IKVM.CoreLib.csproj | 3 +- src/IKVM.CoreLib/Symbols/AssemblyIdentity.cs | 308 ++++++++++++++++++ .../Symbols/AssemblyIdentityComparer.cs | 23 ++ .../Symbols/AssemblyNameFormatter.cs | 17 +- src/IKVM.CoreLib/Symbols/AssemblyNameInfo.cs | 159 --------- src/IKVM.CoreLib/Symbols/IAssemblySymbol.cs | 75 ++++- src/IKVM.CoreLib/Symbols/ISymbolContext.cs | 4 +- .../IkvmReflectionAssemblySymbolBuilder.cs | 4 +- .../IkvmReflectionAssemblySymbol.cs | 4 +- .../IkvmReflectionSymbolContext.cs | 4 +- .../IkvmReflection/IkvmReflectionUtil.cs | 73 +++-- .../Emit/ReflectionAssemblySymbolBuilder.cs | 4 +- .../Reflection/ReflectionAssemblySymbol.cs | 4 +- .../Reflection/ReflectionSymbolContext.cs | 4 +- .../Symbols/Reflection/ReflectionUtil.cs | 63 ++-- src/IKVM.CoreLib/Text/HexConverter.cs | 12 +- src/IKVM.Runtime/AttributeHelper.cs | 4 +- src/IKVM.Runtime/DynamicClassLoader.cs | 33 +- src/IKVM.Runtime/LambdaMetafactory.cs | 2 +- src/IKVM.Runtime/ReflectUtil.cs | 22 +- .../RuntimeAssemblyClassLoader.cs | 8 +- .../RuntimeByteCodeJavaType.FinishContext.cs | 2 +- .../RuntimeByteCodeJavaType.JavaTypeImpl.cs | 2 +- src/IKVM.Runtime/compiler.cs | 4 +- src/IKVM.Tools.Importer/ImportClassLoader.cs | 26 +- .../ImportContextFactory.cs | 2 +- src/IKVM.Tools.Importer/Proxy.cs | 2 +- 29 files changed, 558 insertions(+), 316 deletions(-) create mode 100644 src/IKVM.CoreLib/Symbols/AssemblyIdentity.cs create mode 100644 src/IKVM.CoreLib/Symbols/AssemblyIdentityComparer.cs delete mode 100644 src/IKVM.CoreLib/Symbols/AssemblyNameInfo.cs diff --git a/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs b/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs index 0e7d5b5a8..b827019c2 100644 --- a/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs +++ b/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs @@ -448,7 +448,7 @@ public void CanResolveMultipleEventBuilders() public void CanGetMethodsFromTypeBuilder() { var c = new IkvmReflectionSymbolContext(universe!); - var a = c.DefineAssembly(new AssemblyNameInfo("DynamicAssembly")); + var a = c.DefineAssembly(new AssemblyIdentity("DynamicAssembly")); var m = a.DefineModule("DynamicModule", "DynamicModule.dll"); var type = m.DefineType("DynamicType"); @@ -476,7 +476,7 @@ public void CanGetMethodsFromTypeBuilder() public void CanGetGenericDelegateInvoke() { var c = new IkvmReflectionSymbolContext(universe!); - var a = c.DefineAssembly(new AssemblyNameInfo("DynamicAssembly")); + var a = c.DefineAssembly(new AssemblyIdentity("DynamicAssembly")); var m = a.DefineModule("DynamicModule", "DynamicModule.dll"); var tb = m.DefineType("DynamicGenericDelegate", System.Reflection.TypeAttributes.NotPublic | System.Reflection.TypeAttributes.Sealed, c.GetOrCreateTypeSymbol(coreAssembly!.GetType("System.MulticastDelegate"))); diff --git a/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs b/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs index f0219bf6f..5c5bc6d2a 100644 --- a/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs +++ b/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs @@ -425,7 +425,7 @@ public void CanCompleteTypeBuilder() public void CanGetMethodsFromTypeBuilder() { var c = new ReflectionSymbolContext(); - var a = c.DefineAssembly(new AssemblyNameInfo("DynamicAssembly")); + var a = c.DefineAssembly(new AssemblyIdentity("DynamicAssembly")); var m = a.DefineModule("DynamicModule", "DynamicModule.dll"); var type = m.DefineType("DynamicType"); diff --git a/src/IKVM.CoreLib/IKVM.CoreLib.csproj b/src/IKVM.CoreLib/IKVM.CoreLib.csproj index 13d67775f..d61e8958e 100644 --- a/src/IKVM.CoreLib/IKVM.CoreLib.csproj +++ b/src/IKVM.CoreLib/IKVM.CoreLib.csproj @@ -24,10 +24,11 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + + diff --git a/src/IKVM.CoreLib/Symbols/AssemblyIdentity.cs b/src/IKVM.CoreLib/Symbols/AssemblyIdentity.cs new file mode 100644 index 000000000..3551bd310 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/AssemblyIdentity.cs @@ -0,0 +1,308 @@ +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Diagnostics; +using System.Linq; +using System.Reflection; +using System.Security.Cryptography; + +namespace IKVM.CoreLib.Symbols +{ + + /// + /// Represents an identity of an assembly as defined by CLI metadata specification. + /// + class AssemblyIdentity + { + + /// + /// Determines whether two instances are equal. + /// + /// The operand appearing on the left side of the operator. + /// The operand appearing on the right side of the operator. + public static bool operator ==(AssemblyIdentity? left, AssemblyIdentity? right) + { + return EqualityComparer.Default.Equals(left!, right!); + } + + /// + /// Determines whether two instances are not equal. + /// + /// The operand appearing on the left side of the operator. + /// The operand appearing on the right side of the operator. + public static bool operator !=(AssemblyIdentity? left, AssemblyIdentity? right) + { + return !(left == right); + } + + /// + /// Returns true (false) if specified assembly identities are (not) equal + /// regardless of unification, retargeting or other assembly binding policies. + /// Returns null if these policies must be consulted to determine name equivalence. + /// + public static bool? MemberwiseEqual(AssemblyIdentity x, AssemblyIdentity y) + { + if (ReferenceEquals(x, y)) + return true; + + if (!AssemblyIdentityComparer.SimpleNameComparer.Equals(x._name, y._name)) + return false; + + if (x._version.Equals(y._version) && EqualIgnoringNameAndVersion(x, y)) + return true; + + return null; + } + + /// + /// Returns true if the components of the assembly names, other than name and version, are equal. + /// + /// + /// + /// + public static bool EqualIgnoringNameAndVersion(AssemblyIdentity x, AssemblyIdentity y) + { + return x.ContentType == y.ContentType && AssemblyIdentityComparer.CultureComparer.Equals(x.CultureName, y.CultureName) && KeysEqual(x, y); + } + + /// + /// Returns true if the public keys of both identities are equal. + /// + /// + /// + /// + public static bool KeysEqual(AssemblyIdentity x, AssemblyIdentity y) + { + var xToken = x._publicKeyToken; + var yToken = y._publicKeyToken; + + // weak names or both strong names with initialized PKT - compare tokens: + if (!xToken.IsDefault && !yToken.IsDefault) + return xToken.SequenceEqual(yToken); + + // both are strong names with uninitialized PKT - compare full keys: + if (xToken.IsDefault && yToken.IsDefault) + return x._publicKey.SequenceEqual(y._publicKey); + + // one of the strong names doesn't have PK, other doesn't have PTK initialized. + if (xToken.IsDefault) + return x.PublicKeyToken.SequenceEqual(yToken); + else + return xToken.SequenceEqual(y.PublicKeyToken); + } + + /// + /// Initializes the publickey and publickeytoken values. + /// + /// + /// + /// + /// + static void InitializeKey(ImmutableArray publicKeyOrToken, bool hasPublicKey, out ImmutableArray publicKey, out ImmutableArray publicKeyToken) + { + if (hasPublicKey) + { + publicKey = publicKeyOrToken; + publicKeyToken = default; + } + else + { + publicKey = ImmutableArray.Empty; + publicKeyToken = publicKeyOrToken.IsDefault ? ImmutableArray.Empty : publicKeyOrToken; + } + } + + /// + /// Calculates the public key token from the given public key. + /// + /// + /// + static ImmutableArray CalculatePublicKeyToken(ImmutableArray publicKey) + { + var hash = SHA1.Create().ComputeHash(publicKey.ToArray()); + + // SHA1 hash is always 160 bits: + Debug.Assert(hash.Length == 20); + + // PublicKeyToken is the low 64 bits of the SHA-1 hash of the public key. + int l = hash.Length - 1; + var result = ImmutableArray.CreateBuilder(8); + for (int i = 0; i < 8; i++) + result.Add(hash[l - i]); + + return result.ToImmutable(); + } + + readonly string _name; + readonly Version _version; + readonly string? _cultureName; + readonly AssemblyContentType _contentType; + readonly ProcessorArchitecture _processorArchitecture; + + string? _fullName; + ImmutableArray _publicKey; + ImmutableArray _publicKeyToken; + int _hashCode = 0; + + /// + /// Initializes a new instance of the class. + /// + /// The simple name of the assembly. + /// The version of the assembly. + /// The name of the culture associated with the assembly. + /// The public key or its token. + /// is null. + public AssemblyIdentity(string name, Version? version = null, string? cultureName = null, ImmutableArray publicKeyOrToken = default, bool hasPublicKey = false, AssemblyContentType contentType = default, ProcessorArchitecture processorArchitecture = ProcessorArchitecture.None) + { + _name = name ?? throw new ArgumentNullException(nameof(name)); + _version = version ?? new Version(0, 0, 0, 0); + _cultureName = cultureName; + _contentType = contentType; + _processorArchitecture = processorArchitecture; + InitializeKey(publicKeyOrToken, hasPublicKey, out _publicKey, out _publicKeyToken); + } + + /// + /// Gets the simple name of the assembly. + /// + public string Name => _name; + + /// + /// Gets the version of the assembly. + /// + public Version? Version => _version; + + /// + /// Gets the name of the culture associated with the assembly. + /// + /// + /// Do not create a instance from this string unless + /// you know the string has originated from a trustworthy source. + /// + public string? CultureName => _cultureName; + + /// + /// Returns true if a public key is available. + /// + public bool HasPublicKey => _publicKey.Length > 0; + + /// + /// Gets the public key or the public key token of the assembly. + /// + public ImmutableArray PublicKey => _publicKey; + + /// + /// Low 8 bytes of SHA1 hash of the public key, or empty. + /// + public ImmutableArray PublicKeyToken + { + get + { + if (_publicKeyToken.IsDefault) + ImmutableInterlocked.InterlockedCompareExchange(ref _publicKeyToken, CalculatePublicKeyToken(_publicKey), default); + + return _publicKeyToken; + } + } + + /// + /// Gets the full name of the assembly, also known as the display name. + /// + /// In contrary to it does not validate public key token neither computes it based on the provided public key. + public string FullName => _fullName ??= AssemblyNameFormatter.ComputeDisplayName(Name, Version, CultureName, PublicKeyToken, Flags, ContentType, PublicKey); + + /// + /// Gets the . + /// + public AssemblyNameFlags Flags => HasPublicKey ? AssemblyNameFlags.PublicKey : AssemblyNameFlags.None; + + /// + /// Specifies the binding model for how this object will be treated in comparisons. + /// + public AssemblyContentType ContentType => _contentType; + + /// + /// Gets the processor architecture of the assembly name. + /// + public ProcessorArchitecture ProcessorArchitecture => _processorArchitecture; + + /// + /// True if the assembly identity has a strong name, ie. either a full public key or a token. + /// + public bool IsStrongName => HasPublicKey || _publicKeyToken.Length > 0; + + /// + /// Determines whether the specified instance is equal to the current instance. + /// + /// The object to be compared with the current instance. + public bool Equals(AssemblyIdentity? obj) + { + return !ReferenceEquals(obj, null) && (_hashCode == 0 || obj._hashCode == 0 || _hashCode == obj._hashCode) && MemberwiseEqual(this, obj) == true; + } + + /// + /// Determines whether the specified instance is equal to the current instance. + /// + /// The object to be compared with the current instance. + public override bool Equals(object? obj) + { + return Equals(obj as AssemblyIdentity); + } + + /// + /// Returns the hash code for the current instance. + /// + /// + public override int GetHashCode() + { + if (_hashCode == 0) + { + // Do not include PK/PKT in the hash - collisions on PK/PKT are rare (assembly identities differ only in PKT/PK) + // and we can't calculate hash of PKT if only PK is available + _hashCode = + HashCode.Combine(AssemblyIdentityComparer.SimpleNameComparer.GetHashCode(_name), + HashCode.Combine(_version?.GetHashCode(), GetHashCodeIgnoringNameAndVersion())); + } + + return _hashCode; + } + + /// + /// Gets the hashcode for this instance, without considering the name and version. + /// + /// + int GetHashCodeIgnoringNameAndVersion() + { + return HashCode.Combine((int)_contentType, AssemblyIdentityComparer.CultureComparer.GetHashCode(_cultureName ?? "")); + } + + /// + /// Initializes a new instance of the class based on the stored information. + /// + /// + /// Do not create an instance with string unless + /// you know the string has originated from a trustworthy source. + /// + public AssemblyName ToAssemblyName() + { + AssemblyName assemblyName = new(); + assemblyName.Name = Name; + assemblyName.CultureName = CultureName; + assemblyName.Version = Version; + assemblyName.Flags = Flags; + assemblyName.ContentType = ContentType; +#pragma warning disable SYSLIB0037 // Type or member is obsolete + assemblyName.ProcessorArchitecture = ProcessorArchitecture; +#pragma warning restore SYSLIB0037 // Type or member is obsolete + + if (HasPublicKey) + assemblyName.SetPublicKey(PublicKey.ToArray()); + else if (PublicKeyToken.IsDefaultOrEmpty == false) + assemblyName.SetPublicKeyToken(PublicKeyToken.ToArray()); + + return assemblyName; + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/AssemblyIdentityComparer.cs b/src/IKVM.CoreLib/Symbols/AssemblyIdentityComparer.cs new file mode 100644 index 000000000..a4727d08c --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/AssemblyIdentityComparer.cs @@ -0,0 +1,23 @@ +using System; + +namespace IKVM.CoreLib.Symbols +{ + + class AssemblyIdentityComparer + { + + public static AssemblyIdentityComparer Default { get; } = new AssemblyIdentityComparer(); + + public static StringComparer SimpleNameComparer + { + get { return StringComparer.OrdinalIgnoreCase; } + } + + public static StringComparer CultureComparer + { + get { return StringComparer.OrdinalIgnoreCase; } + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/AssemblyNameFormatter.cs b/src/IKVM.CoreLib/Symbols/AssemblyNameFormatter.cs index 08c41a9c6..60ff5b985 100644 --- a/src/IKVM.CoreLib/Symbols/AssemblyNameFormatter.cs +++ b/src/IKVM.CoreLib/Symbols/AssemblyNameFormatter.cs @@ -1,18 +1,21 @@ using System; +using System.Collections.Immutable; using System.Diagnostics; using System.Reflection; +using System.Security.Cryptography; using IKVM.CoreLib.Text; namespace IKVM.CoreLib.Symbols { - internal static class AssemblyNameFormatter + static class AssemblyNameFormatter { - public static string ComputeDisplayName(string name, Version? version, string? cultureName, byte[]? pkt, AssemblyNameFlags flags = 0, AssemblyContentType contentType = 0, byte[]? pk = null) + public static string ComputeDisplayName(string name, Version? version, string? cultureName, ImmutableArray pkt, AssemblyNameFlags flags, AssemblyContentType contentType, ImmutableArray pk) { const int PUBLIC_KEY_TOKEN_LEN = 8; + Debug.Assert(name.Length != 0); var vsb = new ValueStringBuilder(stackalloc char[256]); @@ -57,7 +60,7 @@ public static string ComputeDisplayName(string name, Version? version, string? c vsb.AppendQuoted(cultureName); } - byte[]? keyOrToken = pkt ?? pk; + var keyOrToken = pkt.IsDefaultOrEmpty == false ? pkt : pk; if (keyOrToken != null) { if (pkt != null) @@ -78,7 +81,7 @@ public static string ComputeDisplayName(string name, Version? version, string? c } else { - HexConverter.EncodeToUtf16(keyOrToken, vsb.AppendSpan(keyOrToken.Length * 2), HexConverter.Casing.Lower); + HexConverter.EncodeToUtf16(keyOrToken.AsSpan(), vsb.AppendSpan(keyOrToken.Length * 2), HexConverter.Casing.Lower); } } @@ -88,12 +91,10 @@ public static string ComputeDisplayName(string name, Version? version, string? c if (contentType == AssemblyContentType.WindowsRuntime) vsb.Append(", ContentType=WindowsRuntime"); - // NOTE: By design (desktop compat) AssemblyName.FullName and ToString() do not include ProcessorArchitecture. - return vsb.ToString(); } - private static void AppendQuoted(this ref ValueStringBuilder vsb, string s) + static void AppendQuoted(this ref ValueStringBuilder vsb, string s) { bool needsQuoting = false; const char quoteChar = '\"'; @@ -136,7 +137,7 @@ private static void AppendQuoted(this ref ValueStringBuilder vsb, string s) vsb.Append(quoteChar); } - private static void AppendSpanFormattable(this ref ValueStringBuilder vsb, ushort value) + static void AppendSpanFormattable(this ref ValueStringBuilder vsb, ushort value) { vsb.Append(value.ToString()); } diff --git a/src/IKVM.CoreLib/Symbols/AssemblyNameInfo.cs b/src/IKVM.CoreLib/Symbols/AssemblyNameInfo.cs deleted file mode 100644 index b92ecd28f..000000000 --- a/src/IKVM.CoreLib/Symbols/AssemblyNameInfo.cs +++ /dev/null @@ -1,159 +0,0 @@ -using System; -using System.Collections.Immutable; -using System.Diagnostics.CodeAnalysis; -using System.Linq; -using System.Reflection; - -namespace IKVM.CoreLib.Symbols -{ - - class AssemblyNameInfo - { - - readonly AssemblyNameFlags _flags; - string? _fullName; - - /// - /// Initializes a new instance of the AssemblyNameInfo class. - /// - /// The simple name of the assembly. - /// The version of the assembly. - /// The name of the culture associated with the assembly. - /// The attributes of the assembly. - /// The public key or its token. Set to when it's public key. - /// is null. - public AssemblyNameInfo(string name, Version? version = null, string? cultureName = null, AssemblyNameFlags flags = AssemblyNameFlags.None, ImmutableArray publicKeyOrToken = default) - { - Name = name ?? throw new ArgumentNullException(nameof(name)); - Version = version; - CultureName = cultureName; - _flags = flags; - PublicKeyOrToken = publicKeyOrToken; - } - - /// - /// Gets the simple name of the assembly. - /// - public string Name { get; } - - /// - /// Gets the version of the assembly. - /// - public Version? Version { get; } - - /// - /// Gets the name of the culture associated with the assembly. - /// - /// - /// Do not create a instance from this string unless - /// you know the string has originated from a trustworthy source. - /// - public string? CultureName { get; } - - /// - /// Gets the attributes of the assembly. - /// - public AssemblyNameFlags Flags => _flags; - - /// - /// Gets the public key or the public key token of the assembly. - /// - /// Check for flag to see whether it's public key or its token. -#if SYSTEM_PRIVATE_CORELIB - public byte[]? PublicKeyOrToken { get; } -#else - public ImmutableArray PublicKeyOrToken { get; } -#endif - - - /// - /// Gets the full name of the assembly, also known as the display name. - /// - /// In contrary to it does not validate public key token neither computes it based on the provided public key. - public string FullName - { - get - { - if (_fullName is null) - { - bool isPublicKey = (Flags & AssemblyNameFlags.PublicKey) != 0; - - byte[]? publicKeyOrToken = -#if SYSTEM_PRIVATE_CORELIB - PublicKeyOrToken; -#elif NET8_0_OR_GREATER - !PublicKeyOrToken.IsDefault ? System.Runtime.InteropServices.ImmutableCollectionsMarshal.AsArray(PublicKeyOrToken) : null; -#else - !PublicKeyOrToken.IsDefault ? PublicKeyOrToken.ToArray() : null; -#endif - _fullName = AssemblyNameFormatter.ComputeDisplayName(Name, Version, CultureName, - pkt: isPublicKey ? null : publicKeyOrToken, - ExtractAssemblyNameFlags(_flags), ExtractAssemblyContentType(_flags), - pk: isPublicKey ? publicKeyOrToken : null); - } - - return _fullName; - } - } - - /// - /// Initializes a new instance of the class based on the stored information. - /// - /// - /// Do not create an instance with string unless - /// you know the string has originated from a trustworthy source. - /// - public AssemblyName ToAssemblyName() - { - AssemblyName assemblyName = new(); - assemblyName.Name = Name; - assemblyName.CultureName = CultureName; - assemblyName.Version = Version; - assemblyName.Flags = Flags; - assemblyName.ContentType = ExtractAssemblyContentType(_flags); -#pragma warning disable SYSLIB0037 // Type or member is obsolete - assemblyName.ProcessorArchitecture = ExtractProcessorArchitecture(_flags); -#pragma warning restore SYSLIB0037 // Type or member is obsolete - -#if SYSTEM_PRIVATE_CORELIB - if (PublicKeyOrToken is not null) - { - if ((Flags & AssemblyNameFlags.PublicKey) != 0) - { - assemblyName.SetPublicKey(PublicKeyOrToken); - } - else - { - assemblyName.SetPublicKeyToken(PublicKeyOrToken); - } - } -#else - if (!PublicKeyOrToken.IsDefault) - { - // A copy of the array needs to be created, as AssemblyName allows for the mutation of provided array. - if ((Flags & AssemblyNameFlags.PublicKey) != 0) - { - assemblyName.SetPublicKey(PublicKeyOrToken.ToArray()); - } - else - { - assemblyName.SetPublicKeyToken(PublicKeyOrToken.ToArray()); - } - } -#endif - - return assemblyName; - } - - internal static AssemblyNameFlags ExtractAssemblyNameFlags(AssemblyNameFlags combinedFlags) - => combinedFlags & unchecked((AssemblyNameFlags)0xFFFFF10F); - - internal static AssemblyContentType ExtractAssemblyContentType(AssemblyNameFlags flags) - => (AssemblyContentType)((((int)flags) >> 9) & 0x7); - - internal static ProcessorArchitecture ExtractProcessorArchitecture(AssemblyNameFlags flags) - => (ProcessorArchitecture)((((int)flags) >> 4) & 0x7); - - } - -} diff --git a/src/IKVM.CoreLib/Symbols/IAssemblySymbol.cs b/src/IKVM.CoreLib/Symbols/IAssemblySymbol.cs index 17fecec18..dbdfb9eef 100644 --- a/src/IKVM.CoreLib/Symbols/IAssemblySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IAssemblySymbol.cs @@ -4,13 +4,20 @@ namespace IKVM.CoreLib.Symbols { + /// + /// Represents an assembly, which is a reusable, versionable, and self-describing building block of a common language runtime application. + /// interface IAssemblySymbol : ISymbol, ICustomAttributeProvider { + /// + /// Gets a collection of the types defined in this assembly. + /// IEnumerable DefinedTypes { get; } - IMethodSymbol? EntryPoint { get; } - + /// + /// Gets a collection of the public types defined in this assembly that are visible outside the assembly. + /// IEnumerable ExportedTypes { get; } /// @@ -33,6 +40,9 @@ interface IAssemblySymbol : ISymbol, ICustomAttributeProvider /// IModuleSymbol ManifestModule { get; } + /// + /// Gets a collection that contains the modules in this assembly. + /// IEnumerable Modules { get; } /// @@ -57,34 +67,79 @@ interface IAssemblySymbol : ISymbol, ICustomAttributeProvider /// Stream? GetManifestResourceStream(ITypeSymbol type, string name); - ITypeSymbol[] GetExportedTypes(); - + /// + /// Gets the specified module in this assembly. + /// + /// + /// IModuleSymbol? GetModule(string name); + /// + /// Gets all the modules that are part of this assembly. + /// + /// IModuleSymbol[] GetModules(); + /// + /// Gets all the modules that are part of this assembly, specifying whether to include resource modules. + /// + /// + /// IModuleSymbol[] GetModules(bool getResourceModules); /// - /// Gets an for this assembly. + /// Gets an for this assembly. + /// + /// + AssemblyIdentity GetIdentity(); + + /// + /// Gets the objects for all the assemblies referenced by this assembly. /// /// - AssemblyNameInfo GetName(); + AssemblyIdentity[] GetReferencedAssemblies(); /// - /// Gets the objects for all the assemblies referenced by this assembly. + /// Gets the Type object with the specified name in the assembly instance. /// + /// /// - AssemblyNameInfo[] GetReferencedAssemblies(); + ITypeSymbol? GetType(string name); + /// + /// Gets the object with the specified name in the assembly instance and optionally throws an exception if the type is not found. + /// + /// + /// + /// ITypeSymbol? GetType(string name, bool throwOnError); + /// + /// Gets the object with the specified name in the assembly instance, with the options of ignoring the case, and of throwing an exception if the type is not found. + /// + /// + /// + /// + /// ITypeSymbol? GetType(string name, bool throwOnError, bool ignoreCase); - ITypeSymbol? GetType(string name); - + /// + /// Gets all types defined in this assembly. + /// + /// ITypeSymbol[] GetTypes(); + /// + /// Gets the public types defined in this assembly that are visible outside the assembly. + /// + /// + ITypeSymbol[] GetExportedTypes(); + + /// + /// Gets the entry point of this assembly. + /// + IMethodSymbol? EntryPoint { get; } + } } \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/ISymbolContext.cs b/src/IKVM.CoreLib/Symbols/ISymbolContext.cs index 37440c21b..32910c189 100644 --- a/src/IKVM.CoreLib/Symbols/ISymbolContext.cs +++ b/src/IKVM.CoreLib/Symbols/ISymbolContext.cs @@ -14,14 +14,14 @@ interface ISymbolContext /// /// /// - IAssemblySymbolBuilder DefineAssembly(AssemblyNameInfo name); + IAssemblySymbolBuilder DefineAssembly(AssemblyIdentity name); /// /// Defines a dynamic assembly that has the specified name and access rights. /// /// /// - IAssemblySymbolBuilder DefineAssembly(AssemblyNameInfo name, ICustomAttributeBuilder[]? assemblyAttributes); + IAssemblySymbolBuilder DefineAssembly(AssemblyIdentity name, ICustomAttributeBuilder[]? assemblyAttributes); /// /// Initializes an instance of the interface given the constructor for the custom attribute and the arguments to the constructor. diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionAssemblySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionAssemblySymbolBuilder.cs index 0d876aa82..8145099b2 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionAssemblySymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionAssemblySymbolBuilder.cs @@ -190,13 +190,13 @@ public IModuleSymbol[] GetModules(bool getResourceModules) } /// - public AssemblyNameInfo GetName() + public AssemblyIdentity GetIdentity() { return UnderlyingAssembly.GetName().Pack(); } /// - public AssemblyNameInfo[] GetReferencedAssemblies() + public AssemblyIdentity[] GetReferencedAssemblies() { return UnderlyingAssembly.GetReferencedAssemblies().Pack(); } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs index 2feec1bc0..3af8e7726 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs @@ -96,13 +96,13 @@ public IModuleSymbol[] GetModules(bool getResourceModules) } /// - public AssemblyNameInfo GetName() + public AssemblyIdentity GetIdentity() { return UnderlyingAssembly.GetName().Pack(); } /// - public AssemblyNameInfo[] GetReferencedAssemblies() + public AssemblyIdentity[] GetReferencedAssemblies() { return UnderlyingAssembly.GetReferencedAssemblies().Pack(); } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolContext.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolContext.cs index 4cc41b20b..56a561339 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolContext.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolContext.cs @@ -32,7 +32,7 @@ public IkvmReflectionSymbolContext(Universe universe) } /// - public IAssemblySymbolBuilder DefineAssembly(AssemblyNameInfo name) + public IAssemblySymbolBuilder DefineAssembly(AssemblyIdentity name) { if (name is null) throw new ArgumentNullException(nameof(name)); @@ -41,7 +41,7 @@ public IAssemblySymbolBuilder DefineAssembly(AssemblyNameInfo name) } /// - public IAssemblySymbolBuilder DefineAssembly(AssemblyNameInfo name, ICustomAttributeBuilder[]? assemblyAttributes) + public IAssemblySymbolBuilder DefineAssembly(AssemblyIdentity name, ICustomAttributeBuilder[]? assemblyAttributes) { if (name is null) throw new ArgumentNullException(nameof(name)); diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionUtil.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionUtil.cs index 5898b55e8..600292ba8 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionUtil.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionUtil.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Immutable; +using System.Linq; using IKVM.CoreLib.Symbols.Emit; using IKVM.CoreLib.Symbols.IkvmReflection.Emit; @@ -15,61 +16,79 @@ static class IkvmReflectionUtil { /// - /// Converts a to a . + /// Converts a to a . /// /// /// - public static AssemblyNameInfo Pack(this AssemblyName n) + public static AssemblyIdentity Pack(this AssemblyName assemblyName) { - return new AssemblyNameInfo(n.Name, n.Version, n.CultureName, (System.Reflection.AssemblyNameFlags)n.Flags, n.GetPublicKeyToken()?.ToImmutableArray() ?? ImmutableArray.Empty); + var pk = assemblyName.GetPublicKey()?.ToImmutableArray() ?? ImmutableArray.Empty; + var hasPublicKey = pk.Length > 0; + var pkt = assemblyName.GetPublicKeyToken()?.ToImmutableArray() ?? ImmutableArray.Empty; + + return new AssemblyIdentity( + assemblyName.Name ?? throw new InvalidOperationException(), + assemblyName.Version, + assemblyName.CultureName, + hasPublicKey ? pk : pkt, + hasPublicKey, + (System.Reflection.AssemblyContentType)assemblyName.ContentType, + (System.Reflection.ProcessorArchitecture)assemblyName.ProcessorArchitecture); } /// - /// Converts a set of to a set of . + /// Converts a set of to a set of . /// - /// + /// /// - public static AssemblyNameInfo[] Pack(this AssemblyName[] n) + public static AssemblyIdentity[] Pack(this AssemblyName[] assemblyNames) { - if (n.Length == 0) + if (assemblyNames.Length == 0) return []; - var a = new AssemblyNameInfo[n.Length]; - for (int i = 0; i < n.Length; i++) - a[i] = n[i].Pack(); + var a = new AssemblyIdentity[assemblyNames.Length]; + for (int i = 0; i < assemblyNames.Length; i++) + a[i] = assemblyNames[i].Pack(); return a; } /// - /// Converts a to a . + /// Converts a to a . /// - /// + /// /// - public static AssemblyName Unpack(this AssemblyNameInfo n) + public static AssemblyName Unpack(this AssemblyIdentity assemblyNameInfo) { - return new AssemblyName() - { - Name = n.Name, - Version = n.Version, - CultureName = n.CultureName, - Flags = (AssemblyNameFlags)n.Flags, - }; + AssemblyName assemblyName = new(); + assemblyName.Name = assemblyNameInfo.Name; + assemblyName.CultureName = assemblyNameInfo.CultureName; + assemblyName.Version = assemblyNameInfo.Version; + assemblyName.Flags = (AssemblyNameFlags)assemblyNameInfo.Flags; + assemblyName.ContentType = (AssemblyContentType)assemblyNameInfo.ContentType; + assemblyName.ProcessorArchitecture = (ProcessorArchitecture)assemblyNameInfo.ProcessorArchitecture; + + if (assemblyNameInfo.HasPublicKey) + assemblyName.SetPublicKey(assemblyNameInfo.PublicKey.ToArray()); + else if (assemblyNameInfo.PublicKeyToken.IsDefaultOrEmpty == false) + assemblyName.SetPublicKeyToken(assemblyNameInfo.PublicKeyToken.ToArray()); + + return assemblyName; } /// - /// Converts a set of to a set of . + /// Converts a set of to a set of . /// - /// + /// /// - public static AssemblyName[] Unpack(this AssemblyNameInfo[] n) + public static AssemblyName[] Unpack(this AssemblyIdentity[] assemblyNameInfos) { - if (n.Length == 0) + if (assemblyNameInfos.Length == 0) return []; - var a = new AssemblyName[n.Length]; - for (int i = 0; i < n.Length; i++) - a[i] = n[i].Unpack(); + var a = new AssemblyName[assemblyNameInfos.Length]; + for (int i = 0; i < assemblyNameInfos.Length; i++) + a[i] = assemblyNameInfos[i].Unpack(); return a; } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs index 5d6469917..c5d085a52 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs @@ -216,13 +216,13 @@ public IModuleSymbol[] GetModules(bool getResourceModules) } /// - public AssemblyNameInfo GetName() + public AssemblyIdentity GetIdentity() { return UnderlyingAssembly.GetName().Pack(); } /// - public AssemblyNameInfo[] GetReferencedAssemblies() + public AssemblyIdentity[] GetReferencedAssemblies() { return UnderlyingAssembly.GetReferencedAssemblies().Pack(); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs index f589ea11d..7496acfff 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs @@ -92,13 +92,13 @@ public IModuleSymbol[] GetModules(bool getResourceModules) } /// - public AssemblyNameInfo GetName() + public AssemblyIdentity GetIdentity() { return UnderlyingAssembly.GetName().Pack(); } /// - public AssemblyNameInfo[] GetReferencedAssemblies() + public AssemblyIdentity[] GetReferencedAssemblies() { return UnderlyingAssembly.GetReferencedAssemblies().Pack(); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs index 1b876eb33..b435aa903 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs @@ -29,7 +29,7 @@ public ReflectionSymbolContext() } /// - public IAssemblySymbolBuilder DefineAssembly(AssemblyNameInfo name) + public IAssemblySymbolBuilder DefineAssembly(AssemblyIdentity name) { if (name is null) throw new ArgumentNullException(nameof(name)); @@ -42,7 +42,7 @@ public IAssemblySymbolBuilder DefineAssembly(AssemblyNameInfo name) } /// - public IAssemblySymbolBuilder DefineAssembly(AssemblyNameInfo name, ICustomAttributeBuilder[]? assemblyAttributes) + public IAssemblySymbolBuilder DefineAssembly(AssemblyIdentity name, ICustomAttributeBuilder[]? assemblyAttributes) { if (name is null) throw new ArgumentNullException(nameof(name)); diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionUtil.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionUtil.cs index 2a8426e22..5a19f7b9a 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionUtil.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionUtil.cs @@ -13,61 +13,68 @@ static class ReflectionUtil { /// - /// Converts a to a . + /// Converts a to a . /// - /// + /// /// - public static AssemblyNameInfo Pack(this AssemblyName n) + public static AssemblyIdentity Pack(this AssemblyName assemblyName) { - return new AssemblyNameInfo(n.Name ?? throw new InvalidOperationException(), n.Version, n.CultureName, n.Flags, n.GetPublicKeyToken()?.ToImmutableArray() ?? ImmutableArray.Empty); + var pk = assemblyName.GetPublicKey()?.ToImmutableArray() ?? ImmutableArray.Empty; + var hasPublicKey = pk.Length > 0; + var pkt = assemblyName.GetPublicKeyToken()?.ToImmutableArray() ?? ImmutableArray.Empty; + +#pragma warning disable SYSLIB0037 // Type or member is obsolete + return new AssemblyIdentity( + assemblyName.Name ?? throw new InvalidOperationException(), + assemblyName.Version, + assemblyName.CultureName, + hasPublicKey ? pk : pkt, + hasPublicKey, + assemblyName.ContentType, + assemblyName.ProcessorArchitecture); +#pragma warning restore SYSLIB0037 // Type or member is obsolete } /// - /// Converts a set of to a set of . + /// Converts a set of to a set of . /// - /// + /// /// - public static AssemblyNameInfo[] Pack(this AssemblyName[] n) + public static AssemblyIdentity[] Pack(this AssemblyName[] assemblyNames) { - if (n.Length == 0) + if (assemblyNames.Length == 0) return []; - var a = new AssemblyNameInfo[n.Length]; - for (int i = 0; i < n.Length; i++) - a[i] = n[i].Pack(); + var a = new AssemblyIdentity[assemblyNames.Length]; + for (int i = 0; i < assemblyNames.Length; i++) + a[i] = assemblyNames[i].Pack(); return a; } /// - /// Converts a to a . + /// Converts a to a . /// - /// + /// /// - public static AssemblyName Unpack(this AssemblyNameInfo n) + public static AssemblyName Unpack(this AssemblyIdentity assemblyNameInfo) { - return new AssemblyName() - { - Name = n.Name, - Version = n.Version, - CultureName = n.CultureName, - Flags = (AssemblyNameFlags)n.Flags, - }; + return assemblyNameInfo.ToAssemblyName(); } /// - /// Converts a set of to a set of . + /// Converts a set of to a set of . /// - /// + /// /// - public static AssemblyName[] Unpack(this AssemblyNameInfo[] n) + public static AssemblyName[] Unpack(this AssemblyIdentity[] assemblyNameInfos) { - if (n.Length == 0) + if (assemblyNameInfos.Length == 0) return []; - var a = new AssemblyName[n.Length]; - for (int i = 0; i < n.Length; i++) - a[i] = n[i].Unpack(); + var a = new AssemblyName[assemblyNameInfos.Length]; + for (int i = 0; i < assemblyNameInfos.Length; i++) + a[i] = assemblyNameInfos[i].Unpack(); return a; } diff --git a/src/IKVM.CoreLib/Text/HexConverter.cs b/src/IKVM.CoreLib/Text/HexConverter.cs index 504f43238..2b9c0aad0 100644 --- a/src/IKVM.CoreLib/Text/HexConverter.cs +++ b/src/IKVM.CoreLib/Text/HexConverter.cs @@ -159,13 +159,6 @@ public static void EncodeToUtf16(ReadOnlySpan bytes, Span chars, Cas { Debug.Assert(chars.Length >= bytes.Length * 2); -#if SYSTEM_PRIVATE_CORELIB - if ((AdvSimd.Arm64.IsSupported || Ssse3.IsSupported) && bytes.Length >= 4) - { - EncodeToUtf16_Vector128(bytes, chars, casing); - return; - } -#endif for (int pos = 0; pos < bytes.Length; pos++) { ToCharsBuffer(bytes[pos], chars, pos * 2, casing); @@ -175,9 +168,7 @@ public static void EncodeToUtf16(ReadOnlySpan bytes, Span chars, Cas public static unsafe string ToString(ReadOnlySpan bytes, Casing casing = Casing.Upper) { #if NETFRAMEWORK || NETSTANDARD2_0 - Span result = bytes.Length > 16 ? - new char[bytes.Length * 2].AsSpan() : - stackalloc char[bytes.Length * 2]; + var result = bytes.Length > 16 ? new char[bytes.Length * 2].AsSpan() : stackalloc char[bytes.Length * 2]; int pos = 0; foreach (byte b in bytes) @@ -185,6 +176,7 @@ public static unsafe string ToString(ReadOnlySpan bytes, Casing casing = C ToCharsBuffer(b, result, pos, casing); pos += 2; } + return result.ToString(); #else return string.Create(bytes.Length * 2, (RosPtr: (IntPtr)(&bytes), casing), static (chars, args) => diff --git a/src/IKVM.Runtime/AttributeHelper.cs b/src/IKVM.Runtime/AttributeHelper.cs index 46f8e86aa..36bd449d0 100644 --- a/src/IKVM.Runtime/AttributeHelper.cs +++ b/src/IKVM.Runtime/AttributeHelper.cs @@ -1015,9 +1015,9 @@ internal string GetAnnotationAttributeType(ITypeSymbol type) return null; } - internal AssemblyNameInfo[] GetInternalsVisibleToAttributes(IAssemblySymbol assembly) + internal AssemblyIdentity[] GetInternalsVisibleToAttributes(IAssemblySymbol assembly) { - var list = new List(); + var list = new List(); foreach (var cad in assembly.GetCustomAttributes()) { diff --git a/src/IKVM.Runtime/DynamicClassLoader.cs b/src/IKVM.Runtime/DynamicClassLoader.cs index 3feb88869..9280aba81 100644 --- a/src/IKVM.Runtime/DynamicClassLoader.cs +++ b/src/IKVM.Runtime/DynamicClassLoader.cs @@ -33,7 +33,8 @@ Jeroen Frijters using static System.Diagnostics.DebuggableAttribute; -using System.Collections.Immutable; +using IKVM.CoreLib.Symbols.Reflection; + #if IMPORTER @@ -135,18 +136,24 @@ public DynamicClassLoader GetOrCreate(RuntimeClassLoader loader) // each assembly class loader gets its own dynamic class loader if (loader is RuntimeAssemblyClassLoader acl) { - var name = acl.MainAssembly.GetName().Name + context.Options.DynamicAssemblySuffixAndPublicKey; - foreach (var attr in acl.MainAssembly.AsReflection().GetCustomAttributes()) + // search for the InternalsVisibleToAttribute on the assembly that specifies the dynamic assembly name + // the name may have a public key suffix for Framework + var internalsVisibleToAttribute = context.Resolver.ResolveCoreType(typeof(InternalsVisibleToAttribute).FullName); + var internalsVisibleToName = acl.MainAssembly.GetIdentity().Name + context.Options.DynamicAssemblySuffixAndPublicKey; + + foreach (var attr in acl.MainAssembly.GetCustomAttributes(internalsVisibleToAttribute)) { - if (attr.AssemblyName == name) + var attributeConstructorArgValue = (string)attr.ConstructorArguments[0].Value; + if (attributeConstructorArgValue == internalsVisibleToName) { - byte[] kp = []; + var kp = Array.Empty(); #if NETFRAMEWORK kp = DynamicClassLoader.ForgedKeyPair.Instance.PublicKey; #endif - - var n = new AssemblyNameInfo(name, publicKeyOrToken: kp.ToImmutableArray()); - return new DynamicClassLoader(context, loader.Diagnostics, DynamicClassLoader.CreateModuleBuilder(context, n), true); + // desired assembly name, which may contain token + var assemblyName = new AssemblyName(internalsVisibleToName); + assemblyName.SetPublicKey(kp); + return new DynamicClassLoader(context, loader.Diagnostics, DynamicClassLoader.CreateModuleBuilder(context, assemblyName.Pack()), true); } } } @@ -447,7 +454,7 @@ internal void FinishAll() internal static IModuleSymbolBuilder CreateJniProxyModuleBuilder(RuntimeContext context) { - jniProxyAssemblyBuilder = DefineDynamicAssembly(context, new AssemblyNameInfo("jniproxy"), null); + jniProxyAssemblyBuilder = DefineDynamicAssembly(context, new AssemblyIdentity("jniproxy"), null); return jniProxyAssemblyBuilder.DefineModule("jniproxy.dll"); } @@ -519,13 +526,13 @@ private static SerializationInfo ToInfo(byte[] publicKey) public static IModuleSymbolBuilder CreateModuleBuilder(RuntimeContext context) { - return CreateModuleBuilder(context, new AssemblyNameInfo("ikvm_dynamic_assembly__" + (uint)Environment.TickCount)); + return CreateModuleBuilder(context, new AssemblyIdentity("ikvm_dynamic_assembly__" + (uint)Environment.TickCount)); } - public static IModuleSymbolBuilder CreateModuleBuilder(RuntimeContext context, AssemblyNameInfo name) + public static IModuleSymbolBuilder CreateModuleBuilder(RuntimeContext context, AssemblyIdentity name) { var now = DateTime.Now; - name = new AssemblyNameInfo(name.Name, new Version(now.Year, (now.Month * 100) + now.Day, (now.Hour * 100) + now.Minute, (now.Second * 1000) + now.Millisecond)); + name = new AssemblyIdentity(name.Name, new Version(now.Year, (now.Month * 100) + now.Day, (now.Hour * 100) + now.Minute, (now.Second * 1000) + now.Millisecond)); var attribs = new List(); #if NETFRAMEWORK @@ -549,7 +556,7 @@ public static IModuleSymbolBuilder CreateModuleBuilder(RuntimeContext context, A return moduleBuilder; } - static IAssemblySymbolBuilder DefineDynamicAssembly(RuntimeContext context, AssemblyNameInfo name, ICustomAttributeBuilder[] assemblyAttributes) + static IAssemblySymbolBuilder DefineDynamicAssembly(RuntimeContext context, AssemblyIdentity name, ICustomAttributeBuilder[] assemblyAttributes) { return context.Resolver.Symbols.DefineAssembly(name, assemblyAttributes); } diff --git a/src/IKVM.Runtime/LambdaMetafactory.cs b/src/IKVM.Runtime/LambdaMetafactory.cs index 6b8847200..e36d89bfd 100644 --- a/src/IKVM.Runtime/LambdaMetafactory.cs +++ b/src/IKVM.Runtime/LambdaMetafactory.cs @@ -441,7 +441,7 @@ private static IMethodSymbolBuilder CreateConstructorAndDispatch(RuntimeByteCode var instField = tb.DefineField("inst", tb, FieldAttributes.Private | FieldAttributes.Static); // static constructor - var cctor = ReflectUtil.DefineTypeInitializer(tb, context.TypeWrapper.ClassLoader); + var cctor = tb.DefineTypeInitializer(); var ilgenCCtor = context.Context.CodeEmitterFactory.Create(cctor); ilgenCCtor.Emit(OpCodes.Newobj, ctor); ilgenCCtor.Emit(OpCodes.Stsfld, instField); diff --git a/src/IKVM.Runtime/ReflectUtil.cs b/src/IKVM.Runtime/ReflectUtil.cs index a87e8132c..2259bc065 100644 --- a/src/IKVM.Runtime/ReflectUtil.cs +++ b/src/IKVM.Runtime/ReflectUtil.cs @@ -121,26 +121,18 @@ internal static bool IsDynamicMethod(IMethodSymbol method) } } - internal static IConstructorSymbolBuilder DefineTypeInitializer(ITypeSymbolBuilder typeBuilder, RuntimeClassLoader loader) - { - return typeBuilder.DefineTypeInitializer(); - } - - internal static bool MatchNameAndPublicKeyToken(AssemblyNameInfo name1, AssemblyNameInfo name2) - { - return name1.Name.Equals(name2.Name, StringComparison.OrdinalIgnoreCase) && CompareKeys(name1.PublicKeyOrToken, name2.PublicKeyOrToken); - } - - static bool CompareKeys(ImmutableArray b1, ImmutableArray b2) - { - return b1.AsSpan().SequenceEqual(b2.AsSpan()); - } - internal static bool IsConstructor(IMethodBaseSymbol method) { return method.IsSpecialName && method.Name == ConstructorInfo.ConstructorName; } + /// + /// Defines a constructor. + /// + /// + /// + /// + /// internal static IConstructorSymbolBuilder DefineConstructor(ITypeSymbolBuilder tb, System.Reflection.MethodAttributes attribs, ITypeSymbol[] parameterTypes) { return tb.DefineConstructor(attribs | System.Reflection.MethodAttributes.SpecialName | System.Reflection.MethodAttributes.RTSpecialName, parameterTypes); diff --git a/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs b/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs index d14dc4fef..e8c275675 100644 --- a/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs +++ b/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs @@ -75,7 +75,7 @@ sealed class AssemblyLoader IModuleSymbol[] modules; Dictionary nameMap; bool hasDotNetModule; - AssemblyNameInfo[] internalsVisibleTo; + AssemblyIdentity[] internalsVisibleTo; string[] jarList; #if !IMPORTER && !EXPORTER && !FIRST_PASS sun.misc.URLClassPath urlClassPath; @@ -384,7 +384,7 @@ internal RuntimeJavaType CreateJavaTypeForAssemblyType(ITypeSymbol type) } } - internal bool InternalsVisibleTo(AssemblyNameInfo otherName) + internal bool InternalsVisibleTo(AssemblyIdentity otherName) { if (internalsVisibleTo == null) Interlocked.CompareExchange(ref internalsVisibleTo, loader.Context.AttributeHelper.GetInternalsVisibleToAttributes(assembly), null); @@ -393,7 +393,7 @@ internal bool InternalsVisibleTo(AssemblyNameInfo otherName) { // we match the simple name and PublicKeyToken (because the AssemblyName constructor used // by GetInternalsVisibleToAttributes() only sets the PublicKeyToken, even if a PublicKey is specified) - if (ReflectUtil.MatchNameAndPublicKeyToken(name, otherName)) + if (AssemblyIdentity.MemberwiseEqual(name, otherName) == true && AssemblyIdentity.KeysEqual(name, otherName)) return true; } @@ -1108,7 +1108,7 @@ internal override bool InternalsVisibleToImpl(RuntimeJavaType wrapper, RuntimeJa if (acl == null) return false; - var otherName = acl.GetAssembly(friend).GetName(); + var otherName = acl.GetAssembly(friend).GetIdentity(); #endif return GetLoader(GetAssembly(wrapper)).InternalsVisibleTo(otherName); diff --git a/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishContext.cs b/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishContext.cs index 06f473f1f..1cbe1c18f 100644 --- a/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishContext.cs +++ b/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishContext.cs @@ -558,7 +558,7 @@ internal ITypeSymbol FinishImpl() } else { - cb = ReflectUtil.DefineTypeInitializer(typeBuilder, wrapper.classLoader); + cb = typeBuilder.DefineTypeInitializer(); context.AttributeHelper.HideFromJava(cb); } var ilGenerator = context.CodeEmitterFactory.Create(cb); diff --git a/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.cs b/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.cs index ed378f2a1..d166671fe 100644 --- a/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.cs +++ b/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.cs @@ -2481,7 +2481,7 @@ internal override IMethodBaseSymbol LinkMethod(RuntimeJavaMethod mw) } else if (m.IsClassInitializer) { - method = ReflectUtil.DefineTypeInitializer(typeBuilder, wrapper.classLoader); + method = typeBuilder.DefineTypeInitializer(); } else { diff --git a/src/IKVM.Runtime/compiler.cs b/src/IKVM.Runtime/compiler.cs index 4bb8d9c88..3dbfba4b5 100644 --- a/src/IKVM.Runtime/compiler.cs +++ b/src/IKVM.Runtime/compiler.cs @@ -2744,7 +2744,7 @@ internal static void Emit(Compiler compiler, ClassFile.ConstantPoolItemInvokeDyn var tb = compiler.finish.DefineIndyCallSiteType(); var fb = tb.DefineField("value", typeofIndyCallSite, FieldAttributes.Static | FieldAttributes.Assembly); - var ilgen = compiler.finish.Context.CodeEmitterFactory.Create(ReflectUtil.DefineTypeInitializer(tb, compiler.clazz.ClassLoader)); + var ilgen = compiler.finish.Context.CodeEmitterFactory.Create(tb.DefineTypeInitializer()); ilgen.Emit(System.Reflection.Emit.OpCodes.Ldnull); ilgen.Emit(System.Reflection.Emit.OpCodes.Ldftn, CreateBootstrapStub(compiler, cpi, delegateType, tb, fb, methodGetTarget)); ilgen.Emit(System.Reflection.Emit.OpCodes.Newobj, compiler.finish.Context.MethodHandleUtil.GetDelegateConstructor(delegateType)); @@ -3102,7 +3102,7 @@ static IFieldSymbolBuilder CreateField(Compiler compiler, MethodTypeConstantHand { var tb = compiler.finish.DefineMethodTypeConstantType(handle); var field = tb.DefineField("value", compiler.finish.Context.JavaBase.TypeOfJavaLangInvokeMethodType.TypeAsSignatureType, FieldAttributes.Assembly | FieldAttributes.Static | FieldAttributes.InitOnly); - var ilgen = compiler.finish.Context.CodeEmitterFactory.Create(ReflectUtil.DefineTypeInitializer(tb, compiler.clazz.ClassLoader)); + var ilgen = compiler.finish.Context.CodeEmitterFactory.Create(tb.DefineTypeInitializer()); var delegateType = compiler.finish.Context.MethodHandleUtil.CreateDelegateTypeForLoadConstant(args, ret); ilgen.Emit(System.Reflection.Emit.OpCodes.Call, compiler.finish.Context.ByteCodeHelperMethods.LoadMethodType.MakeGenericMethod(delegateType)); ilgen.Emit(System.Reflection.Emit.OpCodes.Stsfld, field); diff --git a/src/IKVM.Tools.Importer/ImportClassLoader.cs b/src/IKVM.Tools.Importer/ImportClassLoader.cs index 72ccbb4a8..7e321787b 100644 --- a/src/IKVM.Tools.Importer/ImportClassLoader.cs +++ b/src/IKVM.Tools.Importer/ImportClassLoader.cs @@ -135,9 +135,9 @@ internal void AddReference(ImportClassLoader ccl) peerReferences.Add(ccl); } - internal AssemblyNameInfo GetAssemblyName() + internal AssemblyIdentity GetAssemblyName() { - return assemblyBuilder.GetName(); + return assemblyBuilder.GetIdentity(); } private static PermissionSet Combine(PermissionSet p1, PermissionSet p2) @@ -481,18 +481,15 @@ void AddInternalsVisibleToAttribute(ImportClassLoader ccl) { internalsVisibleTo.Add(ccl); var asm = ccl.assemblyBuilder; - var asmName = asm.GetName(); - var name = asmName.Name; - var pubkey = asmName.PublicKeyOrToken; + var asmIdentity = asm.GetIdentity(); - if (pubkey.IsEmpty && asmName.PublicKeyOrToken.IsEmpty == false) - pubkey = asmName.PublicKeyOrToken; - - if (pubkey != null && pubkey.Length != 0) + var name = asmIdentity.Name; + var publicKeyToken = asmIdentity.PublicKeyToken; + if (publicKeyToken.Length > 0) { var sb = new StringBuilder(name); sb.Append(", PublicKey="); - foreach (byte b in pubkey) + foreach (byte b in publicKeyToken) sb.AppendFormat("{0:X2}", b); name = sb.ToString(); @@ -1897,7 +1894,7 @@ internal void Process4thPass(ICollection remappedTypes) if (classDef.Clinit != null) { - var cb = ReflectUtil.DefineTypeInitializer(typeBuilder, classLoader); + var cb = typeBuilder.DefineTypeInitializer(); var ilgen = Context.CodeEmitterFactory.Create(cb); // TODO emit code to make sure super class is initialized classDef.Clinit.Body.Emit(classLoader, ilgen); @@ -2507,7 +2504,7 @@ internal void FinishRemappedTypes() private static bool IsSigned(IAssemblySymbol asm) { - return asm.GetName().PublicKeyOrToken.IsEmpty == false; + return asm.GetIdentity().IsStrongName; } /// @@ -2618,7 +2615,7 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, IDiag // if it's an IKVM compiled assembly, make sure that it was compiled against same version of the runtime foreach (var asmref in reference.GetReferencedAssemblies()) { - if (asmref.Name == runtimeAssembly.GetName().Name) + if (asmref.Name == runtimeAssembly.GetIdentity().Name) { if (IsSigned(runtimeAssembly)) { @@ -2628,8 +2625,7 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, IDiag } else { - if (asmref.PublicKeyOrToken.IsEmpty == false) - throw new DiagnosticEventException(DiagnosticEvent.RuntimeMismatch(reference.Location, runtimeAssembly.FullName, asmref.FullName)); + throw new DiagnosticEventException(DiagnosticEvent.RuntimeMismatch(reference.Location, runtimeAssembly.FullName, asmref.FullName)); } } } diff --git a/src/IKVM.Tools.Importer/ImportContextFactory.cs b/src/IKVM.Tools.Importer/ImportContextFactory.cs index 40c8f58d9..5772faabd 100644 --- a/src/IKVM.Tools.Importer/ImportContextFactory.cs +++ b/src/IKVM.Tools.Importer/ImportContextFactory.cs @@ -494,7 +494,7 @@ void ResolveReferences(List imports) { var forwarder = asm.GetType("__"); if (forwarder != null && forwarder.Assembly != asm) - diagnostics.NonPrimaryAssemblyReference(asm.Location, forwarder.Assembly.GetName().Name); + diagnostics.NonPrimaryAssemblyReference(asm.Location, forwarder.Assembly.GetIdentity().Name); } } } diff --git a/src/IKVM.Tools.Importer/Proxy.cs b/src/IKVM.Tools.Importer/Proxy.cs index 2c1717e7e..f0d9999e5 100644 --- a/src/IKVM.Tools.Importer/Proxy.cs +++ b/src/IKVM.Tools.Importer/Proxy.cs @@ -360,7 +360,7 @@ void CreateMethod(ImportClassLoader loader, ITypeSymbolBuilder tb, ProxyMethod p void CreateStaticInitializer(ITypeSymbolBuilder tb, List methods, ImportClassLoader loader) { - var ilgen = loader.Context.CodeEmitterFactory.Create(ReflectUtil.DefineTypeInitializer(tb, loader)); + var ilgen = loader.Context.CodeEmitterFactory.Create(tb.DefineTypeInitializer()); var callerID = ilgen.DeclareLocal(loader.Context.JavaBase.TypeOfIkvmInternalCallerID.TypeAsSignatureType); var tbCallerID = RuntimeByteCodeJavaType.FinishContext.EmitCreateCallerID(loader.Context, tb, ilgen); ilgen.Emit(OpCodes.Stloc, callerID); From 9fa2ff9754cfb4ab0e721b3922202c99271c839c Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Sat, 5 Oct 2024 20:30:47 -0500 Subject: [PATCH 30/51] Add EmitSymbols to RuntimeContextOptions instead of JVM. Fix ExportTool's bootstrap settings. --- src/IKVM.Runtime/AttributeHelper.cs | 3 + src/IKVM.Runtime/DynamicClassLoader.cs | 61 ++++++++++++------- src/IKVM.Runtime/JVM.Internal.cs | 5 +- src/IKVM.Runtime/JVM.cs | 39 ------------ src/IKVM.Runtime/RuntimeClassLoaderFactory.cs | 8 +-- src/IKVM.Runtime/RuntimeContextOptions.cs | 10 ++- src/IKVM.Tools.Exporter/ExportImpl.cs | 4 +- src/IKVM.Tools.Importer/ImportTool.cs | 3 +- 8 files changed, 61 insertions(+), 72 deletions(-) diff --git a/src/IKVM.Runtime/AttributeHelper.cs b/src/IKVM.Runtime/AttributeHelper.cs index 36bd449d0..6bf07f89b 100644 --- a/src/IKVM.Runtime/AttributeHelper.cs +++ b/src/IKVM.Runtime/AttributeHelper.cs @@ -996,6 +996,9 @@ internal RemappedTypeAttribute GetRemappedType(ITypeSymbol type) internal RemappedClassAttribute[] GetRemappedClasses(IAssemblySymbol coreAssembly) { + if (coreAssembly == null) + throw new ArgumentNullException(nameof(coreAssembly)); + var attrs = new List(); foreach (var cad in coreAssembly.GetCustomAttributes(TypeOfRemappedClassAttribute)) diff --git a/src/IKVM.Runtime/DynamicClassLoader.cs b/src/IKVM.Runtime/DynamicClassLoader.cs index 9280aba81..bd93ff2fc 100644 --- a/src/IKVM.Runtime/DynamicClassLoader.cs +++ b/src/IKVM.Runtime/DynamicClassLoader.cs @@ -210,9 +210,7 @@ public static string TypeNameMangleImpl(ConcurrentDictionary moduleBuilder; -#if !IMPORTER - -#if NETFRAMEWORK +#if NETFRAMEWORK && !IMPORTER internal sealed class ForgedKeyPair : StrongNameKeyPair { @@ -524,45 +516,68 @@ private static SerializationInfo ToInfo(byte[] publicKey) #endif + /// + /// Creates a new dynamic module. + /// + /// + /// public static IModuleSymbolBuilder CreateModuleBuilder(RuntimeContext context) { return CreateModuleBuilder(context, new AssemblyIdentity("ikvm_dynamic_assembly__" + (uint)Environment.TickCount)); } + /// + /// Creates a new dynamic module. + /// + /// + /// + /// public static IModuleSymbolBuilder CreateModuleBuilder(RuntimeContext context, AssemblyIdentity name) { + // set version on assembly var now = DateTime.Now; - name = new AssemblyIdentity(name.Name, new Version(now.Year, (now.Month * 100) + now.Day, (now.Hour * 100) + now.Minute, (now.Second * 1000) + now.Millisecond)); - var attribs = new List(); - -#if NETFRAMEWORK - if (!AppDomain.CurrentDomain.IsFullyTrusted) - attribs.Add(context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveCoreType(typeof(System.Security.SecurityTransparentAttribute).FullName).GetConstructor([]), [])); -#endif - - var assemblyBuilder = DefineDynamicAssembly(context, name, attribs.ToArray()); + name = new AssemblyIdentity( + name.Name, + new Version(now.Year, (now.Month * 100) + now.Day, (now.Hour * 100) + now.Minute, (now.Second * 1000) + now.Millisecond), + name.CultureName, + name.HasPublicKey ? name.PublicKey : name.PublicKeyToken, + name.HasPublicKey, + name.ContentType, + name.ProcessorArchitecture); + + var attribs = Array.Empty(); + if (AppDomain.CurrentDomain.IsFullyTrusted == false) + attribs = [context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveCoreType(typeof(System.Security.SecurityTransparentAttribute).FullName).GetConstructor([]), [])]; + + var assemblyBuilder = DefineDynamicAssembly(context, name, attribs); context.AttributeHelper.SetRuntimeCompatibilityAttribute(assemblyBuilder); // determine debugging mode var debugMode = DebuggingModes.Default | DebuggingModes.IgnoreSymbolStoreSequencePoints; - if (JVM.EmitSymbols) + if (context.Options.EmitSymbols) debugMode |= DebuggingModes.DisableOptimizations; + // add debugging mode to assembly context.AttributeHelper.SetDebuggingModes(assemblyBuilder, debugMode); - var moduleBuilder = assemblyBuilder.DefineModule(name.Name, null, JVM.EmitSymbols); - + // create new module + var moduleBuilder = assemblyBuilder.DefineModule(name.Name, null, context.Options.EmitSymbols); moduleBuilder.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveRuntimeType(typeof(IKVM.Attributes.JavaModuleAttribute).FullName).GetConstructor([]), [])); return moduleBuilder; } + /// + /// Creates a new dynamic assembly. + /// + /// + /// + /// + /// static IAssemblySymbolBuilder DefineDynamicAssembly(RuntimeContext context, AssemblyIdentity name, ICustomAttributeBuilder[] assemblyAttributes) { return context.Resolver.Symbols.DefineAssembly(name, assemblyAttributes); } -#endif - } } diff --git a/src/IKVM.Runtime/JVM.Internal.cs b/src/IKVM.Runtime/JVM.Internal.cs index 543cf847f..c2c71d615 100644 --- a/src/IKVM.Runtime/JVM.Internal.cs +++ b/src/IKVM.Runtime/JVM.Internal.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using IKVM.CoreLib.Diagnostics.Tracing; using IKVM.Runtime.Accessors; @@ -25,9 +26,9 @@ internal static class Internal #if FIRST_PASS == false && IMPORTER == false && EXPORTER == false #if NETFRAMEWORK - internal static readonly RuntimeContextOptions contextOptions = new RuntimeContextOptions(dynamicAssemblySuffixAndPublicKey: RuntimeContextOptions.SignedDefaultDynamicAssemblySuffixAndPublicKey); + internal static readonly RuntimeContextOptions contextOptions = new RuntimeContextOptions(Debugger.IsAttached, dynamicAssemblySuffixAndPublicKey: RuntimeContextOptions.SignedDefaultDynamicAssemblySuffixAndPublicKey); #else - internal static readonly RuntimeContextOptions contextOptions = new RuntimeContextOptions(dynamicAssemblySuffixAndPublicKey: RuntimeContextOptions.UnsignedDefaultDynamicAssemblySuffixAndPublicKey); + internal static readonly RuntimeContextOptions contextOptions = new RuntimeContextOptions(Debugger.IsAttached, dynamicAssemblySuffixAndPublicKey: RuntimeContextOptions.UnsignedDefaultDynamicAssemblySuffixAndPublicKey); #endif internal static readonly RuntimeContext context = new RuntimeContext(contextOptions, DiagnosticEventSource.Instance, new Resolver()); internal static readonly VfsTable vfs = VfsTable.BuildDefaultTable(new VfsRuntimeContext(context), Properties.HomePath); diff --git a/src/IKVM.Runtime/JVM.cs b/src/IKVM.Runtime/JVM.cs index 159f7aadf..61bc043ed 100644 --- a/src/IKVM.Runtime/JVM.cs +++ b/src/IKVM.Runtime/JVM.cs @@ -1,10 +1,8 @@ using System; -using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.ExceptionServices; using System.Security; using System.Text; -using System.Threading; using IKVM.Runtime.Vfs; @@ -21,7 +19,6 @@ public static partial class JVM static bool initialized; #if EXPORTER == false - static int emitSymbols; internal static bool RelaxedVerification = true; internal static bool AllowNonVirtualCalls; internal static readonly bool DisableEagerClassLoading = SafeGetEnvironmentVariable("IKVM_DISABLE_EAGER_CLASS_LOADING") != null; @@ -90,42 +87,6 @@ internal static void Init() #endif } -#if !IMPORTER && !EXPORTER - - internal static bool EmitSymbols - { - get - { - if (emitSymbols == 0) - { - var state = 2; - -#if NETFRAMEWORK - // check app.config on Framework - if (string.Equals(System.Configuration.ConfigurationManager.AppSettings["ikvm-emit-symbols"] ?? "", "true", StringComparison.OrdinalIgnoreCase)) - state = 1; -#endif - - // respect the IKVM_EMIT_SYMBOLs environmental variable - if (string.Equals(Environment.GetEnvironmentVariable("IKVM_EMIT_SYMBOLS") ?? "", "true", StringComparison.OrdinalIgnoreCase)) - state = 1; - - // by default enable symbols if a debugger is attached - if (state == 2 && Debugger.IsAttached) - state = 1; - - // make sure we only set the value once, because it isn't allowed to changed as that could cause - // the compiler to try emitting symbols into a ModuleBuilder that doesn't accept them (and would - // throw an InvalidOperationException) - Interlocked.CompareExchange(ref emitSymbols, state, 0); - } - - return emitSymbols == 1; - } - } - -#endif - #if FIRST_PASS == false && IMPORTER == false && EXPORTER == false /// diff --git a/src/IKVM.Runtime/RuntimeClassLoaderFactory.cs b/src/IKVM.Runtime/RuntimeClassLoaderFactory.cs index 6e564b166..a8220ffad 100644 --- a/src/IKVM.Runtime/RuntimeClassLoaderFactory.cs +++ b/src/IKVM.Runtime/RuntimeClassLoaderFactory.cs @@ -153,18 +153,18 @@ internal RuntimeClassLoader GetClassLoaderWrapper(java.lang.ClassLoader javaClas if (wrapper == null) { var opt = CodeGenOptions.None; - if (JVM.EmitSymbols) + if (context.Options.EmitSymbols) opt |= CodeGenOptions.DisableOptimizations; -#if NETFRAMEWORK - if (!AppDomain.CurrentDomain.IsFullyTrusted) + if (AppDomain.CurrentDomain.IsFullyTrusted == false) opt |= CodeGenOptions.NoAutomagicSerialization; -#endif + wrapper = new RuntimeClassLoader(context, opt, javaClassLoader); SetWrapperForClassLoader(javaClassLoader, wrapper); } return wrapper; } } + #endif /// diff --git a/src/IKVM.Runtime/RuntimeContextOptions.cs b/src/IKVM.Runtime/RuntimeContextOptions.cs index 20f1f047c..3fd7743ca 100644 --- a/src/IKVM.Runtime/RuntimeContextOptions.cs +++ b/src/IKVM.Runtime/RuntimeContextOptions.cs @@ -7,20 +7,28 @@ internal class RuntimeContextOptions internal const string SignedDefaultDynamicAssemblySuffixAndPublicKey = "-ikvm-runtime-injected, PublicKey=00240000048000009400000006020000002400005253413100040000010001009D674F3D63B8D7A4C428BD7388341B025C71AA61C6224CD53A12C21330A3159D300051FE2EED154FE30D70673A079E4529D0FD78113DCA771DA8B0C1EF2F77B73651D55645B0A4294F0AF9BF7078432E13D0F46F951D712C2FCF02EB15552C0FE7817FC0AED58E0984F86661BF64D882F29B619899DD264041E7D4992548EB9E"; internal const string UnsignedDefaultDynamicAssemblySuffixAndPublicKey = "-ikvm-runtime-injected"; + readonly bool emitSymbols; readonly bool bootstrap; readonly string dynamicAssemblySuffixAndPublicKey; /// /// Initializes a new instance. /// + /// /// /// - public RuntimeContextOptions(bool bootstrap = false, string dynamicAssemblySuffixAndPublicKey = null) + public RuntimeContextOptions(bool emitSymbols = false, bool bootstrap = false, string dynamicAssemblySuffixAndPublicKey = null) { + this.emitSymbols = emitSymbols; this.bootstrap = bootstrap; this.dynamicAssemblySuffixAndPublicKey = dynamicAssemblySuffixAndPublicKey ?? UnsignedDefaultDynamicAssemblySuffixAndPublicKey; } + /// + /// Gets whether or not symbols should be emitted. + /// + public bool EmitSymbols => emitSymbols; + /// /// Gets whether or not bootstrap mode is enabled. /// diff --git a/src/IKVM.Tools.Exporter/ExportImpl.cs b/src/IKVM.Tools.Exporter/ExportImpl.cs index 1c506da3a..37622464f 100644 --- a/src/IKVM.Tools.Exporter/ExportImpl.cs +++ b/src/IKVM.Tools.Exporter/ExportImpl.cs @@ -146,7 +146,7 @@ public int Execute() } compiler = new StaticCompiler(universe, assemblyResolver, runtimeAssembly); - context = new RuntimeContext(new RuntimeContextOptions(true), diagnostics, new ExportRuntimeSymbolResolver(diagnostics, universe, symbols, options.Bootstrap), compiler); + context = new RuntimeContext(new RuntimeContextOptions(bootstrap: true), diagnostics, new ExportRuntimeSymbolResolver(diagnostics, universe, symbols, true), compiler); context.ClassLoaderFactory.SetBootstrapClassLoader(new RuntimeBootstrapClassLoader(context)); } else @@ -172,7 +172,7 @@ public int Execute() } compiler = new StaticCompiler(universe, assemblyResolver, runtimeAssembly); - context = new RuntimeContext(new RuntimeContextOptions(), diagnostics, new ExportRuntimeSymbolResolver(diagnostics, universe, symbols, options.Bootstrap), compiler); + context = new RuntimeContext(new RuntimeContextOptions(), diagnostics, new ExportRuntimeSymbolResolver(diagnostics, universe, symbols, false), compiler); } if (context.AttributeHelper.IsJavaModule(context.Resolver.GetSymbol(assembly.ManifestModule))) diff --git a/src/IKVM.Tools.Importer/ImportTool.cs b/src/IKVM.Tools.Importer/ImportTool.cs index c853fdd92..0e4131b3f 100644 --- a/src/IKVM.Tools.Importer/ImportTool.cs +++ b/src/IKVM.Tools.Importer/ImportTool.cs @@ -285,9 +285,10 @@ static DiagnosticOptions GetDiagnosticOptions(IServiceProvider services, ImportO static RuntimeContextOptions CreateContextOptions(IServiceProvider services) { var u = services.GetRequiredService(); + var o = services.GetRequiredService(); var isNetFX = u.CoreLibName == "mscorlib"; var dynamicSuffix = isNetFX ? RuntimeContextOptions.SignedDefaultDynamicAssemblySuffixAndPublicKey : RuntimeContextOptions.UnsignedDefaultDynamicAssemblySuffixAndPublicKey; - return new RuntimeContextOptions(services.GetRequiredService().Bootstrap, dynamicSuffix); + return new RuntimeContextOptions(o.Debug != ImportDebug.Unspecified, o.Bootstrap, dynamicSuffix); } /// From cfa237ad61498b7a61a8739825e5a74b3e295af0 Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Sun, 6 Oct 2024 11:02:50 -0500 Subject: [PATCH 31/51] Annotations need actual live attribute types. --- .../Java/Externs/java/lang/Class.cs | 32 +++++++++++++------ src/IKVM.Runtime/RuntimeJavaType.cs | 20 ++++++++++++ .../RuntimeManagedByteCodeJavaType.cs | 12 +++---- src/IKVM.Runtime/SymbolExtensions.cs | 12 +++++++ 4 files changed, 60 insertions(+), 16 deletions(-) diff --git a/src/IKVM.Runtime/Java/Externs/java/lang/Class.cs b/src/IKVM.Runtime/Java/Externs/java/lang/Class.cs index e7c9d49e8..31a66d3d9 100644 --- a/src/IKVM.Runtime/Java/Externs/java/lang/Class.cs +++ b/src/IKVM.Runtime/Java/Externs/java/lang/Class.cs @@ -450,26 +450,38 @@ public static string getGenericSignature0(global::java.lang.Class thisClass) return tw.GetGenericSignature(); } - internal static object AnnotationsToMap(RuntimeClassLoader loader, object[] objAnn) + /// + /// Converts an array of annotation instances to a IMap. + /// + /// + /// + /// + internal static object AnnotationsToMap(RuntimeClassLoader loader, object[] annotations) { #if FIRST_PASS throw new NotImplementedException(); #else var map = new global::java.util.LinkedHashMap(); - if (objAnn != null) + + if (annotations != null) { - foreach (object obj in objAnn) + foreach (var obj in annotations) { - var a = obj as global::java.lang.annotation.Annotation; - if (a != null) + // annotation is an actual annotation instance + if (obj is global::java.lang.annotation.Annotation annotation) { - map.put(a.annotationType(), FreezeOrWrapAttribute(a)); + map.put(annotation.annotationType(), FreezeOrWrapAttribute(annotation)); + continue; } - else if (obj is IKVM.Attributes.DynamicAnnotationAttribute) + + // annotation is a DynamicAnnotationAttribute, which encapsulates an annotation + if (obj is IKVM.Attributes.DynamicAnnotationAttribute dynamicAttribute) { - a = (global::java.lang.annotation.Annotation)JVM.NewAnnotation(loader.GetJavaClassLoader(), ((IKVM.Attributes.DynamicAnnotationAttribute)obj).Definition); - if (a != null) - map.put(a.annotationType(), a); + annotation = (global::java.lang.annotation.Annotation)JVM.NewAnnotation(loader.GetJavaClassLoader(), dynamicAttribute.Definition); + if (annotation != null) + map.put(annotation.annotationType(), annotation); + + continue; } } } diff --git a/src/IKVM.Runtime/RuntimeJavaType.cs b/src/IKVM.Runtime/RuntimeJavaType.cs index abb8df974..7a5e44cf1 100644 --- a/src/IKVM.Runtime/RuntimeJavaType.cs +++ b/src/IKVM.Runtime/RuntimeJavaType.cs @@ -1443,26 +1443,46 @@ internal virtual MethodParametersEntry[] GetMethodParameters(RuntimeJavaMethod m } #if !IMPORTER && !EXPORTER + internal virtual string[] GetEnclosingMethod() { return null; } + /// + /// Gets the annotations declared on this type. Expected to return actual runtime instances. + /// + /// internal virtual object[] GetDeclaredAnnotations() { return null; } + /// + /// Gets the annotations declared on the specified method of this type. Expected to return actual runtime instances. + /// + /// + /// internal virtual object[] GetMethodAnnotations(RuntimeJavaMethod mw) { return null; } + /// + /// Gets the annotations declared on the specified parameters of the specified method of this type. Expected to return actual runtime instances. + /// + /// + /// internal virtual object[][] GetParameterAnnotations(RuntimeJavaMethod mw) { return null; } + /// + /// Gets the annotations declared on the specified fieldof this type. Expected to return actual runtime instances. + /// + /// + /// internal virtual object[] GetFieldAnnotations(RuntimeJavaField fw) { return null; diff --git a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs index 0b5a93a43..73fa25273 100644 --- a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs @@ -1104,7 +1104,7 @@ internal override string[] GetEnclosingMethod() return null; } - object[] CastArray(CustomAttribute[] l) + object[] CastArray(object[] l) { var a = new object[l.Length]; for (int i = 0; i < l.Length; i++) @@ -1115,7 +1115,7 @@ object[] CastArray(CustomAttribute[] l) internal override object[] GetDeclaredAnnotations() { - return CastArray(type.GetCustomAttributes(false)); + return CastArray(type.AsReflection().GetCustomAttributes(false)); } internal override object[] GetMethodAnnotations(RuntimeJavaMethod mw) @@ -1127,7 +1127,7 @@ internal override object[] GetMethodAnnotations(RuntimeJavaMethod mw) return null; } - return CastArray(mb.GetCustomAttributes(false)); + return CastArray(mb.AsReflection().GetCustomAttributes(false)); } internal override object[][] GetParameterAnnotations(RuntimeJavaMethod mw) @@ -1150,7 +1150,7 @@ internal override object[][] GetParameterAnnotations(RuntimeJavaMethod mw) var attribs = new object[parameters.Length - skip - skipEnd][]; for (int i = skip; i < parameters.Length - skipEnd; i++) - attribs[i - skip] = CastArray(parameters[i].GetCustomAttributes(false)); + attribs[i - skip] = CastArray(parameters[i].AsReflection().GetCustomAttributes(false)); return attribs; } @@ -1159,10 +1159,10 @@ internal override object[] GetFieldAnnotations(RuntimeJavaField fw) { var field = fw.GetField(); if (field != null) - return CastArray(field.GetCustomAttributes(false)); + return CastArray(field.AsReflection().GetCustomAttributes(false)); if (fw is RuntimeManagedByteCodePropertyJavaField prop) - return CastArray(prop.GetProperty().GetCustomAttributes(false)); + return CastArray(prop.GetProperty().AsReflection().GetCustomAttributes(false)); return Array.Empty(); } diff --git a/src/IKVM.Runtime/SymbolExtensions.cs b/src/IKVM.Runtime/SymbolExtensions.cs index 52745475a..e98aa7697 100644 --- a/src/IKVM.Runtime/SymbolExtensions.cs +++ b/src/IKVM.Runtime/SymbolExtensions.cs @@ -107,6 +107,18 @@ public static MethodInfo AsReflection(this IMethodSymbol symbol) #endif } + public static ParameterInfo AsReflection(this IParameterSymbol symbol) + { + if (symbol == null) + return null; + +#if IMPORTER || EXPORTER + return ((IIkvmReflectionParameterSymbol)symbol).UnderlyingParameter; +#else + return ((IReflectionParameterSymbol)symbol).UnderlyingParameter; +#endif + } + public static FieldInfo AsReflection(this IFieldSymbol symbol) { if (symbol == null) From 61300493a43ccdf1dfac077ed65760fbb4c1ea3a Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Sun, 6 Oct 2024 16:08:23 -0500 Subject: [PATCH 32/51] No need to use open generic, since GetMethod now works against closed builder. --- src/IKVM.Runtime/compiler.cs | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/src/IKVM.Runtime/compiler.cs b/src/IKVM.Runtime/compiler.cs index 3dbfba4b5..e6692cfa1 100644 --- a/src/IKVM.Runtime/compiler.cs +++ b/src/IKVM.Runtime/compiler.cs @@ -2729,19 +2729,8 @@ internal static void Emit(Compiler compiler, ClassFile.ConstantPoolItemInvokeDyn methodLookup.Link(); var typeofIndyCallSite = typeofOpenIndyCallSite.MakeGenericType(delegateType); - IMethodSymbol methodCreateBootStrap; - IMethodSymbol methodGetTarget; - if (ReflectUtil.ContainsTypeBuilder(typeofIndyCallSite)) - { - methodCreateBootStrap = typeofOpenIndyCallSite.GetMethod("CreateBootstrap"); - methodGetTarget = typeofOpenIndyCallSite.GetMethod("GetTarget"); - } - else - { - methodCreateBootStrap = typeofIndyCallSite.GetMethod("CreateBootstrap"); - methodGetTarget = typeofIndyCallSite.GetMethod("GetTarget"); - } - + var methodCreateBootStrap = typeofIndyCallSite.GetMethod("CreateBootstrap"); + var methodGetTarget = typeofIndyCallSite.GetMethod("GetTarget"); var tb = compiler.finish.DefineIndyCallSiteType(); var fb = tb.DefineField("value", typeofIndyCallSite, FieldAttributes.Static | FieldAttributes.Assembly); var ilgen = compiler.finish.Context.CodeEmitterFactory.Create(tb.DefineTypeInitializer()); From 6ccacea9493b546221fe3dad47cdffebec448391 Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Sun, 6 Oct 2024 19:27:05 -0500 Subject: [PATCH 33/51] For GetConstructors, same deal, no need to check for TypeBuilders. --- .../Java/Externs/ikvm/runtime/Util.cs | 2 +- src/IKVM.Runtime/MethodHandleUtil.compiler.cs | 9 +-------- src/IKVM.Runtime/ReflectUtil.cs | 20 ------------------- .../RuntimeByteCodeJavaType.JavaTypeImpl.cs | 1 - 4 files changed, 2 insertions(+), 30 deletions(-) diff --git a/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Util.cs b/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Util.cs index 5d50f9c5b..2da52208a 100644 --- a/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Util.cs +++ b/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Util.cs @@ -117,7 +117,7 @@ internal static RuntimeJavaType GetTypeWrapperFromObject(RuntimeContext context, var ts = JVM.Context.Resolver.GetSymbol(type); int rank = 0; - while (ReflectUtil.IsVector(ts)) + while (ts.IsSZArray) { ts = ts.GetElementType(); rank++; diff --git a/src/IKVM.Runtime/MethodHandleUtil.compiler.cs b/src/IKVM.Runtime/MethodHandleUtil.compiler.cs index b4e2f1d71..041845bb1 100644 --- a/src/IKVM.Runtime/MethodHandleUtil.compiler.cs +++ b/src/IKVM.Runtime/MethodHandleUtil.compiler.cs @@ -49,14 +49,7 @@ internal IConstructorSymbol GetDelegateConstructor(ITypeSymbol delegateType) private IConstructorSymbol GetDelegateOrPackedArgsConstructor(ITypeSymbol type) { - if (ReflectUtil.ContainsTypeBuilder(type)) - { - return type.GetGenericTypeDefinition().GetConstructors()[0]; - } - else - { - return type.GetConstructors()[0]; - } + return type.GetConstructors()[0]; } // for delegate types used for "ldc " we don't want ghost arrays to be erased diff --git a/src/IKVM.Runtime/ReflectUtil.cs b/src/IKVM.Runtime/ReflectUtil.cs index 2259bc065..69c23a0a9 100644 --- a/src/IKVM.Runtime/ReflectUtil.cs +++ b/src/IKVM.Runtime/ReflectUtil.cs @@ -91,21 +91,6 @@ internal static bool IsReflectionOnly(ITypeSymbol type) return false; } - internal static bool ContainsTypeBuilder(ITypeSymbol type) - { - while (type.HasElementType) - type = type.GetElementType(); - - if (!type.IsGenericType || type.IsGenericTypeDefinition) - return type is ITypeSymbolBuilder; - - foreach (var arg in type.GetGenericArguments()) - if (ContainsTypeBuilder(arg)) - return true; - - return type.GetGenericTypeDefinition() is ITypeSymbolBuilder; - } - internal static bool IsDynamicMethod(IMethodSymbol method) { // there's no way to distinguish a baked DynamicMethod from a RuntimeMethodInfo and @@ -179,11 +164,6 @@ private static bool MatchTypes(ITypeSymbol[] t1, ITypeSymbol[] t2) return false; } - internal static bool IsVector(ITypeSymbol type) - { - return type.IsSZArray; - } - #if IMPORTER internal static ITypeSymbol GetMissingType(ITypeSymbol type) diff --git a/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.cs b/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.cs index d166671fe..21106db45 100644 --- a/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.cs +++ b/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.cs @@ -73,7 +73,6 @@ private sealed partial class JavaTypeImpl : DynamicImpl internal JavaTypeImpl(RuntimeJavaType host, ClassFile f, RuntimeByteCodeJavaType wrapper) { - wrapper.ClassLoader.Diagnostics.GenericCompilerInfo("constructing JavaTypeImpl for " + f.Name); this.host = host; this.classFile = f; this.wrapper = (RuntimeDynamicOrImportJavaType)wrapper; From 14a06b08dfe0e5f5c81a875d3ecc7c2f2d736e35 Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Mon, 7 Oct 2024 00:22:11 -0500 Subject: [PATCH 34/51] Complete parameters on first access. Enumeratingn them on type complete causes recursion. --- .../Emit/IReflectionParameterSymbolBuilder.cs | 5 +-- .../Emit/ReflectionMethodBaseSymbolBuilder.cs | 4 --- .../Emit/ReflectionParameterSymbolBuilder.cs | 32 +++++++++++++------ .../Reflection/ReflectionParameterTable.cs | 18 ++++------- 4 files changed, 33 insertions(+), 26 deletions(-) diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionParameterSymbolBuilder.cs index 17f6fb75e..212f8a24f 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionParameterSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionParameterSymbolBuilder.cs @@ -1,4 +1,5 @@ -using System.Reflection.Emit; +using System.Reflection; +using System.Reflection.Emit; using IKVM.CoreLib.Symbols.Emit; @@ -16,7 +17,7 @@ interface IReflectionParameterSymbolBuilder : IReflectionSymbolBuilder, IParamet /// /// Invoked when the owning method of this parameter is completed. /// - void OnComplete(); + void OnComplete(ParameterInfo parameter); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodBaseSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodBaseSymbolBuilder.cs index ac5e72337..990e9379c 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodBaseSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodBaseSymbolBuilder.cs @@ -153,10 +153,6 @@ public override void OnComplete() if (i is IReflectionGenericTypeParameterSymbolBuilder b) b.OnComplete(); - foreach (var i in GetParameters()) - if (i is IReflectionParameterSymbolBuilder b) - b.OnComplete(); - base.OnComplete(); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionParameterSymbolBuilder.cs index d5bd36f67..20209ba1d 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionParameterSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionParameterSymbolBuilder.cs @@ -111,7 +111,14 @@ public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) public int Position => UnderlyingParameter.Position; /// - public override bool IsComplete => _builder == null; + public override bool IsComplete + { + get + { + lock (this) + return _builder == null; + } + } /// public CustomAttribute[] GetCustomAttributes(bool inherit = false) @@ -153,15 +160,22 @@ public ITypeSymbol[] GetRequiredCustomModifiers() #endregion /// - public void OnComplete() + public void OnComplete(ParameterInfo parameter) { - if (ResolvingMember is IReflectionMethodBaseSymbolBuilder b) - _parameter = b.UnderlyingMethodBase.GetParameters()[Position]; - - if (ResolvingMember is IReflectionPropertySymbolBuilder p) - _parameter = p.UnderlyingPropertyBuilder.GetIndexParameters()[Position]; - - _builder = null; + if (parameter is null) + throw new ArgumentNullException(nameof(parameter)); + + if (IsComplete == false) + { + lock (this) + { + if (IsComplete == false) + { + _parameter = parameter; + _builder = null; + } + } + } } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterTable.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterTable.cs index 8d1faa6b1..b4d03c1d6 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterTable.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterTable.cs @@ -20,7 +20,6 @@ struct ReflectionParameterTable IndexRangeDictionary _table = new(); ReaderWriterLockSlim? _lock; - IReflectionParameterSymbol? _returnParameter; /// /// Initializes a new instance. @@ -28,7 +27,6 @@ struct ReflectionParameterTable /// /// /// - /// /// public ReflectionParameterTable(ReflectionSymbolContext context, IReflectionModuleSymbol module, IReflectionMemberSymbol member) { @@ -56,14 +54,15 @@ public IReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo param using (_lock.CreateUpgradeableReadLock()) { var position = parameter.Position; - if (position == -1) - return _returnParameter ??= new ReflectionParameterSymbol(_context, _module, _member, parameter); - if (_table[position] == null) using (_lock.CreateWriteLock()) - return _table[position] ??= new ReflectionParameterSymbol(_context, _module, _member, parameter); + _table[position] ??= new ReflectionParameterSymbol(_context, _module, _member, parameter); + + var item = _table[position] ?? throw new InvalidOperationException(); + if (item.IsComplete == false && item is IReflectionParameterSymbolBuilder builder) + builder.OnComplete(parameter); - return _table[position] ?? throw new InvalidOperationException(); + return item; } } @@ -86,12 +85,9 @@ public IReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBui using (_lock.CreateUpgradeableReadLock()) { var position = parameter.Position - 1; - if (position == -1) - return (IReflectionParameterSymbolBuilder)(_returnParameter ??= new ReflectionParameterSymbolBuilder(_context, _module, (IReflectionMethodBaseSymbol)_member, parameter)); - if (_table[position] == null) using (_lock.CreateWriteLock()) - return (IReflectionParameterSymbolBuilder)(_table[position] ??= new ReflectionParameterSymbolBuilder(_context, _module, (IReflectionMethodBaseSymbol)_member, parameter)); + _table[position] ??= new ReflectionParameterSymbolBuilder(_context, _module, (IReflectionMethodBaseSymbol)_member, parameter); return (IReflectionParameterSymbolBuilder?)_table[position] ?? throw new InvalidOperationException(); } From 9222bb5448e98f0ab1b1ff4eee25c5e9c0a5d944 Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Mon, 7 Oct 2024 15:31:00 -0500 Subject: [PATCH 35/51] Fix. --- .../IkvmReflectionSymbolTests.cs | 4 +- .../Reflection/ReflectionSymbolTests.cs | 4 +- .../Symbols/Emit/IAssemblySymbolBuilder.cs | 10 +-- src/IKVM.CoreLib/Symbols/ISymbolContext.cs | 9 ++- .../IkvmReflectionAssemblySymbolBuilder.cs | 4 +- .../IkvmReflectionSymbolContext.cs | 13 +++- .../Emit/ReflectionAssemblySymbolBuilder.cs | 16 +++-- .../Reflection/ReflectionSymbolContext.cs | 37 ++++++++-- .../ErrorHandlerInterceptor.cs | 43 ++++++------ .../HarnessObserverInterceptor.cs | 68 +++++++++---------- .../IKVM.JTReg.TestAdapter.Core.csproj | 1 + .../JTRegTestDiscoverer.cs | 7 ++ src/IKVM.Runtime/DynamicClassLoader.cs | 2 +- 13 files changed, 138 insertions(+), 80 deletions(-) diff --git a/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs b/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs index b827019c2..792c054a3 100644 --- a/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs +++ b/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs @@ -448,7 +448,7 @@ public void CanResolveMultipleEventBuilders() public void CanGetMethodsFromTypeBuilder() { var c = new IkvmReflectionSymbolContext(universe!); - var a = c.DefineAssembly(new AssemblyIdentity("DynamicAssembly")); + var a = c.DefineAssembly(new AssemblyIdentity("DynamicAssembly"), false, true); var m = a.DefineModule("DynamicModule", "DynamicModule.dll"); var type = m.DefineType("DynamicType"); @@ -476,7 +476,7 @@ public void CanGetMethodsFromTypeBuilder() public void CanGetGenericDelegateInvoke() { var c = new IkvmReflectionSymbolContext(universe!); - var a = c.DefineAssembly(new AssemblyIdentity("DynamicAssembly")); + var a = c.DefineAssembly(new AssemblyIdentity("DynamicAssembly"), false, true); var m = a.DefineModule("DynamicModule", "DynamicModule.dll"); var tb = m.DefineType("DynamicGenericDelegate", System.Reflection.TypeAttributes.NotPublic | System.Reflection.TypeAttributes.Sealed, c.GetOrCreateTypeSymbol(coreAssembly!.GetType("System.MulticastDelegate"))); diff --git a/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs b/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs index 5c5bc6d2a..edf8cf48e 100644 --- a/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs +++ b/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs @@ -425,8 +425,8 @@ public void CanCompleteTypeBuilder() public void CanGetMethodsFromTypeBuilder() { var c = new ReflectionSymbolContext(); - var a = c.DefineAssembly(new AssemblyIdentity("DynamicAssembly")); - var m = a.DefineModule("DynamicModule", "DynamicModule.dll"); + var a = c.DefineAssembly(new AssemblyIdentity("DynamicAssembly"), false, false); + var m = a.DefineModule("DynamicModule"); var type = m.DefineType("DynamicType"); var method = type.DefineMethod("DynamicMethod1", System.Reflection.MethodAttributes.Public | System.Reflection.MethodAttributes.Static); diff --git a/src/IKVM.CoreLib/Symbols/Emit/IAssemblySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IAssemblySymbolBuilder.cs index 5df264c93..8c9ab94ef 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/IAssemblySymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/IAssemblySymbolBuilder.cs @@ -63,15 +63,15 @@ interface IAssemblySymbolBuilder : ISymbolBuilder, IAssemblySym /// /// Sets the entry point for this assembly, assuming that a console application is being built. /// - /// - void SetEntryPoint(IMethodSymbolBuilder mainMethodProxy); + /// + void SetEntryPoint(IMethodSymbol entryMethod); /// /// Sets the entry point for this assembly and defines the type of the portable executable (PE file) being built. /// - /// - /// - void SetEntryPoint(IMethodSymbolBuilder mainMethodProxy, PEFileKinds target); + /// + /// + void SetEntryPoint(IMethodSymbol entryMethod, PEFileKinds fileKind); /// /// Adds a forwarded type to this assembly. diff --git a/src/IKVM.CoreLib/Symbols/ISymbolContext.cs b/src/IKVM.CoreLib/Symbols/ISymbolContext.cs index 32910c189..f014a0a5b 100644 --- a/src/IKVM.CoreLib/Symbols/ISymbolContext.cs +++ b/src/IKVM.CoreLib/Symbols/ISymbolContext.cs @@ -13,15 +13,20 @@ interface ISymbolContext /// Defines a dynamic assembly that has the specified name and access rights. /// /// + /// + /// /// - IAssemblySymbolBuilder DefineAssembly(AssemblyIdentity name); + IAssemblySymbolBuilder DefineAssembly(AssemblyIdentity name, bool collectable = true, bool saveable = false); /// /// Defines a dynamic assembly that has the specified name and access rights. /// /// + /// + /// + /// /// - IAssemblySymbolBuilder DefineAssembly(AssemblyIdentity name, ICustomAttributeBuilder[]? assemblyAttributes); + IAssemblySymbolBuilder DefineAssembly(AssemblyIdentity name, ICustomAttributeBuilder[]? assemblyAttributes, bool collectable = true, bool saveable = false); /// /// Initializes an instance of the interface given the constructor for the custom attribute and the arguments to the constructor. diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionAssemblySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionAssemblySymbolBuilder.cs index 8145099b2..13cc31043 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionAssemblySymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionAssemblySymbolBuilder.cs @@ -106,13 +106,13 @@ public void DefineVersionInfoResource() } /// - public void SetEntryPoint(IMethodSymbolBuilder mainMethodProxy) + public void SetEntryPoint(IMethodSymbol mainMethodProxy) { UnderlyingAssemblyBuilder.SetEntryPoint(mainMethodProxy.Unpack()); } /// - public void SetEntryPoint(IMethodSymbolBuilder mainMethodProxy, IKVM.CoreLib.Symbols.Emit.PEFileKinds target) + public void SetEntryPoint(IMethodSymbol mainMethodProxy, IKVM.CoreLib.Symbols.Emit.PEFileKinds target) { UnderlyingAssemblyBuilder.SetEntryPoint(mainMethodProxy.Unpack(), (IKVM.Reflection.Emit.PEFileKinds)target); } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolContext.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolContext.cs index 56a561339..a3e8d19a5 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolContext.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolContext.cs @@ -32,19 +32,28 @@ public IkvmReflectionSymbolContext(Universe universe) } /// - public IAssemblySymbolBuilder DefineAssembly(AssemblyIdentity name) + public IAssemblySymbolBuilder DefineAssembly(AssemblyIdentity name, bool collectable, bool saveable) { if (name is null) throw new ArgumentNullException(nameof(name)); + if (collectable) + throw new NotSupportedException("IKVM Reflection cannot produce collectable assemblies."); + if (saveable == false) + throw new NotSupportedException("IKVM Reflection can only produce saveable assemblies."); + return GetOrCreateAssemblySymbol(_universe.DefineDynamicAssembly(name.Unpack(), AssemblyBuilderAccess.Save)); } /// - public IAssemblySymbolBuilder DefineAssembly(AssemblyIdentity name, ICustomAttributeBuilder[]? assemblyAttributes) + public IAssemblySymbolBuilder DefineAssembly(AssemblyIdentity name, ICustomAttributeBuilder[]? assemblyAttributes, bool collectable, bool saveable) { if (name is null) throw new ArgumentNullException(nameof(name)); + if (collectable) + throw new NotSupportedException("IKVM Reflection cannot produce collectable assemblies."); + if (saveable == false) + throw new NotSupportedException("IKVM Reflection can only produce saveable assemblies."); return GetOrCreateAssemblySymbol(_universe.DefineDynamicAssembly(name.Unpack(), AssemblyBuilderAccess.Save, assemblyAttributes?.Unpack())); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs index c5d085a52..eae10821b 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs @@ -124,15 +124,23 @@ public void DefineVersionInfoResource() } /// - public void SetEntryPoint(IMethodSymbolBuilder mainMethodProxy) + public void SetEntryPoint(IMethodSymbol mainMethodProxy) { - throw new NotImplementedException(); +#if NETFRAMEWORK + UnderlyingAssemblyBuilder.SetEntryPoint(mainMethodProxy.Unpack()); +#else + throw new NotSupportedException(); +#endif } /// - public void SetEntryPoint(IMethodSymbolBuilder mainMethodProxy, IKVM.CoreLib.Symbols.Emit.PEFileKinds target) + public void SetEntryPoint(IMethodSymbol mainMethodProxy, IKVM.CoreLib.Symbols.Emit.PEFileKinds target) { - throw new NotImplementedException(); +#if NETFRAMEWORK + UnderlyingAssemblyBuilder.SetEntryPoint(mainMethodProxy.Unpack(), (System.Reflection.Emit.PEFileKinds)target); +#else + throw new NotSupportedException(); +#endif } /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs index b435aa903..d4f421bb9 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs @@ -29,28 +29,53 @@ public ReflectionSymbolContext() } /// - public IAssemblySymbolBuilder DefineAssembly(AssemblyIdentity name) + public IAssemblySymbolBuilder DefineAssembly(AssemblyIdentity name, bool collectable, bool saveable) { if (name is null) throw new ArgumentNullException(nameof(name)); + if (collectable && saveable) + throw new NotSupportedException("Assembly cannot be both colletable and saveable."); #if NET - return GetOrCreateAssemblySymbol(AssemblyBuilder.DefineDynamicAssembly(name.Unpack(), AssemblyBuilderAccess.RunAndCollect)); + if (saveable) + throw new NotSupportedException("Assembly cannot be saveable."); + else if (collectable) + return GetOrCreateAssemblySymbol(AssemblyBuilder.DefineDynamicAssembly(name.Unpack(), AssemblyBuilderAccess.RunAndCollect)); + else + return GetOrCreateAssemblySymbol(AssemblyBuilder.DefineDynamicAssembly(name.Unpack(), AssemblyBuilderAccess.Run)); #else - return GetOrCreateAssemblySymbol(AssemblyBuilder.DefineDynamicAssembly(name.Unpack(), AssemblyBuilderAccess.RunAndSave)); + if (saveable) + return GetOrCreateAssemblySymbol(AssemblyBuilder.DefineDynamicAssembly(name.Unpack(), AssemblyBuilderAccess.RunAndSave)); + else if (collectable) + return GetOrCreateAssemblySymbol(AssemblyBuilder.DefineDynamicAssembly(name.Unpack(), AssemblyBuilderAccess.RunAndCollect)); + else + return GetOrCreateAssemblySymbol(AssemblyBuilder.DefineDynamicAssembly(name.Unpack(), AssemblyBuilderAccess.Run)); #endif } /// - public IAssemblySymbolBuilder DefineAssembly(AssemblyIdentity name, ICustomAttributeBuilder[]? assemblyAttributes) + public IAssemblySymbolBuilder DefineAssembly(AssemblyIdentity name, ICustomAttributeBuilder[]? assemblyAttributes, bool collectable, bool saveable) { if (name is null) throw new ArgumentNullException(nameof(name)); + if (collectable && saveable) + throw new NotSupportedException("Assembly cannot be both colletable and saveable."); + #if NET - return GetOrCreateAssemblySymbol(AssemblyBuilder.DefineDynamicAssembly(name.Unpack(), AssemblyBuilderAccess.RunAndCollect, assemblyAttributes?.Unpack())); + if (saveable) + throw new NotSupportedException("Assembly cannot be saveable."); + else if (collectable) + return GetOrCreateAssemblySymbol(AssemblyBuilder.DefineDynamicAssembly(name.Unpack(), AssemblyBuilderAccess.RunAndCollect, assemblyAttributes?.Unpack())); + else + return GetOrCreateAssemblySymbol(AssemblyBuilder.DefineDynamicAssembly(name.Unpack(), AssemblyBuilderAccess.Run, assemblyAttributes?.Unpack())); #else - return GetOrCreateAssemblySymbol(AssemblyBuilder.DefineDynamicAssembly(name.Unpack(), AssemblyBuilderAccess.RunAndSave,assemblyAttributes?.Unpack())); + if (saveable) + return GetOrCreateAssemblySymbol(AssemblyBuilder.DefineDynamicAssembly(name.Unpack(), AssemblyBuilderAccess.RunAndSave, assemblyAttributes?.Unpack())); + else if (collectable) + return GetOrCreateAssemblySymbol(AssemblyBuilder.DefineDynamicAssembly(name.Unpack(), AssemblyBuilderAccess.RunAndCollect, assemblyAttributes?.Unpack())); + else + return GetOrCreateAssemblySymbol(AssemblyBuilder.DefineDynamicAssembly(name.Unpack(), AssemblyBuilderAccess.Run, assemblyAttributes?.Unpack())); #endif } diff --git a/src/IKVM.JTReg.TestAdapter.Core/ErrorHandlerInterceptor.cs b/src/IKVM.JTReg.TestAdapter.Core/ErrorHandlerInterceptor.cs index 2c39731e6..611f02bfd 100644 --- a/src/IKVM.JTReg.TestAdapter.Core/ErrorHandlerInterceptor.cs +++ b/src/IKVM.JTReg.TestAdapter.Core/ErrorHandlerInterceptor.cs @@ -1,6 +1,6 @@ using System; - -using Castle.DynamicProxy; +using System.Linq; +using System.Reflection; namespace IKVM.JTReg.TestAdapter.Core { @@ -8,54 +8,57 @@ namespace IKVM.JTReg.TestAdapter.Core /// /// Generates an implementation of 'com.sun.javatest.TestFinder$ErrorHandler'. /// - class ErrorHandlerInterceptor : IInterceptor + class ErrorHandlerInterceptor : DispatchProxy { - static readonly ProxyGenerator DefaultProxyGenerator = new ProxyGenerator(); + static readonly MethodInfo CreateMethodInfo = typeof(DispatchProxy).GetMethods() + .Where(i => i.Name == "Create") + .Where(i => i.GetGenericArguments().Length == 2) + .First(); /// /// Creates a new implementation of 'com.sun.javatest.TestFinder$ErrorHandler'. /// /// - public static dynamic Create(IJTRegLoggerContext logger) + public static ErrorHandlerInterceptor Create(IJTRegLoggerContext logger) { - return DefaultProxyGenerator.CreateInterfaceProxyWithoutTarget(JTRegTypes.TestFinder.ErrorHandler.Type, new ErrorHandlerInterceptor(logger)); + var proxy = (ErrorHandlerInterceptor)CreateMethodInfo.MakeGenericMethod(JTRegTypes.TestFinder.ErrorHandler.Type, typeof(ErrorHandlerInterceptor)).Invoke(null, []); + proxy.SetLogger(logger); + return proxy; } - readonly IJTRegLoggerContext logger; + IJTRegLoggerContext logger; /// - /// Initializes a new instance. + /// Sets the logger instance. /// /// - /// - public ErrorHandlerInterceptor(IJTRegLoggerContext logger) + public void SetLogger(IJTRegLoggerContext logger) { this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); } /// - /// + /// Intercepts method calls to the underlying type. /// - /// - public void Intercept(IInvocation invocation) + /// + /// + protected override object Invoke(MethodInfo targetMethod, object[] args) { - switch (invocation.Method.Name) + switch (targetMethod.Name) { case "error": - error(invocation.Proxy, (string)invocation.GetArgumentValue(0)); - break; - default: - invocation.Proceed(); + error((string)args[0]); break; } + + throw new InvalidOperationException(); } - public void error(dynamic proxy, string msg) + void error(string msg) { logger.SendMessage(JTRegTestMessageLevel.Error, msg); } - } } diff --git a/src/IKVM.JTReg.TestAdapter.Core/HarnessObserverInterceptor.cs b/src/IKVM.JTReg.TestAdapter.Core/HarnessObserverInterceptor.cs index e37941fb2..aeb21f748 100644 --- a/src/IKVM.JTReg.TestAdapter.Core/HarnessObserverInterceptor.cs +++ b/src/IKVM.JTReg.TestAdapter.Core/HarnessObserverInterceptor.cs @@ -2,8 +2,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; - -using Castle.DynamicProxy; +using System.Reflection; namespace IKVM.JTReg.TestAdapter.Core { @@ -11,10 +10,13 @@ namespace IKVM.JTReg.TestAdapter.Core /// /// Generates an implementation of 'com.sun.javatest.Harness$Observer'. /// - class HarnessObserverInterceptor : IInterceptor + class HarnessObserverInterceptor : DispatchProxy { - static readonly ProxyGenerator DefaultProxyGenerator = new ProxyGenerator(); + static readonly MethodInfo CreateMethodInfo = typeof(DispatchProxy).GetMethods() + .Where(i => i.Name == "Create") + .Where(i => i.GetGenericArguments().Length == 2) + .First(); /// /// Creates a new implementation of 'com.sun.javatest.Harness$Observer'. @@ -22,23 +24,25 @@ class HarnessObserverInterceptor : IInterceptor /// public static dynamic Create(string source, dynamic testSuite, IJTRegExecutionContext context, IEnumerable tests) { - return DefaultProxyGenerator.CreateInterfaceProxyWithoutTarget(JTRegTypes.Harness.Observer.Type, new HarnessObserverInterceptor(source, testSuite, context, tests)); + var proxy = (HarnessObserverInterceptor)CreateMethodInfo.MakeGenericMethod(JTRegTypes.Harness.Observer.Type, typeof(HarnessObserverInterceptor)).Invoke(null, []); + proxy.Init(source, testSuite, context, tests); + return proxy; } - readonly string source; - readonly dynamic testSuite; - readonly IJTRegExecutionContext context; - readonly ConcurrentDictionary tests; + string source; + dynamic testSuite; + IJTRegExecutionContext context; + ConcurrentDictionary tests; /// - /// Initializes a new instance. + /// Initializes the instance. /// /// /// /// /// /// - public HarnessObserverInterceptor(string source, dynamic testSuite, IJTRegExecutionContext context, IEnumerable tests) + void Init(string source, dynamic testSuite, IJTRegExecutionContext context, IEnumerable tests) { this.source = source ?? throw new ArgumentNullException(nameof(source)); this.testSuite = testSuite ?? throw new ArgumentNullException(nameof(testSuite)); @@ -46,47 +50,43 @@ public HarnessObserverInterceptor(string source, dynamic testSuite, IJTRegExecut this.tests = new ConcurrentDictionary(tests?.Where(i => i.Source == source).ToDictionary(i => i.FullyQualifiedName, i => i) ?? new Dictionary()); } - /// - /// Invoked for any operation on the original type. - /// - /// - public void Intercept(IInvocation invocation) + /// + protected override object Invoke(MethodInfo targetMethod, object[] args) { - switch (invocation.Method.Name) + switch (targetMethod.Name) { case "startingTestRun": - startingTestRun(invocation.Proxy, invocation.GetArgumentValue(0)); + startingTestRun(args[0]); break; case "startingTest": - startingTest(invocation.Proxy, invocation.GetArgumentValue(0)); + startingTest(args[0]); break; case "error": - error(invocation.Proxy, (string)invocation.GetArgumentValue(0)); + error((string)args[0]); break; case "stoppingTestRun": - stoppingTestRun(invocation.Proxy); + stoppingTestRun(); break; case "finishedTest": - finishedTest(invocation.Proxy, invocation.GetArgumentValue(0)); + finishedTest(args[0]); break; case "finishedTesting": - finishedTesting(invocation.Proxy); + finishedTesting(); break; case "finishedTestRun": - finishedTestRun(invocation.Proxy, (bool)invocation.GetArgumentValue(0)); - break; - default: - invocation.Proceed(); + finishedTestRun((bool)args[0]); break; } + + throw new InvalidOperationException(); } - public void startingTestRun(dynamic self, dynamic parameters) + void startingTestRun(dynamic parameters) { context.SendMessage(JTRegTestMessageLevel.Informational, $"JTReg: starting test run"); } - public void startingTest(dynamic self, dynamic testResult) + void startingTest(dynamic testResult) { var desc = testResult.getDescription(); var name = (string)Util.GetFullyQualifiedTestName(source, testSuite, desc); @@ -96,17 +96,17 @@ public void startingTest(dynamic self, dynamic testResult) context.RecordStart(test); } - public void error(dynamic self, string message) + void error(string message) { context.SendMessage(JTRegTestMessageLevel.Error, $"JTReg: error: '{message}'"); } - public void stoppingTestRun(dynamic self) + void stoppingTestRun() { context.SendMessage(JTRegTestMessageLevel.Informational, $"JTReg: stopping test run"); } - public void finishedTest(dynamic self, dynamic testResult) + void finishedTest(dynamic testResult) { var desc = testResult.getDescription(); var name = (string)Util.GetFullyQualifiedTestName(source, testSuite, desc); @@ -118,12 +118,12 @@ public void finishedTest(dynamic self, dynamic testResult) context.RecordResult(rslt); } - public void finishedTesting(dynamic self) + void finishedTesting() { context.SendMessage(JTRegTestMessageLevel.Informational, $"JTReg: finished testing"); } - public void finishedTestRun(dynamic self, bool success) + void finishedTestRun(bool success) { context.SendMessage(success ? JTRegTestMessageLevel.Informational : JTRegTestMessageLevel.Warning, $"JTReg: finished test run with overall result '{success}'"); } diff --git a/src/IKVM.JTReg.TestAdapter.Core/IKVM.JTReg.TestAdapter.Core.csproj b/src/IKVM.JTReg.TestAdapter.Core/IKVM.JTReg.TestAdapter.Core.csproj index 49898215b..83826c1e4 100644 --- a/src/IKVM.JTReg.TestAdapter.Core/IKVM.JTReg.TestAdapter.Core.csproj +++ b/src/IKVM.JTReg.TestAdapter.Core/IKVM.JTReg.TestAdapter.Core.csproj @@ -20,6 +20,7 @@ + diff --git a/src/IKVM.JTReg.TestAdapter/JTRegTestDiscoverer.cs b/src/IKVM.JTReg.TestAdapter/JTRegTestDiscoverer.cs index c4f9a52fd..4759b6909 100644 --- a/src/IKVM.JTReg.TestAdapter/JTRegTestDiscoverer.cs +++ b/src/IKVM.JTReg.TestAdapter/JTRegTestDiscoverer.cs @@ -43,6 +43,13 @@ public void DiscoverTests(IEnumerable sources, IDiscoveryContext discove /// public void DiscoverTests(IEnumerable sources, IDiscoveryContext discoveryContext, IMessageLogger logger, ITestCaseDiscoverySink discoverySink, CancellationToken cancellationToken) { + if (discoveryContext is null) + throw new ArgumentNullException(nameof(discoveryContext)); + if (logger is null) + throw new ArgumentNullException(nameof(logger)); + if (discoverySink is null) + throw new ArgumentNullException(nameof(discoverySink)); + foreach (var source in sources) { if (Path.GetExtension(source) is not ".exe" and not ".dll") diff --git a/src/IKVM.Runtime/DynamicClassLoader.cs b/src/IKVM.Runtime/DynamicClassLoader.cs index bd93ff2fc..ab9860866 100644 --- a/src/IKVM.Runtime/DynamicClassLoader.cs +++ b/src/IKVM.Runtime/DynamicClassLoader.cs @@ -575,7 +575,7 @@ public static IModuleSymbolBuilder CreateModuleBuilder(RuntimeContext context, A /// static IAssemblySymbolBuilder DefineDynamicAssembly(RuntimeContext context, AssemblyIdentity name, ICustomAttributeBuilder[] assemblyAttributes) { - return context.Resolver.Symbols.DefineAssembly(name, assemblyAttributes); + return context.Resolver.Symbols.DefineAssembly(name, assemblyAttributes, false, false); } } From 36f2f2c4876ae04805dded4d4c77436d74e8f0dc Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Mon, 7 Oct 2024 15:31:40 -0500 Subject: [PATCH 36/51] Hmm. --- src/IKVM.ConsoleApp/IKVM.ConsoleApp.csproj | 3 +- src/IKVM.ConsoleApp/Program.cs | 33 ++++++++++++++-------- src/ikvmstub/ikvmstub.csproj | 2 +- src/java/java.csproj | 2 +- src/javac/javac.csproj | 2 +- 5 files changed, 26 insertions(+), 16 deletions(-) diff --git a/src/IKVM.ConsoleApp/IKVM.ConsoleApp.csproj b/src/IKVM.ConsoleApp/IKVM.ConsoleApp.csproj index d8e11e329..eeb790913 100644 --- a/src/IKVM.ConsoleApp/IKVM.ConsoleApp.csproj +++ b/src/IKVM.ConsoleApp/IKVM.ConsoleApp.csproj @@ -6,13 +6,14 @@ Exe net481;net6.0;net8.0 - 11 x64 + + diff --git a/src/IKVM.ConsoleApp/Program.cs b/src/IKVM.ConsoleApp/Program.cs index ef839d360..4772ff69c 100644 --- a/src/IKVM.ConsoleApp/Program.cs +++ b/src/IKVM.ConsoleApp/Program.cs @@ -1,5 +1,6 @@ -using System; -using System.Diagnostics.Tracing; +using System.Threading; + +using IKVM.JTReg.TestAdapter.Core; namespace IKVM.ConsoleApp { @@ -7,21 +8,29 @@ namespace IKVM.ConsoleApp public class Program { - public static void Main(string[] args) + class MyDiscoverycontext : IJTRegDiscoveryContext { - var l = new Listener(); - var o = new java.lang.Object(); - java.lang.System.loadLibrary("hi"); - } - } + public JTRegTestOptions Options => new JTRegTestOptions() + { - class Listener : EventListener - { + }; + + public void SendMessage(JTRegTestMessageLevel level, string message) + { - protected override void OnEventWritten(EventWrittenEventArgs eventData) + } + + public void SendTestCase(JTRegTestCase testCase) + { + + } + + } + + public static void Main(string[] args) { - Console.WriteLine(eventData); + JTRegTestManager.Instance.DiscoverTests(@"D:\ikvm\src\IKVM.JTReg.TestAdapter.Tests\bin\Debug\net478\IKVM.JTReg.TestAdapter.Tests.dll", new MyDiscoverycontext(), CancellationToken.None); } } diff --git a/src/ikvmstub/ikvmstub.csproj b/src/ikvmstub/ikvmstub.csproj index f3f5a4191..e66f94dc4 100644 --- a/src/ikvmstub/ikvmstub.csproj +++ b/src/ikvmstub/ikvmstub.csproj @@ -1,7 +1,7 @@  Exe - net6.0;net8.0;net472; + net8.0;net6.0;net472; $(_SupportedToolRuntimes) true true diff --git a/src/java/java.csproj b/src/java/java.csproj index 50c47c7c4..c83f902fd 100644 --- a/src/java/java.csproj +++ b/src/java/java.csproj @@ -5,7 +5,7 @@ Exe - net472;net6.0;net8.0 + net8.0;net472;net6.0; $(_SupportedImageRuntimes) true ikvm.tools.java diff --git a/src/javac/javac.csproj b/src/javac/javac.csproj index b9c781086..e539ea8fd 100644 --- a/src/javac/javac.csproj +++ b/src/javac/javac.csproj @@ -5,7 +5,7 @@ Exe - net472;net6.0;net8.0 + net8.0;net472;net6.0 $(_SupportedImageRuntimes) true com.sun.tools.javac.Main From 8a8fa193da7f04950e2c7579e4841622a59c450a Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Mon, 7 Oct 2024 15:31:46 -0500 Subject: [PATCH 37/51] Hmm --- src/ikvmc/Properties/launchSettings.json | 2 +- src/ikvmstub/Properties/launchSettings.json | 8 ++++++++ src/java/Properties/launchSettings.json | 10 +++++----- src/javac/Properties/launchSettings.json | 14 +++++++------- 4 files changed, 21 insertions(+), 13 deletions(-) create mode 100644 src/ikvmstub/Properties/launchSettings.json diff --git a/src/ikvmc/Properties/launchSettings.json b/src/ikvmc/Properties/launchSettings.json index 150606624..d7c47f0f8 100644 --- a/src/ikvmc/Properties/launchSettings.json +++ b/src/ikvmc/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "ikvmc": { "commandName": "Project", - "commandLineArgs": "@D:\\ikvm\\src\\IKVM.Java.Tests\\obj\\Debug\\net8.0\\IKVM.Java.Tests.ikvmc.rsp" + "commandLineArgs": "@D:\\ikvm\\src\\IKVM.Java\\obj\\Debug\\net8.0\\IKVM.Java.ikvmc.rsp" } } } \ No newline at end of file diff --git a/src/ikvmstub/Properties/launchSettings.json b/src/ikvmstub/Properties/launchSettings.json new file mode 100644 index 000000000..27995bdb5 --- /dev/null +++ b/src/ikvmstub/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "ikvmstub": { + "commandName": "Project", + "commandLineArgs": "--bootstrap --nostdlib --parameters --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\Microsoft.Win32.Primitives.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Collections.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Collections.NonGeneric.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Collections.Specialized.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.ComponentModel.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.ComponentModel.Primitives.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Formats.Asn1.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Memory.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Net.HttpListener.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Net.Primitives.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Net.Security.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Net.WebHeaderCollection.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Net.WebSockets.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.ObjectModel.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Runtime.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Runtime.InteropServices.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Runtime.Numerics.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Security.Claims.dll\" --reference:\"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Security.Cryptography.dll\" --reference:\"D:\\ikvm\\src\\IKVM.Java\\bin\\Debug\\net8.0\\IKVM.Java.dll\" --reference:\"D:\\ikvm\\src\\IKVM.Runtime-ref\\obj\\Debug\\net8.0\\ref\\IKVM.Runtime.dll\" --out:\"System.Net.HttpListener.jar\" \"C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.8\\ref\\net8.0\\System.Net.HttpListener.dll\"" + } + } +} \ No newline at end of file diff --git a/src/java/Properties/launchSettings.json b/src/java/Properties/launchSettings.json index 00ad1de13..3c1b0f992 100644 --- a/src/java/Properties/launchSettings.json +++ b/src/java/Properties/launchSettings.json @@ -1,11 +1,11 @@ { "profiles": { "java": { - "commandName": "Project", - "commandLineArgs": "-version", - "environmentVariables": { - "IKVM_HOME_ROOT": "C:\\dev\\ikvm2\\src\\IKVM.Tests\\bin\\Debug\\net6.0\\ikvm\\" - } + "commandName": "Project", + "commandLineArgs": "-cp C:\\Users\\jhaltom\\Downloads Test", + "environmentVariables": { + "IKVM_HOME_ROOT": "D:\\ikvm\\src\\IKVM.Tests\\bin\\Debug\\net8.0\\ikvm\\" + } } } } \ No newline at end of file diff --git a/src/javac/Properties/launchSettings.json b/src/javac/Properties/launchSettings.json index b796f7ffd..daa0a7491 100644 --- a/src/javac/Properties/launchSettings.json +++ b/src/javac/Properties/launchSettings.json @@ -1,10 +1,10 @@ { - "profiles": { - "javac": { - "commandName": "Project", - "environmentVariables": { - "IKVM_HOME_ROOT": "C:\\dev\\ikvm2\\src\\IKVM.Tests\\bin\\Debug\\net6.0\\ikvm\\" - } - } + "profiles": { + "javac": { + "commandName": "Project", + "environmentVariables": { + "IKVM_HOME_ROOT": "D:\\ikvm\\src\\IKVM.Tests\\bin\\Debug\\net8.0\\ikvm\\" + } } + } } \ No newline at end of file From c597e1c32cf1c34e1a8fedc62dac41242776f548 Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Tue, 8 Oct 2024 18:57:46 -0500 Subject: [PATCH 38/51] Emit properties. The idea here is that a given symbol might need to be emitted as a different underlying type depending on the target. DynamicMethod requires RuntimeTypeHandles, and so cannot accept builders. But, building types on the fly to be used by DynamicMethods is a thing. Think this just worked out on accident previously. But now it's explicit. --- .../ReflectionConstructorSymbolBuilder.cs | 21 +- .../Emit/ReflectionEventSymbolBuilder.cs | 15 +- .../Emit/ReflectionFieldSymbolBuilder.cs | 18 +- ...ectionGenericTypeParameterSymbolBuilder.cs | 14 +- .../Reflection/Emit/ReflectionILGenerator.cs | 113 ++- .../Emit/ReflectionMemberSymbolBuilder.cs | 6 + .../Emit/ReflectionMethodBaseSymbolBuilder.cs | 6 + .../Emit/ReflectionMethodSymbolBuilder.cs | 22 +- .../Emit/ReflectionParameterSymbolBuilder.cs | 33 +- .../Emit/ReflectionPropertySymbolBuilder.cs | 16 +- .../Emit/ReflectionSymbolBuilder.cs | 2 +- .../Emit/ReflectionTypeSymbolBuilder.cs | 680 +----------------- .../IReflectionConstructorSymbol.cs | 10 + .../Reflection/IReflectionEventSymbol.cs | 5 + .../Reflection/IReflectionFieldSymbol.cs | 10 + .../Reflection/IReflectionMemberSymbol.cs | 5 + .../Reflection/IReflectionMethodBaseSymbol.cs | 7 +- .../Reflection/IReflectionMethodSymbol.cs | 10 + .../Reflection/IReflectionParameterSymbol.cs | 5 + .../Reflection/IReflectionPropertySymbol.cs | 5 + .../Reflection/IReflectionTypeSymbol.cs | 10 + .../Reflection/ReflectionArrayTypeSymbol.cs | 34 + .../Reflection/ReflectionByRefTypeSymbol.cs | 32 + .../Reflection/ReflectionConstructorSymbol.cs | 6 + .../Reflection/ReflectionEventSymbol.cs | 3 + .../Reflection/ReflectionFieldSymbol.cs | 6 + .../ReflectionGenericSpecTypeSymbol.cs | 35 + .../ReflectionGenericTypeParameterSymbol.cs | 6 + .../Reflection/ReflectionMemberSymbol.cs | 4 + .../Reflection/ReflectionMethodBaseSymbol.cs | 3 + .../Reflection/ReflectionMethodSymbol.cs | 6 + .../Reflection/ReflectionParameterSymbol.cs | 3 + .../Reflection/ReflectionPointerTypeSymbol.cs | 32 + .../Reflection/ReflectionPropertySymbol.cs | 3 + .../Reflection/ReflectionSZArrayTypeSymbol.cs | 32 + .../Reflection/ReflectionTypeSpecSymbol.cs | 37 + .../Reflection/ReflectionTypeSpecTable.cs | 25 +- .../Reflection/ReflectionTypeSymbol.cs | 633 +--------------- .../Reflection/ReflectionTypeSymbolBase.cs | 669 +++++++++++++++++ 39 files changed, 1185 insertions(+), 1397 deletions(-) create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/ReflectionArrayTypeSymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/ReflectionByRefTypeSymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericSpecTypeSymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/ReflectionPointerTypeSymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/ReflectionSZArrayTypeSymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSpecSymbol.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbolBase.cs diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionConstructorSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionConstructorSymbolBuilder.cs index 414a329ef..ab93503cd 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionConstructorSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionConstructorSymbolBuilder.cs @@ -10,8 +10,8 @@ namespace IKVM.CoreLib.Symbols.Reflection.Emit class ReflectionConstructorSymbolBuilder : ReflectionMethodBaseSymbolBuilder, IReflectionConstructorSymbolBuilder { - ConstructorBuilder? _builder; - ConstructorInfo _ctor; + readonly ConstructorBuilder _builder; + ConstructorInfo? _ctor; ReflectionILGenerator? _il; @@ -27,17 +27,25 @@ public ReflectionConstructorSymbolBuilder(ReflectionSymbolContext context, IRefl base(context, resolvingModule, resolvingType) { _builder = builder ?? throw new ArgumentNullException(nameof(builder)); - _ctor = _builder; } /// - public ConstructorInfo UnderlyingConstructor => _ctor; + public ConstructorInfo UnderlyingConstructor => _ctor ?? _builder; + + /// + public ConstructorInfo UnderlyingEmitConstructor => _builder; + + /// + public ConstructorInfo UnderlyingDynamicEmitConstructor => _ctor ?? throw new InvalidOperationException(); /// public override MethodBase UnderlyingMethodBase => UnderlyingConstructor; /// - public ConstructorBuilder UnderlyingConstructorBuilder => _builder ?? throw new InvalidOperationException(); + public override MethodBase UnderlyingEmitMethodBase => UnderlyingEmitConstructor; + + /// + public ConstructorBuilder UnderlyingConstructorBuilder => _builder; #region IConstructorSymbolBuilder @@ -85,7 +93,7 @@ public override void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAtt #region IConstructorSymbol /// - public override bool IsComplete => _builder == null; + public override bool IsComplete => _ctor != null; #endregion @@ -104,7 +112,6 @@ public override ITypeSymbol[] GetGenericArguments() public override void OnComplete() { _ctor = (ConstructorInfo?)ResolvingModule.UnderlyingModule.ResolveMethod(MetadataToken) ?? throw new InvalidOperationException(); - _builder = null; base.OnComplete(); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionEventSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionEventSymbolBuilder.cs index 024141801..9525d0045 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionEventSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionEventSymbolBuilder.cs @@ -10,8 +10,9 @@ namespace IKVM.CoreLib.Symbols.Reflection.Emit class ReflectionEventSymbolBuilder : ReflectionMemberSymbolBuilder, IReflectionEventSymbolBuilder { - EventBuilder? _builder; - EventInfo _event; + readonly EventBuilder _builder; + readonly ReflectionEventBuilderInfo _builderInfo; + EventInfo? _event; /// /// Initializes a new instance. @@ -25,11 +26,14 @@ public ReflectionEventSymbolBuilder(ReflectionSymbolContext context, IReflection base(context, resolvingModule, resolvingType) { _builder = builder ?? throw new ArgumentNullException(nameof(builder)); - _event = new ReflectionEventBuilderInfo(_builder); + _builderInfo = new ReflectionEventBuilderInfo(_builder); } /// - public EventInfo UnderlyingEvent => _event; + public EventInfo UnderlyingEvent => _event ?? _builderInfo; + + /// + public EventInfo UnderlyingEmitEvent => UnderlyingEvent; /// public EventBuilder UnderlyingEventBuilder => _builder ?? throw new NotImplementedException(); @@ -98,7 +102,7 @@ public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) public IMethodSymbol? RaiseMethod => ResolveMethodSymbol(UnderlyingEvent.RaiseMethod); /// - public override bool IsComplete => _builder == null; + public override bool IsComplete => _event != null; /// public IMethodSymbol? GetAddMethod() @@ -154,7 +158,6 @@ public IMethodSymbol[] GetOtherMethods(bool nonPublic) public override void OnComplete() { _event = (EventInfo?)ResolvingModule.UnderlyingModule.ResolveMember(MetadataToken) ?? throw new InvalidOperationException(); - _builder = null; base.OnComplete(); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionFieldSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionFieldSymbolBuilder.cs index 1c96e8bd8..91186b5ad 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionFieldSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionFieldSymbolBuilder.cs @@ -10,8 +10,8 @@ namespace IKVM.CoreLib.Symbols.Reflection.Emit class ReflectionFieldSymbolBuilder : ReflectionMemberSymbolBuilder, IReflectionFieldSymbolBuilder { - FieldBuilder? _builder; - FieldInfo _field; + readonly FieldBuilder _builder; + FieldInfo? _field; /// /// Initializes a new instance. @@ -25,17 +25,22 @@ public ReflectionFieldSymbolBuilder(ReflectionSymbolContext context, IReflection base(context, resolvingModule, resolvingType) { _builder = builder ?? throw new ArgumentNullException(nameof(builder)); - _field = _builder; } /// - public FieldInfo UnderlyingField => _field; + public FieldInfo UnderlyingField => _field ?? _builder; + + /// + public FieldInfo UnderlyingEmitField => _builder; + + /// + public FieldInfo UnderlyingDynamicEmitField => _field ?? throw new InvalidOperationException(); /// public override MemberInfo UnderlyingMember => UnderlyingField; /// - public FieldBuilder UnderlyingFieldBuilder => _builder ?? throw new InvalidOperationException(); + public FieldBuilder UnderlyingFieldBuilder => _builder; #region IFieldSymbolBuilder @@ -110,7 +115,7 @@ public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) public bool IsStatic => UnderlyingField.IsStatic; /// - public override bool IsComplete => _builder == null; + public override bool IsComplete => _field != null; /// public ITypeSymbol[] GetOptionalCustomModifiers() @@ -136,7 +141,6 @@ public ITypeSymbol[] GetRequiredCustomModifiers() public override void OnComplete() { _field = ResolvingModule.UnderlyingModule.ResolveField(MetadataToken) ?? throw new InvalidOperationException(); - _builder = null; base.OnComplete(); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionGenericTypeParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionGenericTypeParameterSymbolBuilder.cs index 6bced14f4..37c8c2b5c 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionGenericTypeParameterSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionGenericTypeParameterSymbolBuilder.cs @@ -11,9 +11,8 @@ class ReflectionGenericTypeParameterSymbolBuilder : ReflectionMemberSymbolBuilde { readonly IReflectionMemberSymbol? _resolvingMember; - - GenericTypeParameterBuilder? _builder; - Type _type; + readonly GenericTypeParameterBuilder _builder; + Type? _type; ReflectionTypeSpecTable _specTable; @@ -30,12 +29,17 @@ public ReflectionGenericTypeParameterSymbolBuilder(ReflectionSymbolContext conte { _resolvingMember = resolvingMember ?? throw new ArgumentNullException(nameof(resolvingMember)); _builder = builder ?? throw new ArgumentNullException(nameof(builder)); - _type = _builder; _specTable = new ReflectionTypeSpecTable(); } /// - public Type UnderlyingType => _type; + public Type UnderlyingType => _type ?? _builder; + + /// + public Type UnderlyingEmitType => UnderlyingType; + + /// + public Type UnderlyingDynamicEmitType => _type ?? throw new InvalidOperationException(); /// public override MemberInfo UnderlyingMember => UnderlyingType; diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionILGenerator.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionILGenerator.cs index ee009451e..4cbac54c0 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionILGenerator.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionILGenerator.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.Diagnostics.SymbolStore; using System.Reflection; using System.Reflection.Emit; @@ -14,25 +15,86 @@ class ReflectionILGenerator : IILGenerator readonly ReflectionSymbolContext _context; readonly ILGenerator _il; + readonly bool _dynamic = false; /// /// Initializes a new instance. /// + /// /// - public ReflectionILGenerator(ReflectionSymbolContext context, ILGenerator il) + /// + /// + public ReflectionILGenerator(ReflectionSymbolContext context, ILGenerator il, bool dynamic = false) { _context = context ?? throw new ArgumentNullException(nameof(context)); _il = il ?? throw new ArgumentNullException(nameof(il)); + _dynamic = dynamic; } /// public int ILOffset => _il.ILOffset; + /// + /// Gets the underlying emit type for the given . + /// + /// + /// + [return: NotNullIfNotNull(nameof(symbol))] + Type? GetEmitType(ITypeSymbol? symbol) + { + var n = symbol.Name; + if (_dynamic) + return ((IReflectionTypeSymbol?)symbol)?.UnderlyingDynamicEmitType; + else + return ((IReflectionTypeSymbol?)symbol)?.UnderlyingEmitType; + } + + /// + /// Gets the underlying emit type for the given . + /// + /// + /// + [return: NotNullIfNotNull(nameof(symbol))] + FieldInfo? GetEmitField(IFieldSymbol? symbol) + { + if (_dynamic) + return ((IReflectionFieldSymbol?)symbol)?.UnderlyingDynamicEmitField; + else + return ((IReflectionFieldSymbol?)symbol)?.UnderlyingEmitField; + } + + /// + /// Gets the underlying emit type for the given . + /// + /// + /// + [return: NotNullIfNotNull(nameof(symbol))] + ConstructorInfo? GetEmitConstructor(IConstructorSymbol? symbol) + { + if (_dynamic) + return ((IReflectionConstructorSymbol?)symbol)?.UnderlyingDynamicEmitConstructor; + else + return ((IReflectionConstructorSymbol?)symbol)?.UnderlyingEmitConstructor; + } + + /// + /// Gets the underlying emit type for the given . + /// + /// + /// + [return: NotNullIfNotNull(nameof(symbol))] + MethodInfo? GetEmitMethod(IMethodSymbol? symbol) + { + if (_dynamic) + return ((IReflectionMethodSymbol?)symbol)?.UnderlyingDynamicEmitMethod; + else + return ((IReflectionMethodSymbol?)symbol)?.UnderlyingEmitMethod; + } + /// public void BeginCatchBlock(ITypeSymbol? exceptionType) { - _il.BeginCatchBlock(exceptionType?.Unpack()!); - + _il.BeginCatchBlock(GetEmitType(exceptionType)!); } /// @@ -68,13 +130,13 @@ public void BeginScope() /// public ILocalBuilder DeclareLocal(ITypeSymbol localType, bool pinned) { - return new ReflectionLocalBuilder(_context, _il.DeclareLocal(localType.Unpack(), pinned)); + return new ReflectionLocalBuilder(_context, _il.DeclareLocal(GetEmitType(localType), pinned)); } /// public ILocalBuilder DeclareLocal(ITypeSymbol localType) { - return new ReflectionLocalBuilder(_context, _il.DeclareLocal(localType.Unpack())); + return new ReflectionLocalBuilder(_context, _il.DeclareLocal(GetEmitType(localType))); } /// @@ -84,64 +146,63 @@ public ILabel DefineLabel() } /// - public void Emit(OpCode opcode, ILocalBuilder local) + public void Emit(OpCode opcode, ITypeSymbol cls) { - _il.Emit(opcode, local.Unpack()); + _il.Emit(opcode, GetEmitType(cls)); } /// - public void Emit(OpCode opcode, ITypeSymbol cls) + public void Emit(OpCode opcode, IFieldSymbol field) { - _il.Emit(opcode, cls.Unpack()); + _il.Emit(opcode, GetEmitField(field)); } /// - public void Emit(OpCode opcode, string str) + public void Emit(OpCode opcode, IConstructorSymbol con) { - _il.Emit(opcode, str); + _il.Emit(opcode, GetEmitConstructor(con)); } /// - public void Emit(OpCode opcode, float arg) + public void Emit(OpCode opcode, IMethodSymbol method) { - _il.Emit(opcode, arg); + _il.Emit(opcode, GetEmitMethod(method)); } /// - public void Emit(OpCode opcode, sbyte arg) + public void Emit(OpCode opcode, ISignatureHelper signature) { - _il.Emit(opcode, arg); + throw new NotImplementedException(); } /// - public void Emit(OpCode opcode, IMethodSymbol meth) + public void Emit(OpCode opcode, ILabel[] labels) { - _il.Emit(opcode, meth.Unpack()); + _il.Emit(opcode, labels.Unpack()); } /// - public void Emit(OpCode opcode, ISignatureHelper signature) + public void Emit(OpCode opcode, ILocalBuilder local) { - throw new NotImplementedException(); - //_il.Emit(opcode, signature.Unpack()); + _il.Emit(opcode, local.Unpack()); } /// - public void Emit(OpCode opcode, ILabel[] labels) + public void Emit(OpCode opcode, string str) { - _il.Emit(opcode, labels.Unpack()); + _il.Emit(opcode, str); } /// - public void Emit(OpCode opcode, IFieldSymbol field) + public void Emit(OpCode opcode, float arg) { - _il.Emit(opcode, field.Unpack()); + _il.Emit(opcode, arg); } /// - public void Emit(OpCode opcode, IConstructorSymbol con) + public void Emit(OpCode opcode, sbyte arg) { - _il.Emit(opcode, con.Unpack()); + _il.Emit(opcode, arg); } /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMemberSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMemberSymbolBuilder.cs index b0ee71636..b093a18e1 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMemberSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMemberSymbolBuilder.cs @@ -33,6 +33,9 @@ public ReflectionMemberSymbolBuilder(ReflectionSymbolContext context, IReflectio /// public abstract MemberInfo UnderlyingMember { get; } + /// + public virtual MemberInfo UnderlyingEmitMember => UnderlyingMember; + /// public IReflectionModuleSymbol ResolvingModule => _resolvingModule; @@ -337,6 +340,9 @@ public virtual void OnComplete() } + /// + public override string? ToString() => UnderlyingMember.ToString(); + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodBaseSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodBaseSymbolBuilder.cs index 990e9379c..eabf450d1 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodBaseSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodBaseSymbolBuilder.cs @@ -26,9 +26,15 @@ public ReflectionMethodBaseSymbolBuilder(ReflectionSymbolContext context, IRefle /// public abstract MethodBase UnderlyingMethodBase { get; } + /// + public virtual MethodBase UnderlyingEmitMethodBase => UnderlyingMethodBase; + /// public override MemberInfo UnderlyingMember => UnderlyingMethodBase; + /// + public override MemberInfo UnderlyingEmitMember => UnderlyingEmitMethodBase; + #region IReflectionMethodBaseSymbol /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs index c071e4f5f..c43c26618 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs @@ -2,7 +2,6 @@ using System.Reflection; using System.Reflection.Emit; -using IKVM.CoreLib.Reflection; using IKVM.CoreLib.Symbols.Emit; namespace IKVM.CoreLib.Symbols.Reflection.Emit @@ -11,8 +10,8 @@ namespace IKVM.CoreLib.Symbols.Reflection.Emit class ReflectionMethodSymbolBuilder : ReflectionMethodBaseSymbolBuilder, IReflectionMethodSymbolBuilder { - MethodBuilder? _builder; - MethodInfo _method; + readonly MethodBuilder _builder; + MethodInfo? _method; ReflectionGenericTypeParameterTable _genericTypeParameterTable; ReflectionMethodSpecTable _specTable; @@ -31,19 +30,27 @@ public ReflectionMethodSymbolBuilder(ReflectionSymbolContext context, IReflectio base(context, resolvingModule, resolvingType) { _builder = builder ?? throw new ArgumentNullException(nameof(builder)); - _method = _builder; _genericTypeParameterTable = new ReflectionGenericTypeParameterTable(context, resolvingModule, this); _specTable = new ReflectionMethodSpecTable(context, resolvingModule, resolvingType, this); } /// - public MethodInfo UnderlyingMethod => _method; + public MethodInfo UnderlyingMethod => _method ?? _builder; + + /// + public MethodInfo UnderlyingEmitMethod => _builder; + + /// + public MethodInfo UnderlyingDynamicEmitMethod => _method ?? throw new InvalidOperationException(); /// public override MethodBase UnderlyingMethodBase => UnderlyingMethod; /// - public MethodBuilder UnderlyingMethodBuilder => _builder ?? throw new InvalidOperationException(); + public override MethodBase UnderlyingEmitMethodBase => UnderlyingEmitMethod; + + /// + public MethodBuilder UnderlyingMethodBuilder => _builder; #region IReflectionMethodSymbolBuilder @@ -163,7 +170,7 @@ public IGenericTypeParameterSymbolBuilder[] DefineGenericParameters(params strin public ICustomAttributeProvider ReturnTypeCustomAttributes => throw new NotImplementedException(); /// - public override bool IsComplete => _builder == null; + public override bool IsComplete => _method != null; /// public IMethodSymbol GetBaseDefinition() @@ -189,7 +196,6 @@ public IMethodSymbol MakeGenericMethod(params ITypeSymbol[] typeArguments) public override void OnComplete() { _method = (MethodInfo?)ResolvingModule.UnderlyingModule.ResolveMethod(MetadataToken) ?? throw new InvalidOperationException(); - _builder = null; base.OnComplete(); } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionParameterSymbolBuilder.cs index 20209ba1d..760ce9921 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionParameterSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionParameterSymbolBuilder.cs @@ -14,7 +14,8 @@ class ReflectionParameterSymbolBuilder : ReflectionSymbolBuilder, IReflectionPar readonly IReflectionModuleSymbol _module; readonly IReflectionMemberSymbol _member; - ParameterBuilder? _builder; + readonly ParameterBuilder _builder; + readonly ReflectionParameterBuilderInfo _builderInfo; ParameterInfo _parameter; object? _constant; @@ -32,7 +33,7 @@ public ReflectionParameterSymbolBuilder(ReflectionSymbolContext context, IReflec _module = module ?? throw new ArgumentNullException(nameof(module)); _member = member ?? throw new ArgumentNullException(nameof(member)); _builder = builder ?? throw new ArgumentNullException(nameof(builder)); - _parameter = new ReflectionParameterBuilderInfo(builder, () => _constant); + _builderInfo = new ReflectionParameterBuilderInfo(builder, () => _constant); } /// @@ -42,10 +43,13 @@ public ReflectionParameterSymbolBuilder(ReflectionSymbolContext context, IReflec public IReflectionMemberSymbol ResolvingMember => _member; /// - public ParameterInfo UnderlyingParameter => _parameter; + public ParameterInfo UnderlyingParameter => _parameter ?? _builderInfo; /// - public ParameterBuilder UnderlyingParameterBuilder => _builder ?? throw new InvalidOperationException(); + public ParameterInfo UnderlyingEmitParameter => _parameter ?? throw new InvalidOperationException(); + + /// + public ParameterBuilder UnderlyingParameterBuilder => _builder; #region IParameterSymbolBuilder @@ -111,14 +115,7 @@ public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) public int Position => UnderlyingParameter.Position; /// - public override bool IsComplete - { - get - { - lock (this) - return _builder == null; - } - } + public override bool IsComplete => _parameter != null; /// public CustomAttribute[] GetCustomAttributes(bool inherit = false) @@ -165,17 +162,7 @@ public void OnComplete(ParameterInfo parameter) if (parameter is null) throw new ArgumentNullException(nameof(parameter)); - if (IsComplete == false) - { - lock (this) - { - if (IsComplete == false) - { - _parameter = parameter; - _builder = null; - } - } - } + _parameter = parameter; } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionPropertySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionPropertySymbolBuilder.cs index 99859af76..d25067236 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionPropertySymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionPropertySymbolBuilder.cs @@ -10,8 +10,8 @@ namespace IKVM.CoreLib.Symbols.Reflection.Emit class ReflectionPropertySymbolBuilder : ReflectionMemberSymbolBuilder, IReflectionPropertySymbolBuilder { - PropertyBuilder? _builder; - PropertyInfo _property; + PropertyBuilder _builder; + PropertyInfo? _property; ReflectionParameterTable _parameterTable; @@ -27,12 +27,14 @@ public ReflectionPropertySymbolBuilder(ReflectionSymbolContext context, IReflect base(context, resolvingModule, resolvingType) { _builder = builder ?? throw new ArgumentNullException(nameof(builder)); - _property = _builder; _parameterTable = new ReflectionParameterTable(context, resolvingModule, this); } /// - public PropertyInfo UnderlyingProperty => _property; + public PropertyInfo UnderlyingProperty => _property ?? _builder; + + /// + public PropertyInfo UnderlyingEmitProperty => UnderlyingProperty; /// public PropertyBuilder UnderlyingPropertyBuilder => _builder ?? throw new InvalidOperationException(); @@ -40,6 +42,9 @@ public ReflectionPropertySymbolBuilder(ReflectionSymbolContext context, IReflect /// public override MemberInfo UnderlyingMember => UnderlyingProperty; + /// + public override MemberInfo UnderlyingEmitMember => UnderlyingEmitProperty; + #region IReflectionPropertySymbolBuilder /// @@ -124,7 +129,7 @@ public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) public IMethodSymbol? SetMethod => ResolveMethodSymbol(UnderlyingProperty.SetMethod); /// - public override bool IsComplete => _builder == null; + public override bool IsComplete => _property != null; /// public object? GetRawConstantValue() @@ -198,7 +203,6 @@ public ITypeSymbol[] GetRequiredCustomModifiers() public override void OnComplete() { _property = (PropertyInfo?)ResolvingModule.UnderlyingModule.ResolveMember(MetadataToken) ?? throw new InvalidOperationException(); - _builder = null; base.OnComplete(); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionSymbolBuilder.cs index 902317749..a21ac8944 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionSymbolBuilder.cs @@ -23,7 +23,7 @@ protected ReflectionSymbolBuilder(ReflectionSymbolContext context) : } /// - [return: NotNullIfNotNull("genericTypeParameter")] + [return: NotNullIfNotNull(nameof(genericTypeParameter))] public IReflectionGenericTypeParameterSymbolBuilder? ResolveGenericTypeParameterSymbol(GenericTypeParameterBuilder genericTypeParameter) { return Context.GetOrCreateGenericTypeParameterSymbol(genericTypeParameter); diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs index 31c468853..5ce8a95be 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs @@ -1,28 +1,20 @@ using System; using System.Collections.Generic; -using System.Linq; +using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Reflection.Emit; using System.Runtime.InteropServices; -using IKVM.CoreLib.Reflection; using IKVM.CoreLib.Symbols.Emit; namespace IKVM.CoreLib.Symbols.Reflection.Emit { - class ReflectionTypeSymbolBuilder : ReflectionMemberSymbolBuilder, IReflectionTypeSymbolBuilder + class ReflectionTypeSymbolBuilder : ReflectionTypeSymbolBase, IReflectionTypeSymbolBuilder { - TypeBuilder? _builder; - Type _type; - - ReflectionMethodTable _methodTable; - ReflectionFieldTable _fieldTable; - ReflectionPropertyTable _propertyTable; - ReflectionEventTable _eventTable; - ReflectionGenericTypeParameterTable _genericTypeParameterTable; - ReflectionTypeSpecTable _specTable; + readonly TypeBuilder _builder; + Type? _type; List? _incompleteMethods; @@ -33,105 +25,33 @@ class ReflectionTypeSymbolBuilder : ReflectionMemberSymbolBuilder, IReflectionTy /// /// public ReflectionTypeSymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbolBuilder module, TypeBuilder builder) : - base(context, module, null) + base(context, module) { _builder = builder ?? throw new ArgumentNullException(nameof(builder)); - _type = _builder; - _methodTable = new ReflectionMethodTable(context, module, this); - _fieldTable = new ReflectionFieldTable(context, module, this); - _propertyTable = new ReflectionPropertyTable(context, module, this); - _eventTable = new ReflectionEventTable(context, module, this); - _genericTypeParameterTable = new ReflectionGenericTypeParameterTable(context, module, this); - _specTable = new ReflectionTypeSpecTable(context, module, this); } /// - public Type UnderlyingType => _type; - - /// - public override MemberInfo UnderlyingMember => UnderlyingType; + public override Type UnderlyingType => _type ?? _builder; /// - public TypeBuilder UnderlyingTypeBuilder => _builder ?? throw new InvalidOperationException(); - - #region ReflectionTypeSymbol - - /// - public IReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) - { - return _methodTable.GetOrCreateConstructorSymbol(ctor); - } - - /// - public IReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method) - { - return _methodTable.GetOrCreateMethodBaseSymbol(method); - } + public override Type UnderlyingEmitType => _builder; /// - public IReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) - { - return _methodTable.GetOrCreateMethodSymbol(method); - } + public override Type UnderlyingDynamicEmitType => _type ?? throw new InvalidOperationException(); /// - public IReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) - { - return _fieldTable.GetOrCreateFieldSymbol(field); - } + public TypeBuilder UnderlyingTypeBuilder => _builder; /// - public IReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) - { - return _propertyTable.GetOrCreatePropertySymbol(property); - } + public IReflectionModuleSymbolBuilder ResolvingModuleBuilder => (IReflectionModuleSymbolBuilder)ResolvingModule; - /// - public IReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) - { - return _eventTable.GetOrCreateEventSymbol(@event); - } + #region IReflectionSymbolBuilder /// - public IReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type genericTypeParameter) + [return: NotNullIfNotNull("genericTypeParameter")] + public IReflectionGenericTypeParameterSymbolBuilder? ResolveGenericTypeParameterSymbol(GenericTypeParameterBuilder genericTypeParameter) { - return _genericTypeParameterTable.GetOrCreateGenericTypeParameterSymbol(genericTypeParameter); - } - - /// - public IReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeParameterSymbol(GenericTypeParameterBuilder genericTypeParameter) - { - return _genericTypeParameterTable.GetOrCreateGenericTypeParameterSymbol(genericTypeParameter); - } - - /// - public IReflectionTypeSymbol GetOrCreateSZArrayTypeSymbol() - { - return _specTable.GetOrCreateSZArrayTypeSymbol(); - } - - /// - public IReflectionTypeSymbol GetOrCreateArrayTypeSymbol(int rank) - { - return _specTable.GetOrCreateArrayTypeSymbol(rank); - } - - /// - public IReflectionTypeSymbol GetOrCreatePointerTypeSymbol() - { - return _specTable.GetOrCreatePointerTypeSymbol(); - } - - /// - public IReflectionTypeSymbol GetOrCreateByRefTypeSymbol() - { - return _specTable.GetOrCreateByRefTypeSymbol(); - } - - /// - public IReflectionTypeSymbol GetOrCreateGenericTypeSymbol(IReflectionTypeSymbol[] genericTypeDefinition) - { - return _specTable.GetOrCreateGenericTypeSymbol(genericTypeDefinition); + return Context.GetOrCreateGenericTypeParameterSymbol(genericTypeParameter); } #endregion @@ -391,571 +311,6 @@ public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) #endregion - #region ITypeSymbol - - /// - public IAssemblySymbol Assembly => ResolveAssemblySymbol(UnderlyingType.Assembly); - - /// - public string? AssemblyQualifiedName => UnderlyingType.AssemblyQualifiedName; - - /// - public System.Reflection.TypeAttributes Attributes => (System.Reflection.TypeAttributes)UnderlyingType.Attributes; - - /// - public ITypeSymbol? BaseType => ResolveTypeSymbol(UnderlyingType.BaseType); - - /// - public bool ContainsGenericParameters => UnderlyingType.ContainsGenericParameters; - - /// - public IMethodBaseSymbol? DeclaringMethod => ResolveMethodBaseSymbol(UnderlyingType.DeclaringMethod); - - /// - public string? FullName => UnderlyingType.FullName; - - /// - public string? Namespace => UnderlyingType.Namespace; - - /// - public System.Reflection.GenericParameterAttributes GenericParameterAttributes => (System.Reflection.GenericParameterAttributes)UnderlyingType.GenericParameterAttributes; - - /// - public int GenericParameterPosition => UnderlyingType.GenericParameterPosition; - - /// - public ITypeSymbol[] GenericTypeArguments => ResolveTypeSymbols(UnderlyingType.GenericTypeArguments); - - /// - public bool HasElementType => UnderlyingType.HasElementType; - - /// - public TypeCode TypeCode => Type.GetTypeCode(UnderlyingType); - - /// - public bool IsAbstract => UnderlyingType.IsAbstract; - - /// - public bool IsSZArray => UnderlyingType.IsSZArray(); - - /// - public bool IsArray => UnderlyingType.IsArray; - - /// - public bool IsAutoLayout => UnderlyingType.IsAutoLayout; - - /// - public bool IsExplicitLayout => UnderlyingType.IsExplicitLayout; - - /// - public bool IsByRef => UnderlyingType.IsByRef; - - /// - public bool IsClass => UnderlyingType.IsClass; - - /// - public bool IsEnum => UnderlyingType.IsEnum; - - /// - public bool IsInterface => UnderlyingType.IsInterface; - - /// - public bool IsConstructedGenericType => UnderlyingType.IsConstructedGenericType; - - /// - public bool IsGenericParameter => UnderlyingType.IsGenericParameter; - - /// - public bool IsGenericType => UnderlyingType.IsGenericType; - - /// - public bool IsGenericTypeDefinition => UnderlyingType.IsGenericTypeDefinition; - - /// - public bool IsLayoutSequential => UnderlyingType.IsLayoutSequential; - - /// - public bool IsNested => UnderlyingType.IsNested; - - /// - public bool IsNestedAssembly => UnderlyingType.IsNestedAssembly; - - /// - public bool IsNestedFamANDAssem => UnderlyingType.IsNestedFamANDAssem; - - /// - public bool IsNestedFamORAssem => UnderlyingType.IsNestedFamORAssem; - - /// - public bool IsNestedFamily => UnderlyingType.IsNestedFamily; - - /// - public bool IsNestedPrivate => UnderlyingType.IsNestedPrivate; - - /// - public bool IsNestedPublic => UnderlyingType.IsNestedPublic; - - /// - public bool IsNotPublic => UnderlyingType.IsNotPublic; - - /// - public bool IsPointer => UnderlyingType.IsPointer; - -#if NET8_0_OR_GREATER - - /// - public bool IsFunctionPointer => UnderlyingType.IsFunctionPointer; - - /// - public bool IsUnmanagedFunctionPointer => UnderlyingType.IsUnmanagedFunctionPointer; - -#else - - /// - public bool IsFunctionPointer => throw new NotImplementedException(); - - /// - public bool IsUnmanagedFunctionPointer => throw new NotImplementedException(); - -#endif - - /// - public bool IsPrimitive => UnderlyingType.IsPrimitive; - - /// - public bool IsPublic => UnderlyingType.IsPublic; - - /// - public bool IsSealed => UnderlyingType.IsSealed; - - /// - public bool IsSerializable => UnderlyingType.IsSerializable; - - /// - public bool IsValueType => UnderlyingType.IsValueType; - - /// - public bool IsVisible => UnderlyingType.IsVisible; - - /// - public bool IsSignatureType => throw new NotImplementedException(); - - /// - public bool IsSpecialName => UnderlyingType.IsSpecialName; - - /// - public IConstructorSymbol? TypeInitializer => ResolveConstructorSymbol(UnderlyingType.TypeInitializer); - - /// - public override bool IsComplete => _builder == null; - - /// - public int GetArrayRank() - { - return UnderlyingType.GetArrayRank(); - } - - /// - public IConstructorSymbol? GetConstructor(BindingFlags bindingAttr, ITypeSymbol[] types) - { - return ResolveConstructorSymbol(UnderlyingType.GetConstructor((BindingFlags)bindingAttr, binder: null, types.Unpack(), modifiers: null)); - } - - /// - public IConstructorSymbol? GetConstructor(ITypeSymbol[] types) - { - return ResolveConstructorSymbol(UnderlyingType.GetConstructor(types.Unpack())); - } - - /// - public IConstructorSymbol[] GetConstructors() - { - return ResolveConstructorSymbols(UnderlyingType.GetConstructors()); - } - - /// - public IConstructorSymbol[] GetConstructors(BindingFlags bindingAttr) - { - return ResolveConstructorSymbols(UnderlyingType.GetConstructors((BindingFlags)bindingAttr)); - } - - /// - public IMemberSymbol[] GetDefaultMembers() - { - return ResolveMemberSymbols(UnderlyingType.GetDefaultMembers()); - } - - /// - public ITypeSymbol? GetElementType() - { - return ResolveTypeSymbol(UnderlyingType.GetElementType()); - } - - /// - public string? GetEnumName(object value) - { - return UnderlyingType.GetEnumName(value); - } - - /// - public string[] GetEnumNames() - { - return UnderlyingType.GetEnumNames(); - } - - /// - public ITypeSymbol GetEnumUnderlyingType() - { - return ResolveTypeSymbol(UnderlyingType.GetEnumUnderlyingType()); - } - - /// - public Array GetEnumValues() - { - return UnderlyingType.GetEnumValues(); - } - - /// - public IEventSymbol? GetEvent(string name) - { - return ResolveEventSymbol(UnderlyingType.GetEvent(name)); - } - - /// - public IEventSymbol? GetEvent(string name, BindingFlags bindingAttr) - { - return ResolveEventSymbol(UnderlyingType.GetEvent(name, (BindingFlags)bindingAttr)); - } - - /// - public IEventSymbol[] GetEvents() - { - return ResolveEventSymbols(UnderlyingType.GetEvents()); - } - - /// - public IEventSymbol[] GetEvents(BindingFlags bindingAttr) - { - return ResolveEventSymbols(UnderlyingType.GetEvents((BindingFlags)bindingAttr)); - } - - /// - public IFieldSymbol? GetField(string name) - { - return ResolveFieldSymbol(UnderlyingType.GetField(name)); - } - - /// - public IFieldSymbol? GetField(string name, BindingFlags bindingAttr) - { - return ResolveFieldSymbol(UnderlyingType.GetField(name, (BindingFlags)bindingAttr)); - } - - /// - public IFieldSymbol[] GetFields() - { - return ResolveFieldSymbols(UnderlyingType.GetFields()); - } - - /// - public IFieldSymbol[] GetFields(BindingFlags bindingAttr) - { - return ResolveFieldSymbols(UnderlyingType.GetFields((BindingFlags)bindingAttr)); - } - - /// - public ITypeSymbol[] GetGenericArguments() - { - return ResolveTypeSymbols(UnderlyingType.GetGenericArguments()); - } - - /// - public ITypeSymbol[] GetGenericParameterConstraints() - { - return ResolveTypeSymbols(UnderlyingType.GetGenericParameterConstraints()); - } - - /// - public ITypeSymbol GetGenericTypeDefinition() - { - return ResolveTypeSymbol(UnderlyingType.GetGenericTypeDefinition()); - } - - /// - public ITypeSymbol? GetInterface(string name) - { - return ResolveTypeSymbol(UnderlyingType.GetInterface(name)); - } - - /// - public ITypeSymbol? GetInterface(string name, bool ignoreCase) - { - return ResolveTypeSymbol(UnderlyingType.GetInterface(name, ignoreCase)); - } - - /// - public InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) - { - throw new NotImplementedException(); - } - - /// - public ITypeSymbol[] GetInterfaces(bool inherit = true) - { - if (inherit) - return ResolveTypeSymbols(UnderlyingType.GetInterfaces()); - else - throw new NotImplementedException(); - } - - /// - public IMemberSymbol[] GetMember(string name) - { - return ResolveMemberSymbols(UnderlyingType.GetMember(name)); - } - - /// - public IMemberSymbol[] GetMember(string name, BindingFlags bindingAttr) - { - return ResolveMemberSymbols(UnderlyingType.GetMember(name, (BindingFlags)bindingAttr)); - } - - /// - public IMemberSymbol[] GetMember(string name, System.Reflection.MemberTypes type, BindingFlags bindingAttr) - { - return ResolveMemberSymbols(UnderlyingType.GetMember(name, (MemberTypes)type, (BindingFlags)bindingAttr)); - } - - /// - public IMemberSymbol[] GetMembers(BindingFlags bindingAttr) - { - return ResolveMemberSymbols(UnderlyingType.GetMembers((BindingFlags)bindingAttr)); - } - - /// - public IMemberSymbol[] GetMembers() - { - return ResolveMemberSymbols(UnderlyingType.GetMembers()); - } - - /// - public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr) - { - if (IsComplete) - return ResolveMethodSymbol(UnderlyingType.GetMethod(name, bindingAttr)); - else - return GetIncompleteMethods(bindingAttr).FirstOrDefault(i => i.Name == name); - } - - /// - public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) - { - if (IsComplete) - return ResolveMethodSymbol(UnderlyingType.GetMethod(name, types.Unpack())); - else - throw new NotImplementedException(); - } - - /// - public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types) - { - if (IsComplete) - return ResolveMethodSymbol(UnderlyingType.GetMethod(name, bindingAttr, null, types.Unpack(), null)); - else - throw new NotImplementedException(); - } - - /// - public IMethodSymbol? GetMethod(string name) - { - if (IsComplete) - return ResolveMethodSymbol(UnderlyingType.GetMethod(name)); - else - return GetIncompleteMethods().FirstOrDefault(i => i.Name == name); - } - - /// - public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers) - { - if (IsComplete) - return ResolveMethodSymbol(UnderlyingType.GetMethod(name, bindingAttr, null, callConvention, types.Unpack(), modifiers?.Unpack())); - else - throw new NotImplementedException(); - } - - /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers) - { - throw new NotImplementedException(); - } - - /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) - { - throw new NotImplementedException(); - } - - /// - public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) - { - if (IsComplete) - return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), modifiers?.Unpack())); - else - throw new NotImplementedException(); - } - - /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) - { - throw new NotImplementedException(); - } - - /// - public IMethodSymbol[] GetMethods(BindingFlags bindingAttr) - { - if (IsComplete) - return ResolveMethodSymbols(UnderlyingType.GetMethods((BindingFlags)bindingAttr)); - else - return GetIncompleteMethods(bindingAttr); - } - - /// - public IMethodSymbol[] GetMethods() - { - if (IsComplete) - return ResolveMethodSymbols(UnderlyingType.GetMethods()); - else - return GetIncompleteMethods(); - } - - /// - /// Gets the set of incomplete methods. - /// - /// - IMethodSymbol[] GetIncompleteMethods(BindingFlags bindingAttr = BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance) - { - if (_incompleteMethods == null) - return []; - else - return SymbolUtil.FilterMethods(this, _incompleteMethods, bindingAttr).Cast().ToArray(); - } - - /// - public ITypeSymbol? GetNestedType(string name) - { - return ResolveTypeSymbol(UnderlyingType.GetNestedType(name)); - } - - /// - public ITypeSymbol? GetNestedType(string name, BindingFlags bindingAttr) - { - return ResolveTypeSymbol(UnderlyingType.GetNestedType(name, (BindingFlags)bindingAttr)); - } - - /// - public ITypeSymbol[] GetNestedTypes() - { - return ResolveTypeSymbols(UnderlyingType.GetNestedTypes()); - } - - /// - public ITypeSymbol[] GetNestedTypes(BindingFlags bindingAttr) - { - return ResolveTypeSymbols(UnderlyingType.GetNestedTypes((BindingFlags)bindingAttr)); - } - - /// - public IPropertySymbol[] GetProperties() - { - return ResolvePropertySymbols(UnderlyingType.GetProperties()); - } - - /// - public IPropertySymbol[] GetProperties(BindingFlags bindingAttr) - { - return ResolvePropertySymbols(UnderlyingType.GetProperties((BindingFlags)bindingAttr)); - } - - /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol[] types) - { - return ResolvePropertySymbol(UnderlyingType.GetProperty(name, types.Unpack())); - } - - /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types) - { - return ResolvePropertySymbol(UnderlyingType.GetProperty(name, returnType?.Unpack(), types.Unpack())); - } - - /// - public IPropertySymbol? GetProperty(string name, BindingFlags bindingAttr) - { - return ResolvePropertySymbol(UnderlyingType.GetProperty(name, (BindingFlags)bindingAttr)); - } - - /// - public IPropertySymbol? GetProperty(string name) - { - return ResolvePropertySymbol(UnderlyingType.GetProperty(name)); - } - - /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) - { - return ResolvePropertySymbol(UnderlyingType.GetProperty(name, returnType?.Unpack())); - } - - /// - public bool IsAssignableFrom(ITypeSymbol? c) - { - return UnderlyingType.IsAssignableFrom(c?.Unpack()); - } - - /// - public bool IsEnumDefined(object value) - { - return UnderlyingType.IsEnumDefined(value); - } - - /// - public bool IsSubclassOf(ITypeSymbol c) - { - return UnderlyingType.IsSubclassOf(c.Unpack()); - } - - /// - public ITypeSymbol MakeArrayType() - { - return ResolveTypeSymbol(_type.MakeArrayType()); - } - - /// - public ITypeSymbol MakeArrayType(int rank) - { - return ResolveTypeSymbol(_type.MakeArrayType(rank)); - } - - /// - public ITypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments) - { - return ResolveTypeSymbol(_type.MakeGenericType(typeArguments.Unpack())); - } - - /// - public ITypeSymbol MakePointerType() - { - return ResolveTypeSymbol(_type.MakePointerType()); - } - - /// - public ITypeSymbol MakeByRefType() - { - return ResolveTypeSymbol(_type.MakeByRefType()); - } - - #endregion - /// public void Complete() { @@ -963,10 +318,7 @@ public void Complete() { // complete type if (_builder.IsCreated() == false) - { _type = _builder.CreateType()!; - _builder = null; - } // force module to reresolve Context.GetOrCreateModuleSymbol(ResolvingModule.UnderlyingModule); @@ -975,7 +327,7 @@ public void Complete() } /// - public override void OnComplete() + public void OnComplete() { const BindingFlags DefaultBindingFlags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static; @@ -1002,8 +354,6 @@ public override void OnComplete() foreach (var m in GetEvents(DefaultBindingFlags)) if (m is IReflectionPropertySymbolBuilder b) b.OnComplete(); - - base.OnComplete(); } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionConstructorSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionConstructorSymbol.cs index 6da5dafb0..43d116030 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionConstructorSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionConstructorSymbol.cs @@ -11,6 +11,16 @@ interface IReflectionConstructorSymbol : IReflectionMethodBaseSymbol, IConstruct /// ConstructorInfo UnderlyingConstructor { get; } + /// + /// Gets the underlying used for IL emit operations. + /// + ConstructorInfo UnderlyingEmitConstructor { get; } + + /// + /// Gets the underlying used for IL emit operations against dynamic methods. + /// + ConstructorInfo UnderlyingDynamicEmitConstructor { get; } + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionEventSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionEventSymbol.cs index 09a99ae06..f2c411fc9 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionEventSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionEventSymbol.cs @@ -11,6 +11,11 @@ interface IReflectionEventSymbol : IReflectionMemberSymbol, IEventSymbol /// EventInfo UnderlyingEvent { get; } + /// + /// Gets the underlying used for IL emit operations. + /// + EventInfo UnderlyingEmitEvent { get; } + } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionFieldSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionFieldSymbol.cs index 0ceb9e07c..86094cd8d 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionFieldSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionFieldSymbol.cs @@ -11,6 +11,16 @@ interface IReflectionFieldSymbol : IReflectionMemberSymbol, IFieldSymbol /// FieldInfo UnderlyingField { get; } + /// + /// Gets the underlying used for IL emit operations. + /// + FieldInfo UnderlyingEmitField { get; } + + /// + /// Gets the underlying used for IL emit operations against dynamic methods. + /// + FieldInfo UnderlyingDynamicEmitField { get; } + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMemberSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMemberSymbol.cs index a83971303..b62765637 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMemberSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMemberSymbol.cs @@ -21,6 +21,11 @@ interface IReflectionMemberSymbol : IReflectionSymbol, IMemberSymbol /// MemberInfo UnderlyingMember { get; } + /// + /// Gets the underlying used for IL emit operations. + /// + MemberInfo UnderlyingEmitMember { get; } + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMethodBaseSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMethodBaseSymbol.cs index 9e0105610..b46e914f7 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMethodBaseSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMethodBaseSymbol.cs @@ -7,10 +7,15 @@ interface IReflectionMethodBaseSymbol : IReflectionMemberSymbol, IMethodBaseSymb { /// - /// Gets the underlying . + /// Gets the underlying . /// MethodBase UnderlyingMethodBase { get; } + /// + /// Gets the underlying . + /// + MethodBase UnderlyingEmitMethodBase { get; } + /// /// Gets or creates a for the given . /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMethodSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMethodSymbol.cs index 6d17a00c4..07cc3b253 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMethodSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMethodSymbol.cs @@ -12,6 +12,16 @@ interface IReflectionMethodSymbol : IReflectionMethodBaseSymbol, IMethodSymbol /// MethodInfo UnderlyingMethod { get; } + /// + /// Gets the underlying used for IL emit operations. + /// + MethodInfo UnderlyingEmitMethod { get; } + + /// + /// Gets the underlying used for IL emit operations against dynamic methods. + /// + MethodInfo UnderlyingDynamicEmitMethod { get; } + /// /// Gets or creates a for the given generic type parameter. /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionParameterSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionParameterSymbol.cs index 60632e80c..55d9de63c 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionParameterSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionParameterSymbol.cs @@ -21,6 +21,11 @@ interface IReflectionParameterSymbol : IReflectionSymbol, IParameterSymbol /// ParameterInfo UnderlyingParameter { get; } + /// + /// Gets the underlying used for IL emit operations. + /// + ParameterInfo UnderlyingEmitParameter { get; } + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionPropertySymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionPropertySymbol.cs index 2b7aa2401..c1f545f79 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionPropertySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionPropertySymbol.cs @@ -11,6 +11,11 @@ interface IReflectionPropertySymbol : IReflectionMemberSymbol, IPropertySymbol /// PropertyInfo UnderlyingProperty { get; } + /// + /// Gets the underlying used for IL emit operations. + /// + PropertyInfo UnderlyingEmitProperty { get; } + /// /// Gets or creates a for the given . /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionTypeSymbol.cs index edc48697a..a36c6f0a4 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionTypeSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionTypeSymbol.cs @@ -12,6 +12,16 @@ interface IReflectionTypeSymbol : IReflectionMemberSymbol, ITypeSymbol /// Type UnderlyingType { get; } + /// + /// Gets the underlying used for IL emit operations. + /// + Type UnderlyingEmitType { get; } + + /// + /// Gets the underlying used for IL emit operations for dynamic methods. + /// + Type UnderlyingDynamicEmitType { get; } + /// /// Gets or creates a for the given . /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionArrayTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionArrayTypeSymbol.cs new file mode 100644 index 000000000..99a1f0236 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionArrayTypeSymbol.cs @@ -0,0 +1,34 @@ +using System; + +namespace IKVM.CoreLib.Symbols.Reflection +{ + + class ReflectionArrayTypeSymbol : ReflectionTypeSpecSymbol + { + + readonly int rank; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + public ReflectionArrayTypeSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol elementType, int rank) : + base(context, resolvingModule, elementType) + { + this.rank = rank; + } + + /// + public override Type UnderlyingType => ElementType.UnderlyingType.MakeArrayType(rank); + + /// + public override Type UnderlyingEmitType => ElementType.UnderlyingEmitType.MakeArrayType(rank); + + /// + public override Type UnderlyingDynamicEmitType => ElementType.UnderlyingDynamicEmitType.MakeArrayType(rank); + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionByRefTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionByRefTypeSymbol.cs new file mode 100644 index 000000000..70320ff0b --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionByRefTypeSymbol.cs @@ -0,0 +1,32 @@ +using System; + +namespace IKVM.CoreLib.Symbols.Reflection +{ + + class ReflectionByRefTypeSymbol : ReflectionTypeSpecSymbol + { + + /// + /// Initializes a new instance. + /// + /// + /// + /// + public ReflectionByRefTypeSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol elementType) : + base(context, resolvingModule, elementType) + { + + } + + /// + public override Type UnderlyingType => ElementType.UnderlyingType.MakeByRefType(); + + /// + public override Type UnderlyingEmitType => ElementType.UnderlyingEmitType.MakeByRefType(); + + /// + public override Type UnderlyingDynamicEmitType => ElementType.UnderlyingDynamicEmitType.MakeByRefType(); + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionConstructorSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionConstructorSymbol.cs index 0d7c95667..ce5d37ac2 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionConstructorSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionConstructorSymbol.cs @@ -25,6 +25,12 @@ public ReflectionConstructorSymbol(ReflectionSymbolContext context, IReflectionM /// public ConstructorInfo UnderlyingConstructor => _ctor; + /// + public ConstructorInfo UnderlyingEmitConstructor => UnderlyingConstructor; + + /// + public ConstructorInfo UnderlyingDynamicEmitConstructor => UnderlyingEmitConstructor; + /// public override MethodBase UnderlyingMethodBase => UnderlyingConstructor; diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionEventSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionEventSymbol.cs index 1b8abba99..33a0c5721 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionEventSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionEventSymbol.cs @@ -25,6 +25,9 @@ public ReflectionEventSymbol(ReflectionSymbolContext context, IReflectionModuleS /// public EventInfo UnderlyingEvent => _event; + /// + public EventInfo UnderlyingEmitEvent => _event; + /// public override MemberInfo UnderlyingMember => UnderlyingEvent; diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionFieldSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionFieldSymbol.cs index c82d80e20..39b5c3273 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionFieldSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionFieldSymbol.cs @@ -25,6 +25,12 @@ public ReflectionFieldSymbol(ReflectionSymbolContext context, IReflectionModuleS /// public FieldInfo UnderlyingField => _field; + /// + public FieldInfo UnderlyingEmitField => UnderlyingField; + + /// + public FieldInfo UnderlyingDynamicEmitField => UnderlyingEmitField; + /// public override MemberInfo UnderlyingMember => UnderlyingField; diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericSpecTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericSpecTypeSymbol.cs new file mode 100644 index 000000000..bba26a6ad --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericSpecTypeSymbol.cs @@ -0,0 +1,35 @@ +using System; +using System.Linq; + +namespace IKVM.CoreLib.Symbols.Reflection +{ + + class ReflectionGenericSpecTypeSymbol : ReflectionTypeSpecSymbol + { + + readonly IReflectionTypeSymbol[] genericTypeArguments; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + public ReflectionGenericSpecTypeSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol elementType, IReflectionTypeSymbol[] genericTypeArguments) : + base(context, resolvingModule, elementType) + { + this.genericTypeArguments = genericTypeArguments ?? throw new ArgumentNullException(nameof(genericTypeArguments)); + } + + /// + public override Type UnderlyingType => ElementType.UnderlyingType.MakeGenericType(genericTypeArguments.Select(i => i.UnderlyingType).ToArray()); + + /// + public override Type UnderlyingEmitType => ElementType.UnderlyingEmitType.MakeGenericType(genericTypeArguments.Select(i => i.UnderlyingEmitType).ToArray()); + + /// + public override Type UnderlyingDynamicEmitType => ElementType.UnderlyingDynamicEmitType.MakeGenericType(genericTypeArguments.Select(i => i.UnderlyingDynamicEmitType).ToArray()); + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericTypeParameterSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericTypeParameterSymbol.cs index 853b5e4f9..5000896e3 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericTypeParameterSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericTypeParameterSymbol.cs @@ -34,6 +34,12 @@ public ReflectionGenericTypeParameterSymbol(ReflectionSymbolContext context, IRe /// public Type UnderlyingType => _type; + /// + public Type UnderlyingEmitType => UnderlyingType; + + /// + public Type UnderlyingDynamicEmitType => _type; + /// public override MemberInfo UnderlyingMember => UnderlyingType; diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs index b97fa7aa7..229278112 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs @@ -32,6 +32,9 @@ public ReflectionMemberSymbol(ReflectionSymbolContext context, IReflectionModule /// public abstract MemberInfo UnderlyingMember { get; } + /// + public virtual MemberInfo UnderlyingEmitMember => UnderlyingMember; + /// /// Gets the which contains the metadata of this member. /// @@ -208,6 +211,7 @@ public virtual bool IsDefined(ITypeSymbol attributeType, bool inherit = false) #endregion + /// public override string? ToString() => UnderlyingMember.ToString(); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodBaseSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodBaseSymbol.cs index a4ef99e3f..c16020d4c 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodBaseSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodBaseSymbol.cs @@ -35,6 +35,9 @@ public IReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo param /// public abstract MethodBase UnderlyingMethodBase { get; } + /// + public virtual MethodBase UnderlyingEmitMethodBase => UnderlyingMethodBase; + /// public override MemberInfo UnderlyingMember => UnderlyingMethodBase; diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs index ada2a5653..35b421e48 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs @@ -30,6 +30,12 @@ public ReflectionMethodSymbol(ReflectionSymbolContext context, IReflectionModule /// public MethodInfo UnderlyingMethod => _method; + /// + public MethodInfo UnderlyingEmitMethod => UnderlyingMethod; + + /// + public MethodInfo UnderlyingDynamicEmitMethod => UnderlyingEmitMethod; + /// public override MethodBase UnderlyingMethodBase => UnderlyingMethod; diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterSymbol.cs index 23bfcf04c..5d9c95446 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterSymbol.cs @@ -36,6 +36,9 @@ public ReflectionParameterSymbol(ReflectionSymbolContext context, IReflectionMod /// public ParameterInfo UnderlyingParameter => _parameter; + /// + public ParameterInfo UnderlyingEmitParameter => UnderlyingParameter; + #region IParameterSymbol /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionPointerTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionPointerTypeSymbol.cs new file mode 100644 index 000000000..0ac878770 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionPointerTypeSymbol.cs @@ -0,0 +1,32 @@ +using System; + +namespace IKVM.CoreLib.Symbols.Reflection +{ + + class ReflectionPointerTypeSymbol : ReflectionTypeSpecSymbol + { + + /// + /// Initializes a new instance. + /// + /// + /// + /// + public ReflectionPointerTypeSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol elementType) : + base(context, resolvingModule, elementType) + { + + } + + /// + public override Type UnderlyingType => ElementType.UnderlyingType.MakePointerType(); + + /// + public override Type UnderlyingEmitType => ElementType.UnderlyingEmitType.MakePointerType(); + + /// + public override Type UnderlyingDynamicEmitType => ElementType.UnderlyingDynamicEmitType.MakePointerType(); + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionPropertySymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionPropertySymbol.cs index 4a06567d9..ca77f5d84 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionPropertySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionPropertySymbol.cs @@ -28,6 +28,9 @@ public ReflectionPropertySymbol(ReflectionSymbolContext context, IReflectionModu /// public PropertyInfo UnderlyingProperty => _property; + /// + public PropertyInfo UnderlyingEmitProperty => UnderlyingProperty; + /// public override MemberInfo UnderlyingMember => UnderlyingProperty; diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSZArrayTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSZArrayTypeSymbol.cs new file mode 100644 index 000000000..63845863f --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSZArrayTypeSymbol.cs @@ -0,0 +1,32 @@ +using System; + +namespace IKVM.CoreLib.Symbols.Reflection +{ + + class ReflectionSZArrayTypeSymbol : ReflectionTypeSpecSymbol + { + + /// + /// Initializes a new instance. + /// + /// + /// + /// + public ReflectionSZArrayTypeSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol elementType) : + base(context, resolvingModule, elementType) + { + + } + + /// + public override Type UnderlyingType => ElementType.UnderlyingType.MakeArrayType(); + + /// + public override Type UnderlyingEmitType => ElementType.UnderlyingEmitType.MakeArrayType(); + + /// + public override Type UnderlyingDynamicEmitType => ElementType.UnderlyingDynamicEmitType.MakeArrayType(); + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSpecSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSpecSymbol.cs new file mode 100644 index 000000000..bc68441c5 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSpecSymbol.cs @@ -0,0 +1,37 @@ +using System; + +namespace IKVM.CoreLib.Symbols.Reflection +{ + + abstract class ReflectionTypeSpecSymbol : ReflectionTypeSymbolBase + { + + readonly IReflectionTypeSymbol _elementType; + + ReflectionMethodTable _methodTable; + ReflectionFieldTable _fieldTable; + ReflectionPropertyTable _propertyTable; + ReflectionEventTable _eventTable; + ReflectionGenericTypeParameterTable _genericTypeParameterTable; + ReflectionTypeSpecTable _specTable; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + public ReflectionTypeSpecSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol elementType) : + base(context, resolvingModule) + { + _elementType = elementType ?? throw new ArgumentNullException(nameof(elementType)); + } + + /// + /// Gets the element type. + /// + protected IReflectionTypeSymbol ElementType => _elementType; + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSpecTable.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSpecTable.cs index b83bdff39..b115fb485 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSpecTable.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSpecTable.cs @@ -15,12 +15,12 @@ struct ReflectionTypeSpecTable readonly IReflectionModuleSymbol _module; readonly IReflectionTypeSymbol _elementType; - IndexRangeDictionary _asArray; + IndexRangeDictionary _asArray; ReaderWriterLockSlim? _asArrayLock; - IReflectionTypeSymbol? _asSZArray; - IReflectionTypeSymbol? _asPointer; - IReflectionTypeSymbol? _asByRef; - ConcurrentDictionary? _genericTypeSymbols; + ReflectionSZArrayTypeSymbol? _asSZArray; + ReflectionPointerTypeSymbol? _asPointer; + ReflectionByRefTypeSymbol? _asByRef; + ConcurrentDictionary? _genericTypeSymbols; /// /// Initializes a new instance. @@ -34,7 +34,7 @@ public ReflectionTypeSpecTable(ReflectionSymbolContext context, IReflectionModul _context = context ?? throw new ArgumentNullException(nameof(context)); _module = module ?? throw new ArgumentNullException(nameof(module)); _elementType = elementType ?? throw new ArgumentNullException(nameof(elementType)); - _asArray = new IndexRangeDictionary(); + _asArray = new IndexRangeDictionary(); } /// @@ -52,7 +52,7 @@ public IReflectionTypeSymbol GetOrCreateArrayTypeSymbol(int rank) { if (_asArray[rank] == null) using (_asArrayLock.CreateWriteLock()) - _asArray[rank] = new ReflectionTypeSymbol(_context, _module, _elementType.UnderlyingType.MakeArrayType(rank)); + _asArray[rank] = new ReflectionArrayTypeSymbol(_context, _module, _elementType, rank); return _asArray[rank] ?? throw new InvalidOperationException(); } @@ -65,7 +65,7 @@ public IReflectionTypeSymbol GetOrCreateArrayTypeSymbol(int rank) public IReflectionTypeSymbol GetOrCreateSZArrayTypeSymbol() { if (_asSZArray == null) - Interlocked.CompareExchange(ref _asSZArray, new ReflectionTypeSymbol(_context, _module, _elementType.UnderlyingType.MakeArrayType()), null); + Interlocked.CompareExchange(ref _asSZArray, new ReflectionSZArrayTypeSymbol(_context, _module, _elementType), null); return _asSZArray; } @@ -77,7 +77,7 @@ public IReflectionTypeSymbol GetOrCreateSZArrayTypeSymbol() public IReflectionTypeSymbol GetOrCreatePointerTypeSymbol() { if (_asPointer == null) - Interlocked.CompareExchange(ref _asPointer, new ReflectionTypeSymbol(_context, _module, _elementType.UnderlyingType.MakePointerType()), null); + Interlocked.CompareExchange(ref _asPointer, new ReflectionPointerTypeSymbol(_context, _module, _elementType), null); return _asPointer; } @@ -89,7 +89,7 @@ public IReflectionTypeSymbol GetOrCreatePointerTypeSymbol() public IReflectionTypeSymbol GetOrCreateByRefTypeSymbol() { if (_asByRef == null) - Interlocked.CompareExchange(ref _asByRef, new ReflectionTypeSymbol(_context, _module, _elementType.UnderlyingType.MakeByRefType()), null); + Interlocked.CompareExchange(ref _asByRef, new ReflectionByRefTypeSymbol(_context, _module, _elementType), null); return _asByRef; } @@ -118,10 +118,11 @@ public IReflectionTypeSymbol GetOrCreateGenericTypeSymbol(IReflectionTypeSymbol[ /// /// /// - readonly IReflectionTypeSymbol CreateGenericTypeSymbol(IReflectionTypeSymbol[] genericTypeArguments) + readonly ReflectionGenericSpecTypeSymbol CreateGenericTypeSymbol(IReflectionTypeSymbol[] genericTypeArguments) { - return new ReflectionTypeSymbol(_context, _module, _elementType.UnderlyingType.MakeGenericType(genericTypeArguments.Unpack())); + return new ReflectionGenericSpecTypeSymbol(_context, _module, _elementType, genericTypeArguments); } + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbol.cs index 1880246ba..f8476934b 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbol.cs @@ -1,24 +1,14 @@ using System; using System.Diagnostics.CodeAnalysis; -using System.Reflection; - -using IKVM.CoreLib.Reflection; namespace IKVM.CoreLib.Symbols.Reflection { - class ReflectionTypeSymbol : ReflectionMemberSymbol, IReflectionTypeSymbol + class ReflectionTypeSymbol : ReflectionTypeSymbolBase { readonly Type _type; - ReflectionMethodTable _methodTable; - ReflectionFieldTable _fieldTable; - ReflectionPropertyTable _propertyTable; - ReflectionEventTable _eventTable; - ReflectionGenericTypeParameterTable _genericTypeParameterTable; - ReflectionTypeSpecTable _specTable; - /// /// Initializes a new instance. /// @@ -26,104 +16,13 @@ class ReflectionTypeSymbol : ReflectionMemberSymbol, IReflectionTypeSymbol /// /// public ReflectionTypeSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, Type type) : - base(context, resolvingModule, null) + base(context, resolvingModule) { _type = type ?? throw new ArgumentNullException(nameof(type)); - _methodTable = new ReflectionMethodTable(context, resolvingModule, this); - _fieldTable = new ReflectionFieldTable(context, resolvingModule, this); - _propertyTable = new ReflectionPropertyTable(context, resolvingModule, this); - _eventTable = new ReflectionEventTable(context, resolvingModule, this); - _genericTypeParameterTable = new ReflectionGenericTypeParameterTable(context, resolvingModule, this); - _specTable = new ReflectionTypeSpecTable(context, resolvingModule, this); - } - - /// - public Type UnderlyingType => _type; - - /// - public override MemberInfo UnderlyingMember => UnderlyingType; - - #region IReflectionTypeSymbol - - /// - public IReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) - { - return _methodTable.GetOrCreateConstructorSymbol(ctor); - } - - /// - public IReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method) - { - if (method is ConstructorInfo ctor) - return GetOrCreateConstructorSymbol(ctor); - else - return GetOrCreateMethodSymbol((MethodInfo)method); - } - - /// - public IReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) - { - if (method.IsMethodDefinition()) - return _methodTable.GetOrCreateMethodSymbol(method); - else - return ResolveMethodSymbol(method.GetGenericMethodDefinition()).GetOrCreateGenericMethodSymbol(method); - } - - /// - public IReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) - { - return _fieldTable.GetOrCreateFieldSymbol(field); - } - - /// - public IReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) - { - return _propertyTable.GetOrCreatePropertySymbol(property); - } - - /// - public IReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) - { - return _eventTable.GetOrCreateEventSymbol(@event); - } - - /// - public IReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type genericType) - { - return _genericTypeParameterTable.GetOrCreateGenericTypeParameterSymbol(genericType); - } - - /// - public IReflectionTypeSymbol GetOrCreateSZArrayTypeSymbol() - { - return _specTable.GetOrCreateSZArrayTypeSymbol(); - } - - /// - public IReflectionTypeSymbol GetOrCreateArrayTypeSymbol(int rank) - { - return _specTable.GetOrCreateArrayTypeSymbol(rank); - } - - /// - public IReflectionTypeSymbol GetOrCreatePointerTypeSymbol() - { - return _specTable.GetOrCreatePointerTypeSymbol(); - } - - /// - public IReflectionTypeSymbol GetOrCreateByRefTypeSymbol() - { - return _specTable.GetOrCreateByRefTypeSymbol(); } /// - public IReflectionTypeSymbol GetOrCreateGenericTypeSymbol(IReflectionTypeSymbol[] genericTypeDefinition) - { - return _specTable.GetOrCreateGenericTypeSymbol(genericTypeDefinition); - } - - #endregion + public override Type UnderlyingType => _type; #region IReflectionSymbol @@ -139,532 +38,6 @@ public IReflectionTypeSymbol GetOrCreateGenericTypeSymbol(IReflectionTypeSymbol[ #endregion - #region ITypeSymbol - - /// - public IAssemblySymbol Assembly => ResolveAssemblySymbol(UnderlyingType.Assembly); - - /// - public string? AssemblyQualifiedName => UnderlyingType.AssemblyQualifiedName; - - /// - public System.Reflection.TypeAttributes Attributes => (System.Reflection.TypeAttributes)UnderlyingType.Attributes; - - /// - public ITypeSymbol? BaseType => ResolveTypeSymbol(UnderlyingType.BaseType); - - /// - public bool ContainsGenericParameters => UnderlyingType.ContainsGenericParameters; - - /// - public IMethodBaseSymbol? DeclaringMethod => ResolveMethodBaseSymbol(UnderlyingType.DeclaringMethod); - - /// - public string? FullName => UnderlyingType.FullName; - - /// - public string? Namespace => UnderlyingType.Namespace; - - /// - public System.Reflection.GenericParameterAttributes GenericParameterAttributes => (System.Reflection.GenericParameterAttributes)UnderlyingType.GenericParameterAttributes; - - /// - public int GenericParameterPosition => UnderlyingType.GenericParameterPosition; - - /// - public ITypeSymbol[] GenericTypeArguments => ResolveTypeSymbols(UnderlyingType.GenericTypeArguments); - - /// - public bool HasElementType => UnderlyingType.HasElementType; - - /// - public TypeCode TypeCode => Type.GetTypeCode(UnderlyingType); - - /// - public bool IsAbstract => UnderlyingType.IsAbstract; - - /// - public bool IsSZArray => UnderlyingType.IsSZArray(); - - /// - public bool IsArray => UnderlyingType.IsArray; - - /// - public bool IsAutoLayout => UnderlyingType.IsAutoLayout; - - /// - public bool IsExplicitLayout => UnderlyingType.IsExplicitLayout; - - /// - public bool IsByRef => UnderlyingType.IsByRef; - - /// - public bool IsClass => UnderlyingType.IsClass; - - /// - public bool IsEnum => UnderlyingType.IsEnum; - - /// - public bool IsInterface => UnderlyingType.IsInterface; - - /// - public bool IsConstructedGenericType => UnderlyingType.IsConstructedGenericType; - - /// - public bool IsGenericParameter => UnderlyingType.IsGenericParameter; - - /// - public bool IsGenericType => UnderlyingType.IsGenericType; - - /// - public bool IsGenericTypeDefinition => UnderlyingType.IsGenericTypeDefinition; - - /// - public bool IsLayoutSequential => UnderlyingType.IsLayoutSequential; - - /// - public bool IsNested => UnderlyingType.IsNested; - - /// - public bool IsNestedAssembly => UnderlyingType.IsNestedAssembly; - - /// - public bool IsNestedFamANDAssem => UnderlyingType.IsNestedFamANDAssem; - - /// - public bool IsNestedFamORAssem => UnderlyingType.IsNestedFamORAssem; - - /// - public bool IsNestedFamily => UnderlyingType.IsNestedFamily; - - /// - public bool IsNestedPrivate => UnderlyingType.IsNestedPrivate; - - /// - public bool IsNestedPublic => UnderlyingType.IsNestedPublic; - - /// - public bool IsNotPublic => UnderlyingType.IsNotPublic; - - /// - public bool IsPointer => UnderlyingType.IsPointer; - -#if NET8_0_OR_GREATER - - /// - public bool IsFunctionPointer => UnderlyingType.IsFunctionPointer; - - /// - public bool IsUnmanagedFunctionPointer => UnderlyingType.IsUnmanagedFunctionPointer; - -#else - - /// - public bool IsFunctionPointer => throw new NotImplementedException(); - - /// - public bool IsUnmanagedFunctionPointer => throw new NotImplementedException(); - -#endif - - /// - public bool IsPrimitive => UnderlyingType.IsPrimitive; - - /// - public bool IsPublic => UnderlyingType.IsPublic; - - /// - public bool IsSealed => UnderlyingType.IsSealed; - - /// - public bool IsSerializable => UnderlyingType.IsSerializable; - - /// - public bool IsValueType => UnderlyingType.IsValueType; - - /// - public bool IsVisible => UnderlyingType.IsVisible; - - /// - public bool IsSignatureType => throw new NotImplementedException(); - - /// - public bool IsSpecialName => UnderlyingType.IsSpecialName; - - /// - public IConstructorSymbol? TypeInitializer => ResolveConstructorSymbol(UnderlyingType.TypeInitializer); - - /// - public int GetArrayRank() - { - return UnderlyingType.GetArrayRank(); - } - - /// - public IConstructorSymbol? GetConstructor(System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) - { - return ResolveConstructorSymbol(UnderlyingType.GetConstructor((BindingFlags)bindingAttr, binder: null, types.Unpack(), modifiers: null)); - } - - /// - public IConstructorSymbol? GetConstructor(ITypeSymbol[] types) - { - return ResolveConstructorSymbol(UnderlyingType.GetConstructor(types.Unpack())); - } - - /// - public IConstructorSymbol[] GetConstructors() - { - return ResolveConstructorSymbols(UnderlyingType.GetConstructors()); - } - - /// - public IConstructorSymbol[] GetConstructors(System.Reflection.BindingFlags bindingAttr) - { - return ResolveConstructorSymbols(UnderlyingType.GetConstructors((BindingFlags)bindingAttr)); - } - - /// - public IMemberSymbol[] GetDefaultMembers() - { - return ResolveMemberSymbols(UnderlyingType.GetDefaultMembers()); - } - - /// - public ITypeSymbol? GetElementType() - { - return ResolveTypeSymbol(UnderlyingType.GetElementType()); - } - - /// - public string? GetEnumName(object value) - { - return UnderlyingType.GetEnumName(value); - } - - /// - public string[] GetEnumNames() - { - return UnderlyingType.GetEnumNames(); - } - - /// - public ITypeSymbol GetEnumUnderlyingType() - { - return ResolveTypeSymbol(UnderlyingType.GetEnumUnderlyingType()); - } - - /// - public Array GetEnumValues() - { - return UnderlyingType.GetEnumValues(); - } - - /// - public IEventSymbol? GetEvent(string name) - { - return ResolveEventSymbol(UnderlyingType.GetEvent(name)); - } - - /// - public IEventSymbol? GetEvent(string name, System.Reflection.BindingFlags bindingAttr) - { - return ResolveEventSymbol(UnderlyingType.GetEvent(name, (BindingFlags)bindingAttr)); - } - - /// - public IEventSymbol[] GetEvents() - { - return ResolveEventSymbols(UnderlyingType.GetEvents()); - } - - /// - public IEventSymbol[] GetEvents(System.Reflection.BindingFlags bindingAttr) - { - return ResolveEventSymbols(UnderlyingType.GetEvents((BindingFlags)bindingAttr)); - } - - /// - public IFieldSymbol? GetField(string name) - { - return ResolveFieldSymbol(UnderlyingType.GetField(name)); - } - - /// - public IFieldSymbol? GetField(string name, System.Reflection.BindingFlags bindingAttr) - { - return ResolveFieldSymbol(UnderlyingType.GetField(name, (BindingFlags)bindingAttr)); - } - - /// - public IFieldSymbol[] GetFields() - { - return ResolveFieldSymbols(UnderlyingType.GetFields()); - } - - /// - public IFieldSymbol[] GetFields(System.Reflection.BindingFlags bindingAttr) - { - return ResolveFieldSymbols(UnderlyingType.GetFields((BindingFlags)bindingAttr)); - } - - /// - public ITypeSymbol[] GetGenericArguments() - { - return ResolveTypeSymbols(UnderlyingType.GetGenericArguments()); - } - - /// - public ITypeSymbol[] GetGenericParameterConstraints() - { - return ResolveTypeSymbols(UnderlyingType.GetGenericParameterConstraints()); - } - - /// - public ITypeSymbol GetGenericTypeDefinition() - { - return ResolveTypeSymbol(UnderlyingType.GetGenericTypeDefinition()); - } - - /// - public ITypeSymbol? GetInterface(string name) - { - return ResolveTypeSymbol(UnderlyingType.GetInterface(name)); - } - - /// - public ITypeSymbol? GetInterface(string name, bool ignoreCase) - { - return ResolveTypeSymbol(UnderlyingType.GetInterface(name, ignoreCase)); - } - - /// - public InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) - { - return ResolveInterfaceMapping(UnderlyingType.GetInterfaceMap(interfaceType.Unpack())); - } - - /// - public ITypeSymbol[] GetInterfaces(bool inherit = true) - { - if (inherit) - return ResolveTypeSymbols(UnderlyingType.GetInterfaces()); - else - throw new NotImplementedException(); - } - - /// - public IMemberSymbol[] GetMember(string name) - { - return ResolveMemberSymbols(UnderlyingType.GetMember(name)); - } - - /// - public IMemberSymbol[] GetMember(string name, System.Reflection.BindingFlags bindingAttr) - { - return ResolveMemberSymbols(UnderlyingType.GetMember(name, (BindingFlags)bindingAttr)); - } - - /// - public IMemberSymbol[] GetMember(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) - { - return ResolveMemberSymbols(UnderlyingType.GetMember(name, (MemberTypes)type, (BindingFlags)bindingAttr)); - } - - /// - public IMemberSymbol[] GetMembers(System.Reflection.BindingFlags bindingAttr) - { - return ResolveMemberSymbols(UnderlyingType.GetMembers((BindingFlags)bindingAttr)); - } - - /// - public IMemberSymbol[] GetMembers() - { - return ResolveMemberSymbols(UnderlyingType.GetMembers()); - } - - /// - public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr) - { - return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr)); - } - - /// - public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) - { - return ResolveMethodSymbol(UnderlyingType.GetMethod(name, types.Unpack())); - } - - /// - public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) - { - return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), null)); - } - - /// - public IMethodSymbol? GetMethod(string name) - { - return ResolveMethodSymbol(UnderlyingType.GetMethod(name)); - } - - /// - public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) - { - return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, (CallingConventions)callConvention, types.Unpack(), modifiers?.Unpack())); - } - - /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) - { - throw new NotImplementedException(); - } - - /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) - { - throw new NotImplementedException(); - } - - /// - public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) - { - return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), modifiers?.Unpack())); - } - - /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) - { - throw new NotImplementedException(); - } - - /// - public IMethodSymbol[] GetMethods(System.Reflection.BindingFlags bindingAttr) - { - return ResolveMethodSymbols(UnderlyingType.GetMethods((BindingFlags)bindingAttr)); - } - - /// - public IMethodSymbol[] GetMethods() - { - return ResolveMethodSymbols(UnderlyingType.GetMethods()); - } - - /// - public ITypeSymbol? GetNestedType(string name) - { - return ResolveTypeSymbol(UnderlyingType.GetNestedType(name)); - } - - /// - public ITypeSymbol? GetNestedType(string name, System.Reflection.BindingFlags bindingAttr) - { - return ResolveTypeSymbol(UnderlyingType.GetNestedType(name, (BindingFlags)bindingAttr)); - } - - /// - public ITypeSymbol[] GetNestedTypes() - { - return ResolveTypeSymbols(UnderlyingType.GetNestedTypes()); - } - - /// - public ITypeSymbol[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr) - { - return ResolveTypeSymbols(UnderlyingType.GetNestedTypes((BindingFlags)bindingAttr)); - } - - /// - public IPropertySymbol[] GetProperties() - { - return ResolvePropertySymbols(UnderlyingType.GetProperties()); - } - - /// - public IPropertySymbol[] GetProperties(System.Reflection.BindingFlags bindingAttr) - { - return ResolvePropertySymbols(UnderlyingType.GetProperties((BindingFlags)bindingAttr)); - } - - /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol[] types) - { - return ResolvePropertySymbol(UnderlyingType.GetProperty(name, types.Unpack())); - } - - /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types) - { - return ResolvePropertySymbol(UnderlyingType.GetProperty(name, returnType?.Unpack(), types.Unpack())); - } - - /// - public IPropertySymbol? GetProperty(string name, System.Reflection.BindingFlags bindingAttr) - { - return ResolvePropertySymbol(UnderlyingType.GetProperty(name, (BindingFlags)bindingAttr)); - } - - /// - public IPropertySymbol? GetProperty(string name) - { - return ResolvePropertySymbol(UnderlyingType.GetProperty(name)); - } - - /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) - { - return ResolvePropertySymbol(UnderlyingType.GetProperty(name, returnType?.Unpack())); - } - - /// - public bool IsAssignableFrom(ITypeSymbol? c) - { - return UnderlyingType.IsAssignableFrom(c?.Unpack()); - } - - /// - public bool IsEnumDefined(object value) - { - return UnderlyingType.IsEnumDefined(value); - } - - /// - public bool IsSubclassOf(ITypeSymbol c) - { - return UnderlyingType.IsSubclassOf(c.Unpack()); - } - - /// - public ITypeSymbol MakeArrayType() - { - return ResolveTypeSymbol(UnderlyingType.MakeArrayType()); - } - - /// - public ITypeSymbol MakeArrayType(int rank) - { - return ResolveTypeSymbol(UnderlyingType.MakeArrayType(rank)); - } - - /// - public ITypeSymbol MakeByRefType() - { - return ResolveTypeSymbol(UnderlyingType.MakeByRefType()); - } - - /// - public ITypeSymbol MakePointerType() - { - return ResolveTypeSymbol(UnderlyingType.MakePointerType()); - } - - /// - public ITypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments) - { - return ResolveTypeSymbol(UnderlyingType.MakeGenericType(typeArguments.Unpack())); - } - - #endregion - } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbolBase.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbolBase.cs new file mode 100644 index 000000000..33c07a976 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbolBase.cs @@ -0,0 +1,669 @@ +using System; +using System.Reflection; +using System.Reflection.Emit; + +using IKVM.CoreLib.Reflection; +using IKVM.CoreLib.Symbols.Reflection.Emit; + +namespace IKVM.CoreLib.Symbols.Reflection +{ + + abstract class ReflectionTypeSymbolBase : ReflectionMemberSymbol, IReflectionTypeSymbol + { + + protected ReflectionMethodTable _methodTable; + protected ReflectionFieldTable _fieldTable; + protected ReflectionPropertyTable _propertyTable; + protected ReflectionEventTable _eventTable; + protected ReflectionGenericTypeParameterTable _genericTypeParameterTable; + protected ReflectionTypeSpecTable _specTable; + + /// + /// Initializes a new instance. + /// + /// + /// + public ReflectionTypeSymbolBase(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule) : + base(context, resolvingModule, null) + { + _methodTable = new ReflectionMethodTable(context, resolvingModule, this); + _fieldTable = new ReflectionFieldTable(context, resolvingModule, this); + _propertyTable = new ReflectionPropertyTable(context, resolvingModule, this); + _eventTable = new ReflectionEventTable(context, resolvingModule, this); + _genericTypeParameterTable = new ReflectionGenericTypeParameterTable(context, resolvingModule, this); + _specTable = new ReflectionTypeSpecTable(context, resolvingModule, this); + } + + /// + public abstract Type UnderlyingType { get; } + + /// + public virtual Type UnderlyingEmitType => UnderlyingType; + + /// + public virtual Type UnderlyingDynamicEmitType => UnderlyingEmitType; + + /// + public override MemberInfo UnderlyingMember => UnderlyingType; + + #region IReflectionTypeSymbol + + /// + public IReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) + { + return _methodTable.GetOrCreateConstructorSymbol(ctor); + } + + /// + public IReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method) + { + if (method is ConstructorInfo ctor) + return GetOrCreateConstructorSymbol(ctor); + else + return GetOrCreateMethodSymbol((MethodInfo)method); + } + + /// + public IReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) + { + if (method.IsMethodDefinition()) + return _methodTable.GetOrCreateMethodSymbol(method); + else + return ResolveMethodSymbol(method.GetGenericMethodDefinition()).GetOrCreateGenericMethodSymbol(method); + } + + /// + public IReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) + { + return _fieldTable.GetOrCreateFieldSymbol(field); + } + + /// + public IReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) + { + return _propertyTable.GetOrCreatePropertySymbol(property); + } + + /// + public IReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) + { + return _eventTable.GetOrCreateEventSymbol(@event); + } + + /// + public IReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type genericType) + { + return _genericTypeParameterTable.GetOrCreateGenericTypeParameterSymbol(genericType); + } + + /// + public IReflectionTypeSymbol GetOrCreateSZArrayTypeSymbol() + { + return _specTable.GetOrCreateSZArrayTypeSymbol(); + } + + /// + public IReflectionTypeSymbol GetOrCreateArrayTypeSymbol(int rank) + { + return _specTable.GetOrCreateArrayTypeSymbol(rank); + } + + /// + public IReflectionTypeSymbol GetOrCreatePointerTypeSymbol() + { + return _specTable.GetOrCreatePointerTypeSymbol(); + } + + /// + public IReflectionTypeSymbol GetOrCreateByRefTypeSymbol() + { + return _specTable.GetOrCreateByRefTypeSymbol(); + } + + /// + public IReflectionTypeSymbol GetOrCreateGenericTypeSymbol(IReflectionTypeSymbol[] genericTypeDefinition) + { + return _specTable.GetOrCreateGenericTypeSymbol(genericTypeDefinition); + } + + #endregion + + #region IReflectionTypeSymbolBuilder + + /// + public IReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeParameterSymbol(GenericTypeParameterBuilder genericTypeParameter) + { + return _genericTypeParameterTable.GetOrCreateGenericTypeParameterSymbol(genericTypeParameter); + } + + #endregion + + #region ITypeSymbol + + /// + public IAssemblySymbol Assembly => ResolveAssemblySymbol(UnderlyingType.Assembly); + + /// + public string? AssemblyQualifiedName => UnderlyingType.AssemblyQualifiedName; + + /// + public TypeAttributes Attributes => UnderlyingType.Attributes; + + /// + public ITypeSymbol? BaseType => ResolveTypeSymbol(UnderlyingType.BaseType); + + /// + public bool ContainsGenericParameters => UnderlyingType.ContainsGenericParameters; + + /// + public IMethodBaseSymbol? DeclaringMethod => ResolveMethodBaseSymbol(UnderlyingType.DeclaringMethod); + + /// + public string? FullName => UnderlyingType.FullName; + + /// + public string? Namespace => UnderlyingType.Namespace; + + /// + public GenericParameterAttributes GenericParameterAttributes => UnderlyingType.GenericParameterAttributes; + + /// + public int GenericParameterPosition => UnderlyingType.GenericParameterPosition; + + /// + public ITypeSymbol[] GenericTypeArguments => ResolveTypeSymbols(UnderlyingType.GenericTypeArguments); + + /// + public bool HasElementType => UnderlyingType.HasElementType; + + /// + public TypeCode TypeCode => Type.GetTypeCode(UnderlyingType); + + /// + public bool IsAbstract => UnderlyingType.IsAbstract; + + /// + public bool IsSZArray => UnderlyingType.IsSZArray(); + + /// + public bool IsArray => UnderlyingType.IsArray; + + /// + public bool IsAutoLayout => UnderlyingType.IsAutoLayout; + + /// + public bool IsExplicitLayout => UnderlyingType.IsExplicitLayout; + + /// + public bool IsByRef => UnderlyingType.IsByRef; + + /// + public bool IsClass => UnderlyingType.IsClass; + + /// + public bool IsEnum => UnderlyingType.IsEnum; + + /// + public bool IsInterface => UnderlyingType.IsInterface; + + /// + public bool IsConstructedGenericType => UnderlyingType.IsConstructedGenericType; + + /// + public bool IsGenericParameter => UnderlyingType.IsGenericParameter; + + /// + public bool IsGenericType => UnderlyingType.IsGenericType; + + /// + public bool IsGenericTypeDefinition => UnderlyingType.IsGenericTypeDefinition; + + /// + public bool IsLayoutSequential => UnderlyingType.IsLayoutSequential; + + /// + public bool IsNested => UnderlyingType.IsNested; + + /// + public bool IsNestedAssembly => UnderlyingType.IsNestedAssembly; + + /// + public bool IsNestedFamANDAssem => UnderlyingType.IsNestedFamANDAssem; + + /// + public bool IsNestedFamORAssem => UnderlyingType.IsNestedFamORAssem; + + /// + public bool IsNestedFamily => UnderlyingType.IsNestedFamily; + + /// + public bool IsNestedPrivate => UnderlyingType.IsNestedPrivate; + + /// + public bool IsNestedPublic => UnderlyingType.IsNestedPublic; + + /// + public bool IsNotPublic => UnderlyingType.IsNotPublic; + + /// + public bool IsPointer => UnderlyingType.IsPointer; + +#if NET8_0_OR_GREATER + + /// + public bool IsFunctionPointer => UnderlyingType.IsFunctionPointer; + + /// + public bool IsUnmanagedFunctionPointer => UnderlyingType.IsUnmanagedFunctionPointer; + +#else + + /// + public bool IsFunctionPointer => throw new NotImplementedException(); + + /// + public bool IsUnmanagedFunctionPointer => throw new NotImplementedException(); + +#endif + + /// + public bool IsPrimitive => UnderlyingType.IsPrimitive; + + /// + public bool IsPublic => UnderlyingType.IsPublic; + + /// + public bool IsSealed => UnderlyingType.IsSealed; + + /// + public bool IsSerializable => UnderlyingType.IsSerializable; + + /// + public bool IsValueType => UnderlyingType.IsValueType; + + /// + public bool IsVisible => UnderlyingType.IsVisible; + + /// + public bool IsSignatureType => throw new NotImplementedException(); + + /// + public bool IsSpecialName => UnderlyingType.IsSpecialName; + + /// + public IConstructorSymbol? TypeInitializer => ResolveConstructorSymbol(UnderlyingType.TypeInitializer); + + /// + public int GetArrayRank() + { + return UnderlyingType.GetArrayRank(); + } + + /// + public IConstructorSymbol? GetConstructor(BindingFlags bindingAttr, ITypeSymbol[] types) + { + return ResolveConstructorSymbol(UnderlyingType.GetConstructor(bindingAttr, binder: null, types.Unpack(), modifiers: null)); + } + + /// + public IConstructorSymbol? GetConstructor(ITypeSymbol[] types) + { + return ResolveConstructorSymbol(UnderlyingType.GetConstructor(types.Unpack())); + } + + /// + public IConstructorSymbol[] GetConstructors() + { + return ResolveConstructorSymbols(UnderlyingType.GetConstructors()); + } + + /// + public IConstructorSymbol[] GetConstructors(BindingFlags bindingAttr) + { + return ResolveConstructorSymbols(UnderlyingType.GetConstructors(bindingAttr)); + } + + /// + public IMemberSymbol[] GetDefaultMembers() + { + return ResolveMemberSymbols(UnderlyingType.GetDefaultMembers()); + } + + /// + public ITypeSymbol? GetElementType() + { + return ResolveTypeSymbol(UnderlyingType.GetElementType()); + } + + /// + public string? GetEnumName(object value) + { + return UnderlyingType.GetEnumName(value); + } + + /// + public string[] GetEnumNames() + { + return UnderlyingType.GetEnumNames(); + } + + /// + public ITypeSymbol GetEnumUnderlyingType() + { + return ResolveTypeSymbol(UnderlyingType.GetEnumUnderlyingType()); + } + + /// + public Array GetEnumValues() + { + return UnderlyingType.GetEnumValues(); + } + + /// + public IEventSymbol? GetEvent(string name) + { + return ResolveEventSymbol(UnderlyingType.GetEvent(name)); + } + + /// + public IEventSymbol? GetEvent(string name, BindingFlags bindingAttr) + { + return ResolveEventSymbol(UnderlyingType.GetEvent(name, bindingAttr)); + } + + /// + public IEventSymbol[] GetEvents() + { + return ResolveEventSymbols(UnderlyingType.GetEvents()); + } + + /// + public IEventSymbol[] GetEvents(BindingFlags bindingAttr) + { + return ResolveEventSymbols(UnderlyingType.GetEvents(bindingAttr)); + } + + /// + public IFieldSymbol? GetField(string name) + { + return ResolveFieldSymbol(UnderlyingType.GetField(name)); + } + + /// + public IFieldSymbol? GetField(string name, BindingFlags bindingAttr) + { + return ResolveFieldSymbol(UnderlyingType.GetField(name, bindingAttr)); + } + + /// + public IFieldSymbol[] GetFields() + { + return ResolveFieldSymbols(UnderlyingType.GetFields()); + } + + /// + public IFieldSymbol[] GetFields(BindingFlags bindingAttr) + { + return ResolveFieldSymbols(UnderlyingType.GetFields(bindingAttr)); + } + + /// + public ITypeSymbol[] GetGenericArguments() + { + return ResolveTypeSymbols(UnderlyingType.GetGenericArguments()); + } + + /// + public ITypeSymbol[] GetGenericParameterConstraints() + { + return ResolveTypeSymbols(UnderlyingType.GetGenericParameterConstraints()); + } + + /// + public ITypeSymbol GetGenericTypeDefinition() + { + return ResolveTypeSymbol(UnderlyingType.GetGenericTypeDefinition()); + } + + /// + public ITypeSymbol? GetInterface(string name) + { + return ResolveTypeSymbol(UnderlyingType.GetInterface(name)); + } + + /// + public ITypeSymbol? GetInterface(string name, bool ignoreCase) + { + return ResolveTypeSymbol(UnderlyingType.GetInterface(name, ignoreCase)); + } + + /// + public InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) + { + return ResolveInterfaceMapping(UnderlyingType.GetInterfaceMap(interfaceType.Unpack())); + } + + /// + public ITypeSymbol[] GetInterfaces(bool inherit = true) + { + if (inherit) + return ResolveTypeSymbols(UnderlyingType.GetInterfaces()); + else + throw new NotImplementedException(); + } + + /// + public IMemberSymbol[] GetMember(string name) + { + return ResolveMemberSymbols(UnderlyingType.GetMember(name)); + } + + /// + public IMemberSymbol[] GetMember(string name, System.Reflection.BindingFlags bindingAttr) + { + return ResolveMemberSymbols(UnderlyingType.GetMember(name, (BindingFlags)bindingAttr)); + } + + /// + public IMemberSymbol[] GetMember(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) + { + return ResolveMemberSymbols(UnderlyingType.GetMember(name, (MemberTypes)type, (BindingFlags)bindingAttr)); + } + + /// + public IMemberSymbol[] GetMembers(System.Reflection.BindingFlags bindingAttr) + { + return ResolveMemberSymbols(UnderlyingType.GetMembers((BindingFlags)bindingAttr)); + } + + /// + public IMemberSymbol[] GetMembers() + { + return ResolveMemberSymbols(UnderlyingType.GetMembers()); + } + + /// + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr) + { + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr)); + } + + /// + public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) + { + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, types.Unpack())); + } + + /// + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) + { + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), null)); + } + + /// + public IMethodSymbol? GetMethod(string name) + { + return ResolveMethodSymbol(UnderlyingType.GetMethod(name)); + } + + /// + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + { + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, (CallingConventions)callConvention, types.Unpack(), modifiers?.Unpack())); + } + + /// + public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + { + throw new NotImplementedException(); + } + + /// + public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + { + throw new NotImplementedException(); + } + + /// + public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + { + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), modifiers?.Unpack())); + } + + /// + public IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + { + throw new NotImplementedException(); + } + + /// + public IMethodSymbol[] GetMethods(System.Reflection.BindingFlags bindingAttr) + { + return ResolveMethodSymbols(UnderlyingType.GetMethods((BindingFlags)bindingAttr)); + } + + /// + public IMethodSymbol[] GetMethods() + { + return ResolveMethodSymbols(UnderlyingType.GetMethods()); + } + + /// + public ITypeSymbol? GetNestedType(string name) + { + return ResolveTypeSymbol(UnderlyingType.GetNestedType(name)); + } + + /// + public ITypeSymbol? GetNestedType(string name, System.Reflection.BindingFlags bindingAttr) + { + return ResolveTypeSymbol(UnderlyingType.GetNestedType(name, (BindingFlags)bindingAttr)); + } + + /// + public ITypeSymbol[] GetNestedTypes() + { + return ResolveTypeSymbols(UnderlyingType.GetNestedTypes()); + } + + /// + public ITypeSymbol[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr) + { + return ResolveTypeSymbols(UnderlyingType.GetNestedTypes((BindingFlags)bindingAttr)); + } + + /// + public IPropertySymbol[] GetProperties() + { + return ResolvePropertySymbols(UnderlyingType.GetProperties()); + } + + /// + public IPropertySymbol[] GetProperties(System.Reflection.BindingFlags bindingAttr) + { + return ResolvePropertySymbols(UnderlyingType.GetProperties((BindingFlags)bindingAttr)); + } + + /// + public IPropertySymbol? GetProperty(string name, ITypeSymbol[] types) + { + return ResolvePropertySymbol(UnderlyingType.GetProperty(name, types.Unpack())); + } + + /// + public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types) + { + return ResolvePropertySymbol(UnderlyingType.GetProperty(name, returnType?.Unpack(), types.Unpack())); + } + + /// + public IPropertySymbol? GetProperty(string name, System.Reflection.BindingFlags bindingAttr) + { + return ResolvePropertySymbol(UnderlyingType.GetProperty(name, (BindingFlags)bindingAttr)); + } + + /// + public IPropertySymbol? GetProperty(string name) + { + return ResolvePropertySymbol(UnderlyingType.GetProperty(name)); + } + + /// + public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) + { + return ResolvePropertySymbol(UnderlyingType.GetProperty(name, returnType?.Unpack())); + } + + /// + public bool IsAssignableFrom(ITypeSymbol? c) + { + return UnderlyingType.IsAssignableFrom(c?.Unpack()); + } + + /// + public bool IsEnumDefined(object value) + { + return UnderlyingType.IsEnumDefined(value); + } + + /// + public bool IsSubclassOf(ITypeSymbol c) + { + return UnderlyingType.IsSubclassOf(c.Unpack()); + } + + /// + public ITypeSymbol MakeArrayType() + { + return ResolveTypeSymbol(UnderlyingType.MakeArrayType()); + } + + /// + public ITypeSymbol MakeArrayType(int rank) + { + return ResolveTypeSymbol(UnderlyingType.MakeArrayType(rank)); + } + + /// + public ITypeSymbol MakeByRefType() + { + return ResolveTypeSymbol(UnderlyingType.MakeByRefType()); + } + + /// + public ITypeSymbol MakePointerType() + { + return ResolveTypeSymbol(UnderlyingType.MakePointerType()); + } + + /// + public ITypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments) + { + return ResolveTypeSymbol(UnderlyingType.MakeGenericType(typeArguments.Unpack())); + } + + #endregion + + } + +} From d715c0ed52c1e187f78a02d43c949013ce8c3cfb Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Tue, 8 Oct 2024 18:57:58 -0500 Subject: [PATCH 39/51] Pick proper emit type. --- src/IKVM.Runtime/CodeEmitter.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/IKVM.Runtime/CodeEmitter.cs b/src/IKVM.Runtime/CodeEmitter.cs index a74869d2c..f873048aa 100644 --- a/src/IKVM.Runtime/CodeEmitter.cs +++ b/src/IKVM.Runtime/CodeEmitter.cs @@ -79,8 +79,6 @@ public CodeEmitter Create(IMethodBaseSymbolBuilder method) return new CodeEmitter(context, method.GetILGenerator(), method.DeclaringType); } -#if IMPORTER == false - /// /// Creates a new instance. /// @@ -88,11 +86,9 @@ public CodeEmitter Create(IMethodBaseSymbolBuilder method) /// public CodeEmitter Create(DynamicMethod dm) { - return new CodeEmitter(context, new ReflectionILGenerator((ReflectionSymbolContext)context.Resolver.Symbols, dm.GetILGenerator()), null); + return new CodeEmitter(context, new ReflectionILGenerator((ReflectionSymbolContext)context.Resolver.Symbols, dm.GetILGenerator(), true), null); } -#endif - } sealed class CodeEmitter From 73e95bc1571deb8f5f81afd381ed425159624f23 Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Tue, 8 Oct 2024 18:58:33 -0500 Subject: [PATCH 40/51] Return null on tail. --- src/IKVM.JTReg.TestAdapter.Core/ErrorHandlerInterceptor.cs | 5 +++-- .../HarnessObserverInterceptor.cs | 2 +- src/IKVM.JTReg.TestAdapter.Core/JTRegTypes.cs | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/IKVM.JTReg.TestAdapter.Core/ErrorHandlerInterceptor.cs b/src/IKVM.JTReg.TestAdapter.Core/ErrorHandlerInterceptor.cs index 611f02bfd..4bbf7b61a 100644 --- a/src/IKVM.JTReg.TestAdapter.Core/ErrorHandlerInterceptor.cs +++ b/src/IKVM.JTReg.TestAdapter.Core/ErrorHandlerInterceptor.cs @@ -8,7 +8,7 @@ namespace IKVM.JTReg.TestAdapter.Core /// /// Generates an implementation of 'com.sun.javatest.TestFinder$ErrorHandler'. /// - class ErrorHandlerInterceptor : DispatchProxy + public class ErrorHandlerInterceptor : DispatchProxy { static readonly MethodInfo CreateMethodInfo = typeof(DispatchProxy).GetMethods() @@ -52,13 +52,14 @@ protected override object Invoke(MethodInfo targetMethod, object[] args) break; } - throw new InvalidOperationException(); + return null; } void error(string msg) { logger.SendMessage(JTRegTestMessageLevel.Error, msg); } + } } diff --git a/src/IKVM.JTReg.TestAdapter.Core/HarnessObserverInterceptor.cs b/src/IKVM.JTReg.TestAdapter.Core/HarnessObserverInterceptor.cs index aeb21f748..1d2d086e4 100644 --- a/src/IKVM.JTReg.TestAdapter.Core/HarnessObserverInterceptor.cs +++ b/src/IKVM.JTReg.TestAdapter.Core/HarnessObserverInterceptor.cs @@ -78,7 +78,7 @@ protected override object Invoke(MethodInfo targetMethod, object[] args) break; } - throw new InvalidOperationException(); + return null; } void startingTestRun(dynamic parameters) diff --git a/src/IKVM.JTReg.TestAdapter.Core/JTRegTypes.cs b/src/IKVM.JTReg.TestAdapter.Core/JTRegTypes.cs index cd24bff1c..5f8248c44 100644 --- a/src/IKVM.JTReg.TestAdapter.Core/JTRegTypes.cs +++ b/src/IKVM.JTReg.TestAdapter.Core/JTRegTypes.cs @@ -13,7 +13,7 @@ namespace IKVM.JTReg.TestAdapter.Core /// /// Provides information and accessors for JTReg types, which are dynamically loaded. /// - internal static class JTRegTypes + public static class JTRegTypes { static readonly string[] libs = Directory.GetFiles(Path.Combine(Path.GetDirectoryName(typeof(JTRegTestManager).Assembly.Location), "jtreg"), "*.jar"); From 4f9e56943fcfe0ada27733827a8ffebbb6b573bd Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Tue, 8 Oct 2024 19:28:33 -0500 Subject: [PATCH 41/51] public --- src/IKVM.JTReg.TestAdapter.Core/HarnessObserverInterceptor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/IKVM.JTReg.TestAdapter.Core/HarnessObserverInterceptor.cs b/src/IKVM.JTReg.TestAdapter.Core/HarnessObserverInterceptor.cs index 1d2d086e4..ffcfee1f5 100644 --- a/src/IKVM.JTReg.TestAdapter.Core/HarnessObserverInterceptor.cs +++ b/src/IKVM.JTReg.TestAdapter.Core/HarnessObserverInterceptor.cs @@ -10,7 +10,7 @@ namespace IKVM.JTReg.TestAdapter.Core /// /// Generates an implementation of 'com.sun.javatest.Harness$Observer'. /// - class HarnessObserverInterceptor : DispatchProxy + public class HarnessObserverInterceptor : DispatchProxy { static readonly MethodInfo CreateMethodInfo = typeof(DispatchProxy).GetMethods() From d4eab6a3fe51946e66048940019a73917fb5d2fd Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Wed, 9 Oct 2024 00:20:31 -0500 Subject: [PATCH 42/51] Add IncompleteMethods back in. --- .../Emit/ReflectionTypeSymbolBuilder.cs | 61 +++++++++++++++++++ .../Reflection/ReflectionTypeSymbolBase.cs | 20 +++--- 2 files changed, 71 insertions(+), 10 deletions(-) diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs index 5ce8a95be..7b9f0fb8a 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.InteropServices; @@ -311,6 +312,66 @@ public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) #endregion + /// + public override IMethodSymbol? GetMethod(string name) + { + if (IsComplete) + return base.GetMethod(name); + else + return GetIncompleteMethods().FirstOrDefault(i => i.Name == name); + } + + /// + public override IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types, ParameterModifier[]? modifiers) + { + if (IsComplete) + return base.GetMethod(name, bindingAttr, types, modifiers); + else + throw new NotImplementedException(); + } + + /// + public override IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers) + { + if (IsComplete) + return base.GetMethod(name, bindingAttr, callConvention, types, modifiers); + else + throw new NotImplementedException(); + } + + /// + public override IMethodSymbol[] GetMethods() + { + if (IsComplete) + return base.GetMethods(); + else + return GetIncompleteMethods(); + } + + /// + public override IMethodSymbol[] GetMethods(BindingFlags bindingAttr) + { + if (IsComplete) + return base.GetMethods(bindingAttr); + else + return GetIncompleteMethods(bindingAttr); + } + + /// + /// Gets the set of incomplete methods. + /// + /// + IMethodSymbol[] GetIncompleteMethods(BindingFlags bindingAttr = BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance) + { + if (_incompleteMethods == null) + return []; + else + return SymbolUtil.FilterMethods(this, _incompleteMethods, bindingAttr).Cast().ToArray(); + } + + /// + public override bool IsComplete => _type != null; + /// public void Complete() { diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbolBase.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbolBase.cs index 33c07a976..fbc1bd678 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbolBase.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbolBase.cs @@ -483,49 +483,49 @@ public IMemberSymbol[] GetMembers() } /// - public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr) + public virtual IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr) { return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr)); } /// - public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) + public virtual IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) { return ResolveMethodSymbol(UnderlyingType.GetMethod(name, types.Unpack())); } /// - public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) + public virtual IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) { return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), null)); } /// - public IMethodSymbol? GetMethod(string name) + public virtual IMethodSymbol? GetMethod(string name) { return ResolveMethodSymbol(UnderlyingType.GetMethod(name)); } /// - public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + public virtual IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, (CallingConventions)callConvention, types.Unpack(), modifiers?.Unpack())); } /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + public virtual IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { throw new NotImplementedException(); } /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + public virtual IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { throw new NotImplementedException(); } /// - public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + public virtual IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) { return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), modifiers?.Unpack())); } @@ -537,13 +537,13 @@ public IMemberSymbol[] GetMembers() } /// - public IMethodSymbol[] GetMethods(System.Reflection.BindingFlags bindingAttr) + public virtual IMethodSymbol[] GetMethods(System.Reflection.BindingFlags bindingAttr) { return ResolveMethodSymbols(UnderlyingType.GetMethods((BindingFlags)bindingAttr)); } /// - public IMethodSymbol[] GetMethods() + public virtual IMethodSymbol[] GetMethods() { return ResolveMethodSymbols(UnderlyingType.GetMethods()); } From 2daab5a4c3ade6170bb2e598b555f89ccb0311be Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Wed, 9 Oct 2024 13:44:07 -0500 Subject: [PATCH 43/51] , --- .../Emit/ReflectionTypeSymbolBuilder.cs | 16 +- .../ReflectionGenericSpecTypeSymbol.cs | 1 + .../Reflection/ReflectionTypeSpecSymbol.cs | 7 - .../Reflection/ReflectionTypeSymbolBase.cs | 236 +++++++++--------- 4 files changed, 127 insertions(+), 133 deletions(-) diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs index 7b9f0fb8a..df41d1cb6 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs @@ -32,10 +32,10 @@ public ReflectionTypeSymbolBuilder(ReflectionSymbolContext context, IReflectionM } /// - public override Type UnderlyingType => _type ?? _builder; + public override Type UnderlyingType => UnderlyingTypeBuilder; /// - public override Type UnderlyingEmitType => _builder; + public override Type UnderlyingEmitType => UnderlyingTypeBuilder; /// public override Type UnderlyingDynamicEmitType => _type ?? throw new InvalidOperationException(); @@ -392,27 +392,27 @@ public void OnComplete() { const BindingFlags DefaultBindingFlags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static; - foreach (var i in GetGenericArguments()) + foreach (var i in GetGenericArguments() ?? []) if (i is IReflectionGenericTypeParameterSymbolBuilder b) b.OnComplete(); - foreach (var i in GetConstructors(DefaultBindingFlags)) + foreach (var i in GetConstructors(DefaultBindingFlags) ?? []) if (i is IReflectionConstructorSymbolBuilder b) b.OnComplete(); - foreach (var i in GetMethods(DefaultBindingFlags)) + foreach (var i in GetMethods(DefaultBindingFlags) ?? []) if (i is IReflectionMethodSymbolBuilder b) b.OnComplete(); - foreach (var i in GetFields(DefaultBindingFlags)) + foreach (var i in GetFields(DefaultBindingFlags) ?? []) if (i is IReflectionFieldSymbolBuilder b) b.OnComplete(); - foreach (var i in GetProperties(DefaultBindingFlags)) + foreach (var i in GetProperties(DefaultBindingFlags) ?? []) if (i is IReflectionPropertySymbolBuilder b) b.OnComplete(); - foreach (var m in GetEvents(DefaultBindingFlags)) + foreach (var m in GetEvents(DefaultBindingFlags) ?? []) if (m is IReflectionPropertySymbolBuilder b) b.OnComplete(); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericSpecTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericSpecTypeSymbol.cs index bba26a6ad..f7c5cadfc 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericSpecTypeSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericSpecTypeSymbol.cs @@ -15,6 +15,7 @@ class ReflectionGenericSpecTypeSymbol : ReflectionTypeSpecSymbol /// /// /// + /// public ReflectionGenericSpecTypeSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol elementType, IReflectionTypeSymbol[] genericTypeArguments) : base(context, resolvingModule, elementType) { diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSpecSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSpecSymbol.cs index bc68441c5..121f36a58 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSpecSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSpecSymbol.cs @@ -8,13 +8,6 @@ abstract class ReflectionTypeSpecSymbol : ReflectionTypeSymbolBase readonly IReflectionTypeSymbol _elementType; - ReflectionMethodTable _methodTable; - ReflectionFieldTable _fieldTable; - ReflectionPropertyTable _propertyTable; - ReflectionEventTable _eventTable; - ReflectionGenericTypeParameterTable _genericTypeParameterTable; - ReflectionTypeSpecTable _specTable; - /// /// Initializes a new instance. /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbolBase.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbolBase.cs index fbc1bd678..833571069 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbolBase.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbolBase.cs @@ -141,310 +141,310 @@ public IReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeParame #region ITypeSymbol /// - public IAssemblySymbol Assembly => ResolveAssemblySymbol(UnderlyingType.Assembly); + public virtual IAssemblySymbol Assembly => ResolveAssemblySymbol(UnderlyingType.Assembly); /// - public string? AssemblyQualifiedName => UnderlyingType.AssemblyQualifiedName; + public virtual string? AssemblyQualifiedName => UnderlyingType.AssemblyQualifiedName; /// - public TypeAttributes Attributes => UnderlyingType.Attributes; + public virtual TypeAttributes Attributes => UnderlyingType.Attributes; /// - public ITypeSymbol? BaseType => ResolveTypeSymbol(UnderlyingType.BaseType); + public virtual ITypeSymbol? BaseType => ResolveTypeSymbol(UnderlyingType.BaseType); /// - public bool ContainsGenericParameters => UnderlyingType.ContainsGenericParameters; + public virtual bool ContainsGenericParameters => UnderlyingType.ContainsGenericParameters; /// - public IMethodBaseSymbol? DeclaringMethod => ResolveMethodBaseSymbol(UnderlyingType.DeclaringMethod); + public virtual IMethodBaseSymbol? DeclaringMethod => ResolveMethodBaseSymbol(UnderlyingType.DeclaringMethod); /// - public string? FullName => UnderlyingType.FullName; + public virtual string? FullName => UnderlyingType.FullName; /// - public string? Namespace => UnderlyingType.Namespace; + public virtual string? Namespace => UnderlyingType.Namespace; /// - public GenericParameterAttributes GenericParameterAttributes => UnderlyingType.GenericParameterAttributes; + public virtual GenericParameterAttributes GenericParameterAttributes => UnderlyingType.GenericParameterAttributes; /// - public int GenericParameterPosition => UnderlyingType.GenericParameterPosition; + public virtual int GenericParameterPosition => UnderlyingType.GenericParameterPosition; /// - public ITypeSymbol[] GenericTypeArguments => ResolveTypeSymbols(UnderlyingType.GenericTypeArguments); + public virtual ITypeSymbol[] GenericTypeArguments => ResolveTypeSymbols(UnderlyingType.GenericTypeArguments); /// - public bool HasElementType => UnderlyingType.HasElementType; + public virtual bool HasElementType => UnderlyingType.HasElementType; /// - public TypeCode TypeCode => Type.GetTypeCode(UnderlyingType); + public virtual TypeCode TypeCode => Type.GetTypeCode(UnderlyingType); /// - public bool IsAbstract => UnderlyingType.IsAbstract; + public virtual bool IsAbstract => UnderlyingType.IsAbstract; /// - public bool IsSZArray => UnderlyingType.IsSZArray(); + public virtual bool IsSZArray => UnderlyingType.IsSZArray(); /// - public bool IsArray => UnderlyingType.IsArray; + public virtual bool IsArray => UnderlyingType.IsArray; /// - public bool IsAutoLayout => UnderlyingType.IsAutoLayout; + public virtual bool IsAutoLayout => UnderlyingType.IsAutoLayout; /// - public bool IsExplicitLayout => UnderlyingType.IsExplicitLayout; + public virtual bool IsExplicitLayout => UnderlyingType.IsExplicitLayout; /// - public bool IsByRef => UnderlyingType.IsByRef; + public virtual bool IsByRef => UnderlyingType.IsByRef; /// - public bool IsClass => UnderlyingType.IsClass; + public virtual bool IsClass => UnderlyingType.IsClass; /// - public bool IsEnum => UnderlyingType.IsEnum; + public virtual bool IsEnum => UnderlyingType.IsEnum; /// - public bool IsInterface => UnderlyingType.IsInterface; + public virtual bool IsInterface => UnderlyingType.IsInterface; /// - public bool IsConstructedGenericType => UnderlyingType.IsConstructedGenericType; + public virtual bool IsConstructedGenericType => UnderlyingType.IsConstructedGenericType; /// - public bool IsGenericParameter => UnderlyingType.IsGenericParameter; + public virtual bool IsGenericParameter => UnderlyingType.IsGenericParameter; /// - public bool IsGenericType => UnderlyingType.IsGenericType; + public virtual bool IsGenericType => UnderlyingType.IsGenericType; /// - public bool IsGenericTypeDefinition => UnderlyingType.IsGenericTypeDefinition; + public virtual bool IsGenericTypeDefinition => UnderlyingType.IsGenericTypeDefinition; /// - public bool IsLayoutSequential => UnderlyingType.IsLayoutSequential; + public virtual bool IsLayoutSequential => UnderlyingType.IsLayoutSequential; /// - public bool IsNested => UnderlyingType.IsNested; + public virtual bool IsNested => UnderlyingType.IsNested; /// - public bool IsNestedAssembly => UnderlyingType.IsNestedAssembly; + public virtual bool IsNestedAssembly => UnderlyingType.IsNestedAssembly; /// - public bool IsNestedFamANDAssem => UnderlyingType.IsNestedFamANDAssem; + public virtual bool IsNestedFamANDAssem => UnderlyingType.IsNestedFamANDAssem; /// - public bool IsNestedFamORAssem => UnderlyingType.IsNestedFamORAssem; + public virtual bool IsNestedFamORAssem => UnderlyingType.IsNestedFamORAssem; /// - public bool IsNestedFamily => UnderlyingType.IsNestedFamily; + public virtual bool IsNestedFamily => UnderlyingType.IsNestedFamily; /// - public bool IsNestedPrivate => UnderlyingType.IsNestedPrivate; + public virtual bool IsNestedPrivate => UnderlyingType.IsNestedPrivate; /// - public bool IsNestedPublic => UnderlyingType.IsNestedPublic; + public virtual bool IsNestedPublic => UnderlyingType.IsNestedPublic; /// - public bool IsNotPublic => UnderlyingType.IsNotPublic; + public virtual bool IsNotPublic => UnderlyingType.IsNotPublic; /// - public bool IsPointer => UnderlyingType.IsPointer; + public virtual bool IsPointer => UnderlyingType.IsPointer; #if NET8_0_OR_GREATER /// - public bool IsFunctionPointer => UnderlyingType.IsFunctionPointer; + public virtual bool IsFunctionPointer => UnderlyingType.IsFunctionPointer; /// - public bool IsUnmanagedFunctionPointer => UnderlyingType.IsUnmanagedFunctionPointer; + public virtual bool IsUnmanagedFunctionPointer => UnderlyingType.IsUnmanagedFunctionPointer; #else /// - public bool IsFunctionPointer => throw new NotImplementedException(); + public virtual bool IsFunctionPointer => throw new NotImplementedException(); /// - public bool IsUnmanagedFunctionPointer => throw new NotImplementedException(); + public virtual bool IsUnmanagedFunctionPointer => throw new NotImplementedException(); #endif /// - public bool IsPrimitive => UnderlyingType.IsPrimitive; + public virtual bool IsPrimitive => UnderlyingType.IsPrimitive; /// - public bool IsPublic => UnderlyingType.IsPublic; + public virtual bool IsPublic => UnderlyingType.IsPublic; /// - public bool IsSealed => UnderlyingType.IsSealed; + public virtual bool IsSealed => UnderlyingType.IsSealed; /// - public bool IsSerializable => UnderlyingType.IsSerializable; + public virtual bool IsSerializable => UnderlyingType.IsSerializable; /// - public bool IsValueType => UnderlyingType.IsValueType; + public virtual bool IsValueType => UnderlyingType.IsValueType; /// - public bool IsVisible => UnderlyingType.IsVisible; + public virtual bool IsVisible => UnderlyingType.IsVisible; /// - public bool IsSignatureType => throw new NotImplementedException(); + public virtual bool IsSignatureType => throw new NotImplementedException(); /// - public bool IsSpecialName => UnderlyingType.IsSpecialName; + public virtual bool IsSpecialName => UnderlyingType.IsSpecialName; /// - public IConstructorSymbol? TypeInitializer => ResolveConstructorSymbol(UnderlyingType.TypeInitializer); + public virtual IConstructorSymbol? TypeInitializer => ResolveConstructorSymbol(UnderlyingType.TypeInitializer); /// - public int GetArrayRank() + public virtual int GetArrayRank() { return UnderlyingType.GetArrayRank(); } /// - public IConstructorSymbol? GetConstructor(BindingFlags bindingAttr, ITypeSymbol[] types) + public virtual IConstructorSymbol? GetConstructor(BindingFlags bindingAttr, ITypeSymbol[] types) { return ResolveConstructorSymbol(UnderlyingType.GetConstructor(bindingAttr, binder: null, types.Unpack(), modifiers: null)); } /// - public IConstructorSymbol? GetConstructor(ITypeSymbol[] types) + public virtual IConstructorSymbol? GetConstructor(ITypeSymbol[] types) { return ResolveConstructorSymbol(UnderlyingType.GetConstructor(types.Unpack())); } /// - public IConstructorSymbol[] GetConstructors() + public virtual IConstructorSymbol[] GetConstructors() { return ResolveConstructorSymbols(UnderlyingType.GetConstructors()); } /// - public IConstructorSymbol[] GetConstructors(BindingFlags bindingAttr) + public virtual IConstructorSymbol[] GetConstructors(BindingFlags bindingAttr) { return ResolveConstructorSymbols(UnderlyingType.GetConstructors(bindingAttr)); } /// - public IMemberSymbol[] GetDefaultMembers() + public virtual IMemberSymbol[] GetDefaultMembers() { return ResolveMemberSymbols(UnderlyingType.GetDefaultMembers()); } /// - public ITypeSymbol? GetElementType() + public virtual ITypeSymbol? GetElementType() { return ResolveTypeSymbol(UnderlyingType.GetElementType()); } /// - public string? GetEnumName(object value) + public virtual string? GetEnumName(object value) { return UnderlyingType.GetEnumName(value); } /// - public string[] GetEnumNames() + public virtual string[] GetEnumNames() { return UnderlyingType.GetEnumNames(); } /// - public ITypeSymbol GetEnumUnderlyingType() + public virtual ITypeSymbol GetEnumUnderlyingType() { return ResolveTypeSymbol(UnderlyingType.GetEnumUnderlyingType()); } /// - public Array GetEnumValues() + public virtual Array GetEnumValues() { return UnderlyingType.GetEnumValues(); } /// - public IEventSymbol? GetEvent(string name) + public virtual IEventSymbol? GetEvent(string name) { return ResolveEventSymbol(UnderlyingType.GetEvent(name)); } /// - public IEventSymbol? GetEvent(string name, BindingFlags bindingAttr) + public virtual IEventSymbol? GetEvent(string name, BindingFlags bindingAttr) { return ResolveEventSymbol(UnderlyingType.GetEvent(name, bindingAttr)); } /// - public IEventSymbol[] GetEvents() + public virtual IEventSymbol[] GetEvents() { return ResolveEventSymbols(UnderlyingType.GetEvents()); } /// - public IEventSymbol[] GetEvents(BindingFlags bindingAttr) + public virtual IEventSymbol[] GetEvents(BindingFlags bindingAttr) { return ResolveEventSymbols(UnderlyingType.GetEvents(bindingAttr)); } /// - public IFieldSymbol? GetField(string name) + public virtual IFieldSymbol? GetField(string name) { return ResolveFieldSymbol(UnderlyingType.GetField(name)); } /// - public IFieldSymbol? GetField(string name, BindingFlags bindingAttr) + public virtual IFieldSymbol? GetField(string name, BindingFlags bindingAttr) { return ResolveFieldSymbol(UnderlyingType.GetField(name, bindingAttr)); } /// - public IFieldSymbol[] GetFields() + public virtual IFieldSymbol[] GetFields() { return ResolveFieldSymbols(UnderlyingType.GetFields()); } /// - public IFieldSymbol[] GetFields(BindingFlags bindingAttr) + public virtual IFieldSymbol[] GetFields(BindingFlags bindingAttr) { return ResolveFieldSymbols(UnderlyingType.GetFields(bindingAttr)); } /// - public ITypeSymbol[] GetGenericArguments() + public virtual ITypeSymbol[] GetGenericArguments() { return ResolveTypeSymbols(UnderlyingType.GetGenericArguments()); } /// - public ITypeSymbol[] GetGenericParameterConstraints() + public virtual ITypeSymbol[] GetGenericParameterConstraints() { return ResolveTypeSymbols(UnderlyingType.GetGenericParameterConstraints()); } /// - public ITypeSymbol GetGenericTypeDefinition() + public virtual ITypeSymbol GetGenericTypeDefinition() { return ResolveTypeSymbol(UnderlyingType.GetGenericTypeDefinition()); } /// - public ITypeSymbol? GetInterface(string name) + public virtual ITypeSymbol? GetInterface(string name) { return ResolveTypeSymbol(UnderlyingType.GetInterface(name)); } /// - public ITypeSymbol? GetInterface(string name, bool ignoreCase) + public virtual ITypeSymbol? GetInterface(string name, bool ignoreCase) { return ResolveTypeSymbol(UnderlyingType.GetInterface(name, ignoreCase)); } /// - public InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) + public virtual InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) { return ResolveInterfaceMapping(UnderlyingType.GetInterfaceMap(interfaceType.Unpack())); } /// - public ITypeSymbol[] GetInterfaces(bool inherit = true) + public virtual ITypeSymbol[] GetInterfaces(bool inherit = true) { if (inherit) return ResolveTypeSymbols(UnderlyingType.GetInterfaces()); @@ -453,85 +453,85 @@ public ITypeSymbol[] GetInterfaces(bool inherit = true) } /// - public IMemberSymbol[] GetMember(string name) + public virtual IMemberSymbol[] GetMember(string name) { return ResolveMemberSymbols(UnderlyingType.GetMember(name)); } /// - public IMemberSymbol[] GetMember(string name, System.Reflection.BindingFlags bindingAttr) + public virtual IMemberSymbol[] GetMember(string name, BindingFlags bindingAttr) { - return ResolveMemberSymbols(UnderlyingType.GetMember(name, (BindingFlags)bindingAttr)); + return ResolveMemberSymbols(UnderlyingType.GetMember(name, bindingAttr)); } /// - public IMemberSymbol[] GetMember(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) + public virtual IMemberSymbol[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) { - return ResolveMemberSymbols(UnderlyingType.GetMember(name, (MemberTypes)type, (BindingFlags)bindingAttr)); + return ResolveMemberSymbols(UnderlyingType.GetMember(name, type, bindingAttr)); } /// - public IMemberSymbol[] GetMembers(System.Reflection.BindingFlags bindingAttr) + public virtual IMemberSymbol[] GetMembers(BindingFlags bindingAttr) { - return ResolveMemberSymbols(UnderlyingType.GetMembers((BindingFlags)bindingAttr)); + return ResolveMemberSymbols(UnderlyingType.GetMembers(bindingAttr)); } /// - public IMemberSymbol[] GetMembers() + public virtual IMemberSymbol[] GetMembers() { return ResolveMemberSymbols(UnderlyingType.GetMembers()); } /// - public virtual IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr) + public virtual IMethodSymbol? GetMethod(string name) { - return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr)); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name)); } /// - public virtual IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) + public virtual IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr) { - return ResolveMethodSymbol(UnderlyingType.GetMethod(name, types.Unpack())); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, bindingAttr)); } /// - public virtual IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) + public virtual IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) { - return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), null)); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, types.Unpack())); } /// - public virtual IMethodSymbol? GetMethod(string name) + public virtual IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types) { - return ResolveMethodSymbol(UnderlyingType.GetMethod(name)); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, bindingAttr, null, types.Unpack(), null)); } /// - public virtual IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + public virtual IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types, ParameterModifier[]? modifiers) { - return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, (CallingConventions)callConvention, types.Unpack(), modifiers?.Unpack())); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, bindingAttr, null, types.Unpack(), modifiers?.Unpack())); } /// - public virtual IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + public virtual IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, ITypeSymbol[] types, ParameterModifier[]? modifiers) { throw new NotImplementedException(); } /// - public virtual IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + public virtual IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers) { - throw new NotImplementedException(); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, bindingAttr, null, callConvention, types.Unpack(), modifiers?.Unpack())); } /// - public virtual IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + public virtual IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, ParameterModifier[]? modifiers) { - return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), modifiers?.Unpack())); + throw new NotImplementedException(); } /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) + public virtual IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers) { throw new NotImplementedException(); } @@ -549,115 +549,115 @@ public virtual IMethodSymbol[] GetMethods() } /// - public ITypeSymbol? GetNestedType(string name) + public virtual ITypeSymbol? GetNestedType(string name) { return ResolveTypeSymbol(UnderlyingType.GetNestedType(name)); } /// - public ITypeSymbol? GetNestedType(string name, System.Reflection.BindingFlags bindingAttr) + public virtual ITypeSymbol? GetNestedType(string name, System.Reflection.BindingFlags bindingAttr) { return ResolveTypeSymbol(UnderlyingType.GetNestedType(name, (BindingFlags)bindingAttr)); } /// - public ITypeSymbol[] GetNestedTypes() + public virtual ITypeSymbol[] GetNestedTypes() { return ResolveTypeSymbols(UnderlyingType.GetNestedTypes()); } /// - public ITypeSymbol[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr) + public virtual ITypeSymbol[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr) { return ResolveTypeSymbols(UnderlyingType.GetNestedTypes((BindingFlags)bindingAttr)); } /// - public IPropertySymbol[] GetProperties() + public virtual IPropertySymbol[] GetProperties() { return ResolvePropertySymbols(UnderlyingType.GetProperties()); } /// - public IPropertySymbol[] GetProperties(System.Reflection.BindingFlags bindingAttr) + public virtual IPropertySymbol[] GetProperties(System.Reflection.BindingFlags bindingAttr) { return ResolvePropertySymbols(UnderlyingType.GetProperties((BindingFlags)bindingAttr)); } /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol[] types) + public virtual IPropertySymbol? GetProperty(string name, ITypeSymbol[] types) { return ResolvePropertySymbol(UnderlyingType.GetProperty(name, types.Unpack())); } /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types) + public virtual IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types) { return ResolvePropertySymbol(UnderlyingType.GetProperty(name, returnType?.Unpack(), types.Unpack())); } /// - public IPropertySymbol? GetProperty(string name, System.Reflection.BindingFlags bindingAttr) + public virtual IPropertySymbol? GetProperty(string name, System.Reflection.BindingFlags bindingAttr) { return ResolvePropertySymbol(UnderlyingType.GetProperty(name, (BindingFlags)bindingAttr)); } /// - public IPropertySymbol? GetProperty(string name) + public virtual IPropertySymbol? GetProperty(string name) { return ResolvePropertySymbol(UnderlyingType.GetProperty(name)); } /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) + public virtual IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) { return ResolvePropertySymbol(UnderlyingType.GetProperty(name, returnType?.Unpack())); } /// - public bool IsAssignableFrom(ITypeSymbol? c) + public virtual bool IsAssignableFrom(ITypeSymbol? c) { return UnderlyingType.IsAssignableFrom(c?.Unpack()); } /// - public bool IsEnumDefined(object value) + public virtual bool IsEnumDefined(object value) { return UnderlyingType.IsEnumDefined(value); } /// - public bool IsSubclassOf(ITypeSymbol c) + public virtual bool IsSubclassOf(ITypeSymbol c) { return UnderlyingType.IsSubclassOf(c.Unpack()); } /// - public ITypeSymbol MakeArrayType() + public virtual ITypeSymbol MakeArrayType() { return ResolveTypeSymbol(UnderlyingType.MakeArrayType()); } /// - public ITypeSymbol MakeArrayType(int rank) + public virtual ITypeSymbol MakeArrayType(int rank) { return ResolveTypeSymbol(UnderlyingType.MakeArrayType(rank)); } /// - public ITypeSymbol MakeByRefType() + public virtual ITypeSymbol MakeByRefType() { return ResolveTypeSymbol(UnderlyingType.MakeByRefType()); } /// - public ITypeSymbol MakePointerType() + public virtual ITypeSymbol MakePointerType() { return ResolveTypeSymbol(UnderlyingType.MakePointerType()); } /// - public ITypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments) + public virtual ITypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments) { return ResolveTypeSymbol(UnderlyingType.MakeGenericType(typeArguments.Unpack())); } From b7b2716de1768f0d3b2f7e520dca33279dd2ba00 Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Sun, 13 Oct 2024 16:08:52 -0500 Subject: [PATCH 44/51] . --- .../Reflection/ReflectionSymbolTests.cs | 79 ++- .../Reflection/ReflectionExtensions.cs | 75 ++ src/IKVM.CoreLib/Symbols/CustomAttribute.cs | 148 +++- .../Symbols/Emit/IAssemblySymbolBuilder.cs | 15 +- .../Symbols/Emit/ICustomAttributeBuilder.cs | 11 - .../Emit/ICustomAttributeProviderBuilder.cs | 15 + .../Symbols/Emit/IEventSymbolBuilder.cs | 13 - .../Symbols/Emit/IFieldSymbolBuilder.cs | 13 - .../Symbols/Emit/IMemberSymbolBuilder.cs | 2 +- .../Symbols/Emit/IMethodBaseSymbolBuilder.cs | 13 - .../Symbols/Emit/IModuleSymbolBuilder.cs | 15 +- .../Symbols/Emit/IParameterSymbolBuilder.cs | 16 +- .../Symbols/Emit/IPropertySymbolBuilder.cs | 13 - .../Symbols/Emit/ITypeSymbolBuilder.cs | 13 - .../Symbols/ICustomAttributeProvider.cs | 2 +- src/IKVM.CoreLib/Symbols/ISymbolContext.cs | 45 +- ...eflectionCustomAttributeProviderBuilder.cs | 13 + .../IIkvmReflectionMemberSymbolBuilder.cs | 3 +- .../IkvmReflectionAssemblySymbolBuilder.cs | 11 +- .../IkvmReflectionConstructorSymbolBuilder.cs | 12 +- .../IkvmReflectionCustomAttributeBuilder.cs | 29 - .../Emit/IkvmReflectionEventSymbolBuilder.cs | 12 +- .../Emit/IkvmReflectionFieldSymbolBuilder.cs | 22 +- ...ectionGenericTypeParameterSymbolBuilder.cs | 11 + .../Emit/IkvmReflectionMemberSymbolBuilder.cs | 9 +- .../IkvmReflectionMethodBaseSymbolBuilder.cs | 6 - .../Emit/IkvmReflectionMethodSymbolBuilder.cs | 22 +- .../Emit/IkvmReflectionModuleSymbolBuilder.cs | 10 +- .../IkvmReflectionParameterSymbolBuilder.cs | 10 +- .../IkvmReflectionPropertySymbolBuilder.cs | 12 +- .../Emit/IkvmReflectionTypeSymbolBuilder.cs | 21 +- .../IkvmReflectionSymbolContext.cs | 29 +- .../IkvmReflection/IkvmReflectionTypeTable.cs | 2 +- .../IkvmReflection/IkvmReflectionUtil.cs | 107 ++- ...eflectionCustomAttributeProviderBuilder.cs | 13 + ...ectionGenericTypeParameterSymbolBuilder.cs | 7 +- .../IReflectionMethodBaseSymbolBuilder.cs | 11 +- .../Emit/IReflectionMethodSymbolBuilder.cs | 7 - .../Emit/IReflectionModuleSymbolBuilder.cs | 57 -- .../Emit/IReflectionPropertySymbolBuilder.cs | 7 - .../Emit/IReflectionSymbolBuilder.cs | 72 -- .../Emit/IReflectionTypeSymbolBuilder.cs | 42 -- .../Emit/ReflectionAssemblySymbolBuilder.cs | 168 +---- .../ReflectionConstructorSymbolBuilder.cs | 91 ++- .../Emit/ReflectionCustomAttributeBuilder.cs | 29 - .../Emit/ReflectionEventBuilderInfo.cs | 1 + .../Emit/ReflectionEventSymbolBuilder.cs | 96 +-- .../Emit/ReflectionFieldSymbolBuilder.cs | 99 +-- ...ectionGenericTypeParameterSymbolBuilder.cs | 662 +----------------- .../Reflection/Emit/ReflectionILGenerator.cs | 17 +- .../Emit/ReflectionMemberSymbolBuilder.cs | 348 --------- .../Emit/ReflectionMethodBaseSymbolBuilder.cs | 167 ----- .../Emit/ReflectionMethodSymbolBuilder.cs | 144 ++-- .../Emit/ReflectionModuleSymbolBuilder.cs | 397 +---------- .../Emit/ReflectionParameterSymbolBuilder.cs | 22 +- .../Emit/ReflectionPropertySymbolBuilder.cs | 141 +--- .../Emit/ReflectionSymbolBuilder.cs | 12 +- .../Emit/ReflectionTypeSymbolBuilder.cs | 118 ++-- .../Reflection/IReflectionAssemblySymbol.cs | 5 + .../IReflectionConstructorSymbol.cs | 7 +- .../Reflection/IReflectionEventSymbol.cs | 4 +- .../Reflection/IReflectionFieldSymbol.cs | 9 +- .../Reflection/IReflectionMemberSymbol.cs | 4 +- .../Reflection/IReflectionMethodBaseSymbol.cs | 12 +- .../Reflection/IReflectionMethodSymbol.cs | 17 +- .../Reflection/IReflectionModuleSymbol.cs | 65 ++ .../Reflection/IReflectionParameterSymbol.cs | 4 +- .../Reflection/IReflectionPropertySymbol.cs | 14 +- .../Symbols/Reflection/IReflectionSymbol.cs | 83 +++ .../Reflection/IReflectionTypeSymbol.cs | 62 +- .../Reflection/ReflectionArrayTypeSymbol.cs | 5 +- .../Reflection/ReflectionAssemblySymbol.cs | 9 +- .../Reflection/ReflectionByRefTypeSymbol.cs | 5 +- .../Reflection/ReflectionConstructorSymbol.cs | 8 +- .../Reflection/ReflectionEventSymbol.cs | 7 +- .../Reflection/ReflectionFieldSymbol.cs | 10 +- .../ReflectionGenericSpecTypeSymbol.cs | 5 +- .../ReflectionGenericTypeParameterSymbol.cs | 54 +- .../Reflection/ReflectionMemberSymbol.cs | 9 +- .../Reflection/ReflectionMethodBaseSymbol.cs | 16 +- .../Reflection/ReflectionMethodSymbol.cs | 17 +- .../Reflection/ReflectionModuleSymbol.cs | 72 +- .../Reflection/ReflectionModuleTable.cs | 11 - .../Reflection/ReflectionParameterSymbol.cs | 2 +- .../Reflection/ReflectionPointerTypeSymbol.cs | 5 +- .../Reflection/ReflectionPropertySymbol.cs | 16 +- .../Reflection/ReflectionSZArrayTypeSymbol.cs | 5 +- .../Symbols/Reflection/ReflectionSymbol.cs | 31 + .../Reflection/ReflectionSymbolContext.cs | 38 +- .../Reflection/ReflectionTypeSymbol.cs | 3 + .../Reflection/ReflectionTypeSymbolBase.cs | 80 ++- .../Symbols/Reflection/ReflectionUtil.cs | 95 ++- src/IKVM.CoreLib/Symbols/SymbolUtil.cs | 26 +- .../ErrorHandlerInterceptor.cs | 4 +- src/IKVM.Runtime/AttributeHelper.cs | 158 ++--- src/IKVM.Runtime/ByteCodeHelper.cs | 6 +- src/IKVM.Runtime/DynamicClassLoader.cs | 14 +- src/IKVM.Runtime/JNI/JNIEnv.cs | 14 +- src/IKVM.Runtime/JVM.Internal.cs | 2 +- src/IKVM.Runtime/JVM.Properties.cs | 2 +- .../Java/Externs/ikvm/runtime/Util.cs | 9 +- .../Java/Externs/java/io/ObjectStreamClass.cs | 8 +- .../Java/Externs/java/lang/Package.cs | 2 +- .../java/lang/invoke/MethodHandleNatives.cs | 4 +- .../Java/Externs/java/lang/reflect/Array.cs | 4 +- .../Java/Externs/sun/misc/Unsafe.cs | 32 +- src/IKVM.Runtime/Java/Externs/sun/misc/VM.cs | 2 +- .../Externs/sun/reflect/ReflectionFactory.cs | 20 +- .../MethodHandleUtil.jniexport.cs | 12 +- src/IKVM.Runtime/ReflectUtil.cs | 4 +- .../RuntimeAssemblyClassLoader.cs | 26 +- .../RuntimeByteCodeJavaType.FinishContext.cs | 6 +- .../RuntimeByteCodeJavaType.JavaTypeImpl.cs | 28 +- src/IKVM.Runtime/RuntimeConstantJavaField.cs | 2 +- src/IKVM.Runtime/RuntimeJavaField.cs | 20 +- src/IKVM.Runtime/RuntimeJavaMethod.cs | 2 +- src/IKVM.Runtime/RuntimeJavaType.cs | 8 +- ...ntimeManagedByteCodeAccessStubJavaField.cs | 4 +- ...meManagedByteCodeJavaType.GhostJavaType.cs | 4 +- ...agedByteCodeJavaType.RemappedJavaMethod.cs | 2 +- .../RuntimeManagedByteCodeJavaType.cs | 16 +- ...RuntimeManagedByteCodePropertyJavaField.cs | 4 +- ...gedJavaType.AttributeAnnotationJavaType.cs | 10 +- ...RuntimeManagedJavaType.EnumEnumJavaType.cs | 4 +- ...ntimeManagedJavaType.EnumWrapJavaMethod.cs | 2 +- ...JavaType.ValueTypeDefaultCtorJavaMethod.cs | 2 +- src/IKVM.Runtime/RuntimeManagedJavaType.cs | 2 +- src/IKVM.Runtime/RuntimeSimpleJavaField.cs | 4 +- src/IKVM.Runtime/Serialization.cs | 8 +- src/IKVM.Runtime/SymbolExtensions.cs | 66 +- .../Invoke/NativeInvokerBytecodeGenerator.cs | 4 +- src/IKVM.Tools.Importer/ImportClassLoader.cs | 17 +- 132 files changed, 1662 insertions(+), 3248 deletions(-) delete mode 100644 src/IKVM.CoreLib/Symbols/Emit/ICustomAttributeBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Emit/ICustomAttributeProviderBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionCustomAttributeProviderBuilder.cs delete mode 100644 src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionCustomAttributeBuilder.cs create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionCustomAttributeProviderBuilder.cs delete mode 100644 src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionCustomAttributeBuilder.cs delete mode 100644 src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMemberSymbolBuilder.cs delete mode 100644 src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodBaseSymbolBuilder.cs diff --git a/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs b/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs index edf8cf48e..31e4ecaea 100644 --- a/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs +++ b/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs @@ -21,6 +21,38 @@ public class ReflectionSymbolTests class Foo { T? field; + } + + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] + class AttributeWithWithDefaultCtor : Attribute + { + + public AttributeWithWithDefaultCtor() + { + + } + + } + + [AttributeUsage(AttributeTargets.Class)] + class AttributeWithType : Attribute + { + + public AttributeWithType(Type type) + { + Type = type; + } + + public Type Type { get; } + + } + + [AttributeWithType(typeof(object))] + class ClassWithAttributeWithType + { + + + } [TestMethod] @@ -183,35 +215,44 @@ public void CanResolveParameters() p[1].ParameterType.Should().Be(c.GetOrCreateTypeSymbol(typeof(object))); } - [AttributeUsage(AttributeTargets.Class)] - class AttributeWithType : Attribute + [TestMethod] + public void CanReadCustomAttributes() { - - public AttributeWithType(Type type) - { - Type = type; - } - - public Type Type { get; } - + var c = new ReflectionSymbolContext(); + var s = c.GetOrCreateTypeSymbol(typeof(ClassWithAttributeWithType)); + var a = s.GetCustomAttribute(c.GetOrCreateTypeSymbol(typeof(AttributeWithType))); + var v = a.Value.ConstructorArguments[0].Value; + v.Should().BeOfType(); } - [AttributeWithType(typeof(object))] - class ClassWithAttributeWithType + [TestMethod] + public void CanReadCustomAttributesFromTypeBuilder() { + var c = new ReflectionSymbolContext(); + var a = c.DefineAssembly(new AssemblyIdentity("DynamicAssembly"), false, false); + var m = a.DefineModule("DynamicModule"); + var type = m.DefineType("DynamicType"); - - + type.SetCustomAttribute(CustomAttribute.Create(c.GetOrCreateTypeSymbol(typeof(AttributeWithWithDefaultCtor)).GetConstructors()[0], [])); + var ca = type.GetCustomAttribute(c.GetOrCreateTypeSymbol(typeof(AttributeWithWithDefaultCtor))); + ca.Should().NotBeNull(); } [TestMethod] - public void CanReadCustomAttributes() + public void CanReadCustomAttributesFromMethodBuilder() { var c = new ReflectionSymbolContext(); - var s = c.GetOrCreateTypeSymbol(typeof(ClassWithAttributeWithType)); - var a = s.GetCustomAttribute(c.GetOrCreateTypeSymbol(typeof(AttributeWithType))); - var v = a.Value.ConstructorArguments[0].Value; - v.Should().BeOfType(); + var a = c.DefineAssembly(new AssemblyIdentity("DynamicAssembly"), false, false); + var m = a.DefineModule("DynamicModule"); + var type = m.DefineType("DynamicType"); + + var method = type.DefineMethod("DynamicMethod1", System.Reflection.MethodAttributes.Public | System.Reflection.MethodAttributes.Static); + var il = method.GetILGenerator(); + il.Emit(OpCodes.Ret); + + method.SetCustomAttribute(CustomAttribute.Create(c.GetOrCreateTypeSymbol(typeof(AttributeWithWithDefaultCtor)).GetConstructors()[0], [])); + var ca = method.GetCustomAttribute(c.GetOrCreateTypeSymbol(typeof(AttributeWithWithDefaultCtor))); + ca.Should().NotBeNull(); } [TestMethod] diff --git a/src/IKVM.CoreLib/Reflection/ReflectionExtensions.cs b/src/IKVM.CoreLib/Reflection/ReflectionExtensions.cs index 7ce0795da..ee2c0b7b9 100644 --- a/src/IKVM.CoreLib/Reflection/ReflectionExtensions.cs +++ b/src/IKVM.CoreLib/Reflection/ReflectionExtensions.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq.Expressions; using System.Reflection; using System.Reflection.Emit; @@ -590,6 +591,80 @@ public static bool IsSZArray(this Type type) #endif } + /// + /// Implements GetcustomAttributeData with support for examining inheritence. + /// + /// + public static IEnumerable GetCustomAttributesData(this Type type, bool inherit) + { + foreach (var i in type.GetCustomAttributesData()) + yield return i; + + if (inherit) + for (var baseType = type.BaseType; baseType != null; baseType = baseType.BaseType) + foreach (var cad in baseType.GetCustomAttributesData()) + if (cad.AttributeType.GetCustomAttribute()?.Inherited ?? false) + yield return cad; + } + + /// + /// Implements GetcustomAttributeData with support for examining inheritence. + /// + /// + public static IEnumerable GetInheritedCustomAttributesData(this Type type) + { + for (var baseType = type.BaseType; baseType != null; baseType = baseType.BaseType) + foreach (var cad in baseType.GetCustomAttributesData()) + if (cad.AttributeType.GetCustomAttribute()?.Inherited ?? false) + yield return cad; + } + + /// + /// Implements GetcustomAttributeData with support for examining inheritence. + /// + /// + /// + public static IEnumerable GetCustomAttributesData(this MethodInfo method, bool inherit) + { + foreach (var i in method.GetCustomAttributesData()) + yield return i; + + if (inherit) + for (var baseMethod = method.GetBaseDefinition(); baseMethod != null; baseMethod = baseMethod.GetBaseDefinition()) + foreach (var cad in baseMethod.GetCustomAttributesData()) + if (cad.AttributeType.GetCustomAttribute()?.Inherited ?? false) + yield return cad; + } + + /// + /// Implements GetcustomAttributeData with support for examining inheritence. + /// + /// + /// + public static IEnumerable GetInheritedCustomAttributesData(this MethodInfo method) + { + for (var baseMethod = method.GetBaseDefinition(); baseMethod != null; baseMethod = baseMethod.GetBaseDefinition()) + foreach (var cad in baseMethod.GetCustomAttributesData()) + if (cad.AttributeType.GetCustomAttribute()?.Inherited ?? false) + yield return cad; + } + + /// + /// Implements GetcustomAttributeData with support for examining inheritence. + /// + /// + /// + public static IEnumerable GetCustomAttributesData(this MemberInfo member, bool inherit) + { + if (member is Type type) + return GetCustomAttributesData(type, inherit); + + if (member is MethodInfo method) + return GetCustomAttributesData(method, inherit); + + return member.GetCustomAttributesData(); + } + } } \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/CustomAttribute.cs b/src/IKVM.CoreLib/Symbols/CustomAttribute.cs index 7b1af0a9d..a910c5aa8 100644 --- a/src/IKVM.CoreLib/Symbols/CustomAttribute.cs +++ b/src/IKVM.CoreLib/Symbols/CustomAttribute.cs @@ -1,4 +1,6 @@ -using System.Collections.Immutable; +using System; +using System.Collections.Immutable; +using System.Linq; namespace IKVM.CoreLib.Symbols { @@ -7,7 +9,149 @@ readonly record struct CustomAttribute( ITypeSymbol AttributeType, IConstructorSymbol Constructor, ImmutableArray ConstructorArguments, - ImmutableArray NamedArguments); + ImmutableArray NamedArguments) + { + + /// + /// Initializes an instance of the interface given the constructor for the custom attribute and the arguments to the constructor. + /// + /// + /// + /// + public static CustomAttribute Create(IConstructorSymbol ctor, object?[] constructorArgs) + { + return new CustomAttribute( + ctor.DeclaringType ?? throw new InvalidOperationException(), + ctor, + PackTypedArgs(ctor.GetParameters().Select(i => i.ParameterType).ToArray(), constructorArgs), + ImmutableArray.Empty); + } + + /// + /// Initializes an instance of the interface given the constructor for the custom attribute, the arguments to the constructor, and a set of named field/value pairs. + /// + /// + /// + /// + /// + public static CustomAttribute Create(IConstructorSymbol ctor, object?[] constructorArgs, IFieldSymbol[] namedFields, object?[] fieldValues) + { + return new CustomAttribute( + ctor.DeclaringType ?? throw new InvalidOperationException(), + ctor, + PackTypedArgs(ctor.GetParameters().Select(i => i.ParameterType).ToArray(), constructorArgs), + PackNamedArgs([], [], namedFields, fieldValues)); + } + + /// + /// Initializes an instance of the interface given the constructor for the custom attribute, the arguments to the constructor, and a set of named property or value pairs. + /// + /// + /// + /// + /// + public static CustomAttribute Create(IConstructorSymbol ctor, object?[] constructorArgs, IPropertySymbol[] namedProperties, object?[] propertyValues) + { + return new CustomAttribute( + ctor.DeclaringType ?? throw new InvalidOperationException(), + ctor, + PackTypedArgs(ctor.GetParameters().Select(i => i.ParameterType).ToArray(), constructorArgs), + PackNamedArgs(namedProperties, propertyValues, [], [])); + } + + /// + /// Initializes an instance of the interface given the constructor for the custom attribute, the arguments to the constructor, a set of named property or value pairs, and a set of named field or value pairs. + /// + /// + /// + /// + /// + /// + /// + public static CustomAttribute Create(IConstructorSymbol ctor, object?[] constructorArgs, IPropertySymbol[] namedProperties, object?[] propertyValues, IFieldSymbol[] namedFields, object?[] fieldValues) + { + return new CustomAttribute( + ctor.DeclaringType ?? throw new InvalidOperationException(), + ctor, + PackTypedArgs(ctor.GetParameters().Select(i => i.ParameterType).ToArray(), constructorArgs), + PackNamedArgs(namedProperties, propertyValues, namedFields, fieldValues)); + } + + /// + /// Packs the types as typed arguments. + /// + /// + /// + /// + /// + /// + static ImmutableArray PackTypedArgs(ITypeSymbol[] types, object?[] values) + { + if (types is null) + throw new ArgumentNullException(nameof(types)); + if (values is null) + throw new ArgumentNullException(nameof(values)); + if (types.Length != values.Length) + throw new ArgumentException(); + + var a = ImmutableArray.CreateBuilder(types.Length); + for (int i = 0; i < types.Length; i++) + a.Add(PackTypedArg(types[i], values[i])); + + return a.ToImmutable(); + } + + /// + /// Packs the type as a typed argument. + /// + /// + /// + /// + static CustomAttributeTypedArgument PackTypedArg(ITypeSymbol type, object? value) + { + return new CustomAttributeTypedArgument(type, value); + } + + /// + /// Packages the members and args as a named argument. + /// + /// + /// + /// + static ImmutableArray PackNamedArgs(IPropertySymbol[] namedProperties, object?[] propertyValues, IFieldSymbol[] namedFields, object?[] fieldValues) + { + var a = ImmutableArray.CreateBuilder(namedProperties.Length + namedFields.Length); + for (int i = 0; i < namedProperties.Length; i++) + a.Add(PackNamedArg(namedProperties[i], propertyValues[i])); + for (int i = 0; i < namedFields.Length; i++) + a.Add(PackNamedArg(namedFields[i], fieldValues[i])); + + return a.ToImmutable(); + } + + /// + /// Packs the property and arg as a named argument. + /// + /// + /// + /// + static CustomAttributeNamedArgument PackNamedArg(IPropertySymbol property, object? v) + { + return new CustomAttributeNamedArgument(false, property, property.Name, PackTypedArg(property.PropertyType, v)); + } + + /// + /// Packs the field and arg as a named argument. + /// + /// + /// + /// + static CustomAttributeNamedArgument PackNamedArg(IFieldSymbol field, object? v) + { + return new CustomAttributeNamedArgument(false, field, field.Name, PackTypedArg(field.FieldType, v)); + } + + } } diff --git a/src/IKVM.CoreLib/Symbols/Emit/IAssemblySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IAssemblySymbolBuilder.cs index 8c9ab94ef..bda4b9a53 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/IAssemblySymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/IAssemblySymbolBuilder.cs @@ -3,7 +3,7 @@ namespace IKVM.CoreLib.Symbols.Emit { - interface IAssemblySymbolBuilder : ISymbolBuilder, IAssemblySymbol + interface IAssemblySymbolBuilder : ISymbolBuilder, IAssemblySymbol, ICustomAttributeProviderBuilder { /// @@ -30,19 +30,6 @@ interface IAssemblySymbolBuilder : ISymbolBuilder, IAssemblySym /// IModuleSymbolBuilder DefineModule(string name, string fileName, bool emitSymbolInfo); - /// - /// Set a custom attribute using a custom attribute builder. - /// - /// - void SetCustomAttribute(ICustomAttributeBuilder customBuilder); - - /// - /// Sets a custom attribute using a specified custom attribute blob. - /// - /// - /// - void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute); - /// /// Sets a Win32 icon on the generated assembly. /// diff --git a/src/IKVM.CoreLib/Symbols/Emit/ICustomAttributeBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/ICustomAttributeBuilder.cs deleted file mode 100644 index e30a02e21..000000000 --- a/src/IKVM.CoreLib/Symbols/Emit/ICustomAttributeBuilder.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace IKVM.CoreLib.Symbols.Emit -{ - - interface ICustomAttributeBuilder - { - - - - } - -} diff --git a/src/IKVM.CoreLib/Symbols/Emit/ICustomAttributeProviderBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/ICustomAttributeProviderBuilder.cs new file mode 100644 index 000000000..d07fbc431 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Emit/ICustomAttributeProviderBuilder.cs @@ -0,0 +1,15 @@ +namespace IKVM.CoreLib.Symbols.Emit +{ + + interface ICustomAttributeProviderBuilder + { + + /// + /// Set a custom attribute on this object. + /// + /// + public void SetCustomAttribute(CustomAttribute attribute); + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Emit/IEventSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IEventSymbolBuilder.cs index 36b725765..719f270b5 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/IEventSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/IEventSymbolBuilder.cs @@ -28,19 +28,6 @@ interface IEventSymbolBuilder : ISymbolBuilder, IMemberSymbolBuild /// void AddOtherMethod(IMethodSymbolBuilder mdBuilder); - /// - /// Set a custom attribute using a custom attribute builder. - /// - /// - void SetCustomAttribute(ICustomAttributeBuilder customBuilder); - - /// - /// Sets a custom attribute using a specified custom attribute blob. - /// - /// - /// - void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute); - } } \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/Emit/IFieldSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IFieldSymbolBuilder.cs index ad3048c16..9cd676798 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/IFieldSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/IFieldSymbolBuilder.cs @@ -16,19 +16,6 @@ interface IFieldSymbolBuilder : ISymbolBuilder, IMemberSymbolBuild /// void SetOffset(int iOffset); - /// - /// Set a custom attribute using a custom attribute builder. - /// - /// - void SetCustomAttribute(ICustomAttributeBuilder customBuilder); - - /// - /// Sets a custom attribute using a specified custom attribute blob. - /// - /// - /// - void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute); - } } diff --git a/src/IKVM.CoreLib/Symbols/Emit/IMemberSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IMemberSymbolBuilder.cs index b787c9ced..a2d87e08e 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/IMemberSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/IMemberSymbolBuilder.cs @@ -1,7 +1,7 @@ namespace IKVM.CoreLib.Symbols.Emit { - interface IMemberSymbolBuilder : ISymbolBuilder, IMemberSymbol + interface IMemberSymbolBuilder : ISymbolBuilder, IMemberSymbol, ICustomAttributeProviderBuilder { diff --git a/src/IKVM.CoreLib/Symbols/Emit/IMethodBaseSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IMethodBaseSymbolBuilder.cs index c3173daf1..162146f11 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/IMethodBaseSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/IMethodBaseSymbolBuilder.cs @@ -34,19 +34,6 @@ interface IMethodBaseSymbolBuilder : ISymbolBuilder, IMemberS /// IILGenerator GetILGenerator(); - /// - /// Set a custom attribute using a custom attribute builder. - /// - /// - void SetCustomAttribute(ICustomAttributeBuilder customBuilder); - - /// - /// Sets a custom attribute using a specified custom attribute blob. - /// - /// - /// - void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute); - } } \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/Emit/IModuleSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IModuleSymbolBuilder.cs index 1ad74cf09..efdd7a7ad 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/IModuleSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/IModuleSymbolBuilder.cs @@ -9,7 +9,7 @@ namespace IKVM.CoreLib.Symbols.Emit { - interface IModuleSymbolBuilder : ISymbolBuilder, IModuleSymbol + interface IModuleSymbolBuilder : ISymbolBuilder, IModuleSymbol, ICustomAttributeProviderBuilder { /// @@ -163,19 +163,6 @@ interface IModuleSymbolBuilder : ISymbolBuilder, IModuleSymbol /// ITypeSymbolBuilder DefineType(string name, TypeAttributes attr, ITypeSymbol? parent, ITypeSymbol[]? interfaces); - /// - /// Set a custom attribute using a custom attribute builder. - /// - /// - void SetCustomAttribute(ICustomAttributeBuilder customBuilder); - - /// - /// Sets a custom attribute using a specified custom attribute blob. - /// - /// - /// - void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute); - /// /// Explicitely adds a reference to the specified assembly. /// diff --git a/src/IKVM.CoreLib/Symbols/Emit/IParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IParameterSymbolBuilder.cs index 860f872f7..ec2148e7b 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/IParameterSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/IParameterSymbolBuilder.cs @@ -1,27 +1,15 @@ namespace IKVM.CoreLib.Symbols.Emit { - interface IParameterSymbolBuilder : ISymbolBuilder, IParameterSymbol + interface IParameterSymbolBuilder : ISymbolBuilder, IParameterSymbol, ICustomAttributeProviderBuilder { + /// /// Sets the default value of the parameter. /// /// void SetConstant(object? defaultValue); - /// - /// Set a custom attribute using a custom attribute builder. - /// - /// - void SetCustomAttribute(ICustomAttributeBuilder customBuilder); - - /// - /// Sets a custom attribute using a specified custom attribute blob. - /// - /// - /// - void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute); - } } \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/Emit/IPropertySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IPropertySymbolBuilder.cs index c1f200f2f..29dd90ed4 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/IPropertySymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/IPropertySymbolBuilder.cs @@ -28,19 +28,6 @@ interface IPropertySymbolBuilder : ISymbolBuilder, IMemberSymbo /// void AddOtherMethod(IMethodSymbolBuilder mdBuilder); - /// - /// Set a custom attribute using a custom attribute builder. - /// - /// - void SetCustomAttribute(ICustomAttributeBuilder customBuilder); - - /// - /// Sets a custom attribute using a specified custom attribute blob. - /// - /// - /// - void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute); - } } \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/Emit/ITypeSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/ITypeSymbolBuilder.cs index 1afc22d77..dfa306cf8 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/ITypeSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/ITypeSymbolBuilder.cs @@ -318,19 +318,6 @@ interface ITypeSymbolBuilder : ISymbolBuilder, IMemberSymbolBuilder /// IPropertySymbolBuilder DefineProperty(string name, PropertyAttributes attributes, CallingConventions callingConvention, ITypeSymbol returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers); - /// - /// Set a custom attribute using a custom attribute builder. - /// - /// - void SetCustomAttribute(ICustomAttributeBuilder customBuilder); - - /// - /// Sets a custom attribute using a specified custom attribute blob. - /// - /// - /// - void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute); - /// /// Finishes the type, updating the associated symbol. /// diff --git a/src/IKVM.CoreLib/Symbols/ICustomAttributeProvider.cs b/src/IKVM.CoreLib/Symbols/ICustomAttributeProvider.cs index 447839f6a..a8747edc4 100644 --- a/src/IKVM.CoreLib/Symbols/ICustomAttributeProvider.cs +++ b/src/IKVM.CoreLib/Symbols/ICustomAttributeProvider.cs @@ -4,7 +4,7 @@ /// /// Provides custom attributes for reflection objects that support them. /// - interface ICustomAttributeProvider + interface ICustomAttributeProvider : ISymbol { /// diff --git a/src/IKVM.CoreLib/Symbols/ISymbolContext.cs b/src/IKVM.CoreLib/Symbols/ISymbolContext.cs index f014a0a5b..776a0d862 100644 --- a/src/IKVM.CoreLib/Symbols/ISymbolContext.cs +++ b/src/IKVM.CoreLib/Symbols/ISymbolContext.cs @@ -1,5 +1,4 @@ -using System.Reflection; -using System.Reflection.Emit; +using System.Collections.Immutable; using IKVM.CoreLib.Symbols.Emit; @@ -22,49 +21,11 @@ interface ISymbolContext /// Defines a dynamic assembly that has the specified name and access rights. /// /// - /// + /// /// /// /// - IAssemblySymbolBuilder DefineAssembly(AssemblyIdentity name, ICustomAttributeBuilder[]? assemblyAttributes, bool collectable = true, bool saveable = false); - - /// - /// Initializes an instance of the interface given the constructor for the custom attribute and the arguments to the constructor. - /// - /// - /// - /// - ICustomAttributeBuilder CreateCustomAttribute(IConstructorSymbol con, object?[] constructorArgs); - - /// - /// Initializes an instance of the interface given the constructor for the custom attribute, the arguments to the constructor, and a set of named field/value pairs. - /// - /// - /// - /// - /// - ICustomAttributeBuilder CreateCustomAttribute(IConstructorSymbol con, object?[] constructorArgs, IFieldSymbol[] namedFields, object?[] fieldValues); - - /// - /// Initializes an instance of the interface given the constructor for the custom attribute, the arguments to the constructor, and a set of named property or value pairs. - /// - /// - /// - /// - /// - ICustomAttributeBuilder CreateCustomAttribute(IConstructorSymbol con, object?[] constructorArgs, IPropertySymbol[] namedProperties, object?[] propertyValues); - - /// - /// Initializes an instance of the interface given the constructor for the custom attribute, the arguments to the constructor, a set of named property or value pairs, and a set of named field or value pairs. - /// - /// - /// - /// - /// - /// - /// - ICustomAttributeBuilder CreateCustomAttribute(IConstructorSymbol con, object?[] constructorArgs, IPropertySymbol[] namedProperties, object?[] propertyValues, IFieldSymbol[] namedFields, object?[] fieldValues); - + IAssemblySymbolBuilder DefineAssembly(AssemblyIdentity name, ImmutableArray attributes, bool collectable = true, bool saveable = false); } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionCustomAttributeProviderBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionCustomAttributeProviderBuilder.cs new file mode 100644 index 000000000..e4fd3ea67 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionCustomAttributeProviderBuilder.cs @@ -0,0 +1,13 @@ +using IKVM.CoreLib.Symbols.Emit; + +namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit +{ + + interface IIkvmReflectionCustomAttributeProviderBuilder : ICustomAttributeProviderBuilder + { + + + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionMemberSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionMemberSymbolBuilder.cs index 3008c8e06..f7b637f27 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionMemberSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IIkvmReflectionMemberSymbolBuilder.cs @@ -1,10 +1,9 @@ using IKVM.CoreLib.Symbols.Emit; -using IKVM.Reflection.Emit; namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit { - interface IIkvmReflectionMemberSymbolBuilder : IIkvmReflectionSymbolBuilder, IMemberSymbolBuilder, IIkvmReflectionMemberSymbol + interface IIkvmReflectionMemberSymbolBuilder : IIkvmReflectionSymbolBuilder, IMemberSymbolBuilder, IIkvmReflectionMemberSymbol, IIkvmReflectionCustomAttributeProviderBuilder { /// diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionAssemblySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionAssemblySymbolBuilder.cs index 13cc31043..8f245c446 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionAssemblySymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionAssemblySymbolBuilder.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.IO; -using System.Linq; using IKVM.CoreLib.Symbols.Emit; using IKVM.Reflection; @@ -76,15 +75,9 @@ public IModuleSymbolBuilder DefineModule(string name, string fileName, bool emit } /// - public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) + public void SetCustomAttribute(CustomAttribute attribute) { - UnderlyingAssemblyBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); - } - - /// - public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) - { - UnderlyingAssemblyBuilder.SetCustomAttribute(((IkvmReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); + UnderlyingAssemblyBuilder.SetCustomAttribute(attribute.Unpack()); } /// diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionConstructorSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionConstructorSymbolBuilder.cs index 8c776fbff..0ab2e7673 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionConstructorSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionConstructorSymbolBuilder.cs @@ -68,16 +68,14 @@ public override IILGenerator GetILGenerator(int streamSize) return _il ??= new IkvmReflectionILGenerator(Context, UnderlyingConstructorBuilder.GetILGenerator(streamSize)); } - /// - public override void SetCustomAttribute(ICustomAttributeBuilder customBuilder) - { - UnderlyingConstructorBuilder.SetCustomAttribute(((IkvmReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); - } + #endregion + + #region ICustomAttributeProviderBuilder /// - public override void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) + public override void SetCustomAttribute(CustomAttribute attribute) { - UnderlyingConstructorBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); + UnderlyingConstructorBuilder.SetCustomAttribute(attribute.Unpack()); } #endregion diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionCustomAttributeBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionCustomAttributeBuilder.cs deleted file mode 100644 index 3e9abec0f..000000000 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionCustomAttributeBuilder.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; - -using IKVM.CoreLib.Symbols.Emit; -using IKVM.Reflection.Emit; - -namespace IKVM.CoreLib.Symbols.IkvmReflection.Emit -{ - - class IkvmReflectionCustomAttributeBuilder : ICustomAttributeBuilder - { - - readonly CustomAttributeBuilder _builder; - - /// - /// Initializes a new instance. - /// - public IkvmReflectionCustomAttributeBuilder(CustomAttributeBuilder builder) - { - _builder = builder ?? throw new ArgumentNullException(nameof(builder)); - } - - /// - /// Gets the underlying reflection . - /// - internal CustomAttributeBuilder UnderlyingBuilder => _builder; - - } - -} diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionEventSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionEventSymbolBuilder.cs index 4f388a3b2..45a4169e4 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionEventSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionEventSymbolBuilder.cs @@ -63,16 +63,14 @@ public void AddOtherMethod(IMethodSymbolBuilder mdBuilder) UnderlyingEventBuilder.AddOtherMethod(((IIkvmReflectionMethodSymbolBuilder)mdBuilder).UnderlyingMethodBuilder); } - /// - public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) - { - UnderlyingEventBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); - } + #endregion + + #region ICustomAttributeProviderBuilder /// - public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) + public override void SetCustomAttribute(CustomAttribute attribute) { - UnderlyingEventBuilder.SetCustomAttribute(((IkvmReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); + UnderlyingEventBuilder.SetCustomAttribute(attribute.Unpack()); } #endregion diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionFieldSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionFieldSymbolBuilder.cs index 847249780..cb4971589 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionFieldSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionFieldSymbolBuilder.cs @@ -51,18 +51,6 @@ public void SetOffset(int iOffset) UnderlyingFieldBuilder.SetOffset(iOffset); } - /// - public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) - { - UnderlyingFieldBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); - } - - /// - public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) - { - UnderlyingFieldBuilder.SetCustomAttribute(((IkvmReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); - } - #endregion #region IFieldSymbol @@ -132,6 +120,16 @@ public ITypeSymbol[] GetRequiredCustomModifiers() #endregion + #region ICustomAttributeProviderBuilder + + /// + public override void SetCustomAttribute(CustomAttribute attribute) + { + UnderlyingFieldBuilder.SetCustomAttribute(attribute.Unpack()); + } + + #endregion + /// public override void OnComplete() { diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionGenericTypeParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionGenericTypeParameterSymbolBuilder.cs index 3e455d9d8..ad8e18c99 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionGenericTypeParameterSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionGenericTypeParameterSymbolBuilder.cs @@ -1,5 +1,6 @@ using System; +using IKVM.CoreLib.Symbols.Emit; using IKVM.Reflection; using IKVM.Reflection.Emit; @@ -696,6 +697,16 @@ public ITypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments) #endregion + #region ICustomAttributeProviderBuilder + + /// + public override void SetCustomAttribute(CustomAttribute attribute) + { + UnderlyingGenericTypeParameterBuilder.SetCustomAttribute(attribute.Unpack()); + } + + #endregion + /// public override void OnComplete() { diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMemberSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMemberSymbolBuilder.cs index b174dd069..693bdb19e 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMemberSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMemberSymbolBuilder.cs @@ -2,6 +2,7 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; +using IKVM.CoreLib.Symbols.Emit; using IKVM.Reflection; using IKVM.Reflection.Emit; @@ -335,6 +336,13 @@ public virtual bool IsDefined(ITypeSymbol attributeType, bool inherit = false) #endregion + #region ICustomAttributeProviderBuilder + + /// + public abstract void SetCustomAttribute(CustomAttribute attribute); + + #endregion + /// public virtual void OnComplete() { @@ -343,7 +351,6 @@ public virtual void OnComplete() /// public override string ToString() => UnderlyingMember.ToString()!; - } } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodBaseSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodBaseSymbolBuilder.cs index 60499625a..9770fd84f 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodBaseSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodBaseSymbolBuilder.cs @@ -52,12 +52,6 @@ public IIkvmReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo p /// public abstract IILGenerator GetILGenerator(int streamSize); - /// - public abstract void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute); - - /// - public abstract void SetCustomAttribute(ICustomAttributeBuilder customBuilder); - /// public IIkvmReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter) { diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodSymbolBuilder.cs index 2b5270b6d..e486d31cc 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionMethodSymbolBuilder.cs @@ -106,18 +106,6 @@ public override IILGenerator GetILGenerator(int streamSize) return _il ??= new IkvmReflectionILGenerator(Context, UnderlyingMethodBuilder.GetILGenerator(streamSize)); } - /// - public override void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) - { - UnderlyingMethodBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); - } - - /// - public override void SetCustomAttribute(ICustomAttributeBuilder customBuilder) - { - UnderlyingMethodBuilder.SetCustomAttribute(((IkvmReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); - } - #endregion #region IMethodSymbolBuilder @@ -186,6 +174,16 @@ public IMethodSymbol MakeGenericMethod(params ITypeSymbol[] typeArguments) #endregion + #region ICustomAttributeProviderBuilder + + /// + public override void SetCustomAttribute(CustomAttribute attribute) + { + UnderlyingMethodBuilder.SetCustomAttribute(attribute.Unpack()); + } + + #endregion + /// public override void OnComplete() { diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionModuleSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionModuleSymbolBuilder.cs index a1ee9f91d..273dfcd75 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionModuleSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionModuleSymbolBuilder.cs @@ -284,15 +284,9 @@ public ITypeSymbolBuilder DefineType(string name, System.Reflection.TypeAttribut } /// - public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) + public void SetCustomAttribute(CustomAttribute attribute) { - UnderlyingModuleBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); - } - - /// - public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) - { - UnderlyingModuleBuilder.SetCustomAttribute(((IkvmReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); + UnderlyingModuleBuilder.SetCustomAttribute(attribute.Unpack()); } /// diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterSymbolBuilder.cs index f0e7aed50..648ac97c3 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionParameterSymbolBuilder.cs @@ -56,15 +56,9 @@ public void SetConstant(object? defaultValue) } /// - public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) + public void SetCustomAttribute(CustomAttribute attribute) { - UnderlyingParameterBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); - } - - /// - public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) - { - UnderlyingParameterBuilder.SetCustomAttribute(((IkvmReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); + UnderlyingParameterBuilder.SetCustomAttribute(attribute.Unpack()); } #endregion diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionPropertySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionPropertySymbolBuilder.cs index f4416773b..6b71a089d 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionPropertySymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionPropertySymbolBuilder.cs @@ -86,16 +86,14 @@ public void AddOtherMethod(IMethodSymbolBuilder mdBuilder) UnderlyingPropertyBuilder.AddOtherMethod(((IIkvmReflectionMethodSymbolBuilder)mdBuilder).UnderlyingMethodBuilder); } - /// - public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) - { - UnderlyingPropertyBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); - } + #endregion + + #region ICustomAttributeProviderBuilder /// - public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) + public override void SetCustomAttribute(CustomAttribute attribute) { - UnderlyingPropertyBuilder.SetCustomAttribute(((IkvmReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); + UnderlyingPropertyBuilder.SetCustomAttribute(attribute.Unpack()); } #endregion diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionTypeSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionTypeSymbolBuilder.cs index babaa086a..376f463cc 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionTypeSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionTypeSymbolBuilder.cs @@ -378,17 +378,6 @@ public IConstructorSymbolBuilder DefineTypeInitializer() { return (IConstructorSymbolBuilder)ResolveConstructorSymbol(UnderlyingTypeBuilder.DefineTypeInitializer()); } - /// - public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) - { - UnderlyingTypeBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); - } - - /// - public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) - { - UnderlyingTypeBuilder.SetCustomAttribute(((IkvmReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); - } #endregion @@ -945,6 +934,16 @@ public ITypeSymbol MakeByRefType() #endregion + #region ICustomAttributeProviderBuilder + + /// + public override void SetCustomAttribute(CustomAttribute attribute) + { + UnderlyingTypeBuilder.SetCustomAttribute(attribute.Unpack()); + } + + #endregion + /// public void Complete() { diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolContext.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolContext.cs index a3e8d19a5..c97a3b836 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolContext.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolContext.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Concurrent; +using System.Collections.Immutable; using System.Runtime.CompilerServices; using IKVM.CoreLib.Symbols.Emit; @@ -46,7 +47,7 @@ public IAssemblySymbolBuilder DefineAssembly(AssemblyIdentity name, bool collect } /// - public IAssemblySymbolBuilder DefineAssembly(AssemblyIdentity name, ICustomAttributeBuilder[]? assemblyAttributes, bool collectable, bool saveable) + public IAssemblySymbolBuilder DefineAssembly(AssemblyIdentity name, ImmutableArray attributes, bool collectable, bool saveable) { if (name is null) throw new ArgumentNullException(nameof(name)); @@ -55,7 +56,7 @@ public IAssemblySymbolBuilder DefineAssembly(AssemblyIdentity name, ICustomAttri if (saveable == false) throw new NotSupportedException("IKVM Reflection can only produce saveable assemblies."); - return GetOrCreateAssemblySymbol(_universe.DefineDynamicAssembly(name.Unpack(), AssemblyBuilderAccess.Save, assemblyAttributes?.Unpack())); + return GetOrCreateAssemblySymbol(_universe.DefineDynamicAssembly(name.Unpack(), AssemblyBuilderAccess.Save, attributes.Unpack())); } /// @@ -332,30 +333,6 @@ public IIkvmReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypePa return GetOrCreateModuleSymbol((ModuleBuilder)genericTypeParameter.Module).GetOrCreateGenericTypeParameterSymbol(genericTypeParameter); } - /// - public ICustomAttributeBuilder CreateCustomAttribute(IConstructorSymbol con, object?[] constructorArgs) - { - return new IkvmReflectionCustomAttributeBuilder(new CustomAttributeBuilder(con.Unpack(), UnpackArguments(constructorArgs))); - } - - /// - public ICustomAttributeBuilder CreateCustomAttribute(IConstructorSymbol con, object?[] constructorArgs, IFieldSymbol[] namedFields, object?[] fieldValues) - { - return new IkvmReflectionCustomAttributeBuilder(new CustomAttributeBuilder(con.Unpack(), UnpackArguments(constructorArgs), namedFields.Unpack(), UnpackArguments(fieldValues))); - } - - /// - public ICustomAttributeBuilder CreateCustomAttribute(IConstructorSymbol con, object?[] constructorArgs, IPropertySymbol[] namedProperties, object?[] propertyValues) - { - return new IkvmReflectionCustomAttributeBuilder(new CustomAttributeBuilder(con.Unpack(), UnpackArguments(constructorArgs), namedProperties.Unpack(), UnpackArguments(propertyValues))); - } - - /// - public ICustomAttributeBuilder CreateCustomAttribute(IConstructorSymbol con, object?[] constructorArgs, IPropertySymbol[] namedProperties, object?[] propertyValues, IFieldSymbol[] namedFields, object?[] fieldValues) - { - return new IkvmReflectionCustomAttributeBuilder(new CustomAttributeBuilder(con.Unpack(), UnpackArguments(constructorArgs), namedProperties.Unpack(), UnpackArguments(propertyValues), namedFields.Unpack(), UnpackArguments(fieldValues))); - } - /// /// Unpacks a single constructor argument. /// diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeTable.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeTable.cs index 706ffe012..dfc0291da 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeTable.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeTable.cs @@ -23,7 +23,7 @@ struct IkvmReflectionTypeTable IndexRangeDictionary _table = new(); ReaderWriterLockSlim? _lock; - ConcurrentDictionary _byName; + ConcurrentDictionary? _byName; ConcurrentDictionary? _byToken; /// diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionUtil.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionUtil.cs index 600292ba8..2dddc4c98 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionUtil.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionUtil.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; @@ -397,28 +398,112 @@ public static Label[] Unpack(this ILabel[] labels) } /// - /// Unpacks the . + /// Unpacks the . /// - /// + /// /// - public static CustomAttributeBuilder Unpack(this ICustomAttributeBuilder customAttributes) + public static CustomAttributeBuilder Unpack(this CustomAttribute attributes) { - return ((IkvmReflectionCustomAttributeBuilder)customAttributes).UnderlyingBuilder; + // unpack constructor arg values + var constructorValues = new object?[attributes.ConstructorArguments.Length]; + for (int i = 0; i < attributes.ConstructorArguments.Length; i++) + constructorValues[i] = UnpackCustomAttributeValue(attributes.ConstructorArguments[i]); + + // unpack named arguments into sets of properties and fields + List? namedProperties = null; + List? propertyValues = null; + List? namedFields = null; + List? fieldValues = null; + + // split named arguments into two sets + foreach (var i in attributes.NamedArguments) + { + var v = UnpackCustomAttributeValue(i.TypedValue.Value); + if (i.IsField == false) + { + namedProperties ??= new(); + namedProperties.Add(((IPropertySymbol)i.MemberInfo).Unpack()); + propertyValues ??= new(); + propertyValues.Add(v); + } + else + { + namedFields ??= new(); + namedFields.Add(((IFieldSymbol)i.MemberInfo).Unpack()); + fieldValues ??= new(); + fieldValues.Add(v); + } + } + + return new CustomAttributeBuilder( + attributes.Constructor.Unpack(), + constructorValues, + namedProperties?.ToArray() ?? [], + propertyValues?.ToArray() ?? [], + namedFields?.ToArray() ?? [], + fieldValues?.ToArray() ?? []); } /// - /// Unpacks the s. + /// Unpacks the s. /// - /// + /// /// - public static CustomAttributeBuilder[] Unpack(this ICustomAttributeBuilder[] customAttributes) + public static CustomAttributeBuilder[] Unpack(this CustomAttribute[] attributes) { - if (customAttributes.Length == 0) + if (attributes.Length == 0) return []; - var a = new CustomAttributeBuilder[customAttributes.Length]; - for (int i = 0; i < customAttributes.Length; i++) - a[i] = customAttributes[i].Unpack(); + var a = new CustomAttributeBuilder[attributes.Length]; + for (int i = 0; i < attributes.Length; i++) + a[i] = attributes[i].Unpack(); + + return a; + } + + /// + /// Unpacks the s. + /// + /// + /// + public static CustomAttributeBuilder[] Unpack(this ImmutableArray attributes) + { + if (attributes.Length == 0) + return []; + + var a = new CustomAttributeBuilder[attributes.Length]; + for (int i = 0; i < attributes.Length; i++) + a[i] = attributes[i].Unpack(); + + return a; + } + + /// + /// Unpacks the attribute value object. + /// + /// + /// + static object? UnpackCustomAttributeValue(object? value) + { + return value switch + { + IReadOnlyList l => UnpackCustomAttributeArrayValue(l), + ITypeSymbol t => t.Unpack(), + CustomAttributeTypedArgument a => UnpackCustomAttributeValue(a.Value), + _ => value, + }; + } + + /// + /// Unpacks the attribute value array. + /// + /// + /// + static object?[] UnpackCustomAttributeArrayValue(IReadOnlyList l) + { + var a = new object?[l.Count]; + for (int i = 0; i < l.Count; i++) + a[i] = UnpackCustomAttributeValue(l[i]); return a; } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionCustomAttributeProviderBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionCustomAttributeProviderBuilder.cs new file mode 100644 index 000000000..8f78217a9 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionCustomAttributeProviderBuilder.cs @@ -0,0 +1,13 @@ +using IKVM.CoreLib.Symbols.Emit; + +namespace IKVM.CoreLib.Symbols.Reflection.Emit +{ + + interface IReflectionCustomAttributeProviderBuilder : ICustomAttributeProviderBuilder + { + + + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionGenericTypeParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionGenericTypeParameterSymbolBuilder.cs index c02f275dd..8e5789c04 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionGenericTypeParameterSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionGenericTypeParameterSymbolBuilder.cs @@ -1,4 +1,5 @@ -using System.Reflection.Emit; +using System; +using System.Reflection.Emit; using IKVM.CoreLib.Symbols.Emit; @@ -14,9 +15,9 @@ interface IReflectionGenericTypeParameterSymbolBuilder : IReflectionSymbolBuilde GenericTypeParameterBuilder UnderlyingGenericTypeParameterBuilder { get; } /// - /// Invoked when the type containing this generic type parameter is completed. + /// Invoked when the type containing this generic type parameter is completed. Passed the completed type. /// - void OnComplete(); + void OnComplete(Type type); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionMethodBaseSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionMethodBaseSymbolBuilder.cs index bdc1c996f..cf15d47d4 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionMethodBaseSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionMethodBaseSymbolBuilder.cs @@ -1,6 +1,4 @@ -using System.Reflection.Emit; - -using IKVM.CoreLib.Symbols.Emit; +using IKVM.CoreLib.Symbols.Emit; namespace IKVM.CoreLib.Symbols.Reflection.Emit { @@ -8,12 +6,7 @@ namespace IKVM.CoreLib.Symbols.Reflection.Emit interface IReflectionMethodBaseSymbolBuilder : IReflectionSymbolBuilder, IReflectionMemberSymbolBuilder, IMethodBaseSymbolBuilder, IReflectionMethodBaseSymbol { - /// - /// Gets or creates a for the given . - /// - /// - /// - public IReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter); + } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionMethodSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionMethodSymbolBuilder.cs index 76cbe97c5..87d35faeb 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionMethodSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionMethodSymbolBuilder.cs @@ -13,13 +13,6 @@ interface IReflectionMethodSymbolBuilder : IReflectionSymbolBuilder, IReflection /// MethodBuilder UnderlyingMethodBuilder { get; } - /// - /// Gets or creates a for the given . - /// - /// - /// - IReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeParameterSymbol(GenericTypeParameterBuilder genericTypeParameter); - } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionModuleSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionModuleSymbolBuilder.cs index 695568f4f..8affb7ef2 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionModuleSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionModuleSymbolBuilder.cs @@ -13,63 +13,6 @@ interface IReflectionModuleSymbolBuilder : IReflectionSymbolBuilder, IModuleSymb /// ModuleBuilder UnderlyingModuleBuilder { get; } - /// - /// Gets or creates a for the specified . - /// - /// - /// - IReflectionTypeSymbolBuilder GetOrCreateTypeSymbol(TypeBuilder type); - - /// - /// Gets or creates a for the specified . - /// - /// - /// - IReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor); - - /// - /// Gets or creates a for the specified . - /// - /// - /// - IReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method); - - /// - /// Gets or creates a for the specified . - /// - /// - /// - IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field); - - /// - /// Gets or creates a for the specified . - /// - /// - /// - IReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property); - - /// - /// Gets or creates a for the specified . - /// - /// - /// - IReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event); - - /// - /// Gets or creates a for the specified . - /// - /// - /// - /// - IReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(IReflectionMemberSymbolBuilder member, ParameterBuilder parameter); - - /// - /// Gets or creates a for the specified . - /// - /// - /// - IReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeParameterSymbol(GenericTypeParameterBuilder genericTypeParameter); - } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionPropertySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionPropertySymbolBuilder.cs index c010b0196..6028d6de6 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionPropertySymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionPropertySymbolBuilder.cs @@ -13,13 +13,6 @@ interface IReflectionPropertySymbolBuilder : IReflectionSymbolBuilder, IReflecti /// PropertyBuilder UnderlyingPropertyBuilder { get; } - /// - /// Gets or creates a for the given . - /// - /// - /// - public IReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter); - } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionSymbolBuilder.cs index b7795a7d3..1f88cf8c8 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionSymbolBuilder.cs @@ -9,78 +9,6 @@ namespace IKVM.CoreLib.Symbols.Reflection.Emit interface IReflectionSymbolBuilder : ISymbolBuilder { - /// - /// Resolves the symbol for the specified assembly builder. - /// - /// - /// - [return: NotNullIfNotNull(nameof(assembly))] - IReflectionAssemblySymbolBuilder ResolveAssemblySymbol(AssemblyBuilder assembly); - - /// - /// Resolves the symbol for the specified module. - /// - /// - /// - [return: NotNullIfNotNull(nameof(module))] - IReflectionModuleSymbolBuilder ResolveModuleSymbol(ModuleBuilder module); - - /// - /// Resolves the symbol for the specified type. - /// - /// - /// - [return: NotNullIfNotNull(nameof(type))] - IReflectionTypeSymbolBuilder ResolveTypeSymbol(TypeBuilder type); - - /// - /// Resolves the symbol for the specified constructor. - /// - /// - /// - [return: NotNullIfNotNull(nameof(ctor))] - IReflectionConstructorSymbolBuilder ResolveConstructorSymbol(ConstructorBuilder ctor); - - /// - /// Resolves the symbol for the specified method. - /// - /// - /// - [return: NotNullIfNotNull(nameof(method))] - IReflectionMethodSymbolBuilder ResolveMethodSymbol(MethodBuilder method); - - /// - /// Resolves the symbol for the specified field. - /// - /// - /// - [return: NotNullIfNotNull(nameof(field))] - IReflectionFieldSymbolBuilder ResolveFieldSymbol(FieldBuilder field); - - /// - /// Resolves the symbol for the specified property. - /// - /// - /// - [return: NotNullIfNotNull(nameof(property))] - IReflectionPropertySymbolBuilder ResolvePropertySymbol(PropertyBuilder property); - - /// - /// Resolves the symbol for the specified event. - /// - /// - /// - [return: NotNullIfNotNull(nameof(@event))] - IReflectionEventSymbolBuilder ResolveEventSymbol(EventBuilder @event); - - /// - /// Resolves the symbol for the specified generic type parameter. - /// - /// - /// - [return: NotNullIfNotNull(nameof(genericTypeParameter))] - IReflectionGenericTypeParameterSymbolBuilder? ResolveGenericTypeParameterSymbol(GenericTypeParameterBuilder genericTypeParameter); - } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionTypeSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionTypeSymbolBuilder.cs index d5ed37b22..835835b8e 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionTypeSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/IReflectionTypeSymbolBuilder.cs @@ -13,48 +13,6 @@ interface IReflectionTypeSymbolBuilder : IReflectionMemberSymbolBuilder, ITypeSy /// TypeBuilder UnderlyingTypeBuilder { get; } - /// - /// Gets or creates a for the given . - /// - /// - /// - IReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor); - - /// - /// Gets or creates a for the given . - /// - /// - /// - IReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method); - - /// - /// Gets or creates a for the given . - /// - /// - /// - IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field); - - /// - /// Gets or creates a for the given . - /// - /// - /// - IReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property); - - /// - /// Gets or creates a for the given . - /// - /// - /// - IReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event); - - /// - /// Gets or creates a for the given . - /// - /// - /// - IReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeParameterSymbol(GenericTypeParameterBuilder genericTypeParameter); - } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs index eae10821b..7588f2e38 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionAssemblySymbolBuilder.cs @@ -1,7 +1,4 @@ using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; using System.Reflection; using System.Reflection.Emit; @@ -10,12 +7,11 @@ namespace IKVM.CoreLib.Symbols.Reflection.Emit { - class ReflectionAssemblySymbolBuilder : ReflectionSymbolBuilder, IReflectionAssemblySymbolBuilder + class ReflectionAssemblySymbolBuilder : ReflectionAssemblySymbol, IReflectionAssemblySymbolBuilder { readonly AssemblyBuilder _builder; - - ReflectionModuleTable _moduleTable; + Assembly? _assembly; /// /// Initializes a new instance. @@ -23,34 +19,23 @@ class ReflectionAssemblySymbolBuilder : ReflectionSymbolBuilder, IReflectionAsse /// /// public ReflectionAssemblySymbolBuilder(ReflectionSymbolContext context, AssemblyBuilder builder) : - base(context) + base(context, builder) { _builder = builder ?? throw new ArgumentNullException(nameof(builder)); - _moduleTable = new ReflectionModuleTable(context, this); } /// - public Assembly UnderlyingAssembly => UnderlyingAssemblyBuilder; + public AssemblyBuilder UnderlyingAssemblyBuilder => _builder; /// - public AssemblyBuilder UnderlyingAssemblyBuilder => _builder; + public override Assembly UnderlyingRuntimeAssembly => _assembly ?? throw new InvalidOperationException(); #region IReflectionAssemblySymbolBuilder /// public IReflectionModuleSymbolBuilder GetOrCreateModuleSymbol(ModuleBuilder module) { - return _moduleTable.GetOrCreateModuleSymbol(module); - } - - #endregion - - #region IReflectionAssemblySymbol - - /// - public IReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) - { - return _moduleTable.GetOrCreateModuleSymbol(module); + return (IReflectionModuleSymbolBuilder)base.GetOrCreateModuleSymbol(module); } #endregion @@ -90,15 +75,9 @@ public IModuleSymbolBuilder DefineModule(string name, string fileName, bool emit } /// - public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) + public void SetCustomAttribute(CustomAttribute attribute) { - UnderlyingAssemblyBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); - } - - /// - public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) - { - UnderlyingAssemblyBuilder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); + UnderlyingAssemblyBuilder.SetCustomAttribute(attribute.Unpack()); } /// @@ -160,7 +139,7 @@ public void AddResourceFile(string name, string fileName) } /// - public void Save(string assemblyFileName, System.Reflection.PortableExecutableKinds portableExecutableKind, IKVM.CoreLib.Symbols.ImageFileMachine imageFileMachine) + public void Save(string assemblyFileName, PortableExecutableKinds portableExecutableKind, IKVM.CoreLib.Symbols.ImageFileMachine imageFileMachine) { #if NETFRAMEWORK UnderlyingAssemblyBuilder.Save(assemblyFileName, portableExecutableKind, (System.Reflection.ImageFileMachine)imageFileMachine); @@ -174,134 +153,7 @@ public void Save(string assemblyFileName, System.Reflection.PortableExecutableKi #region IAssemblySymbol /// - public IEnumerable DefinedTypes => ResolveTypeSymbols(UnderlyingAssembly.DefinedTypes); - - /// - public IMethodSymbol? EntryPoint => ResolveMethodSymbol(UnderlyingAssembly.EntryPoint); - - /// - public IEnumerable ExportedTypes => ResolveTypeSymbols(UnderlyingAssembly.ExportedTypes); - - /// - public string? FullName => UnderlyingAssembly.FullName; - - /// - public string ImageRuntimeVersion => UnderlyingAssembly.ImageRuntimeVersion; - - /// - public IModuleSymbol ManifestModule => ResolveModuleSymbol(UnderlyingAssembly.ManifestModule); - - /// - public IEnumerable Modules => ResolveModuleSymbols(UnderlyingAssembly.Modules); - - /// - public override bool IsComplete => _builder == null; - - public string Location => throw new NotImplementedException(); - - /// - public ITypeSymbol[] GetExportedTypes() - { - return ResolveTypeSymbols(UnderlyingAssembly.GetExportedTypes()); - } - - /// - public IModuleSymbol? GetModule(string name) - { - return ResolveModuleSymbol(UnderlyingAssembly.GetModule(name)); - } - - /// - public IModuleSymbol[] GetModules() - { - return ResolveModuleSymbols(UnderlyingAssembly.GetModules()); - } - - /// - public IModuleSymbol[] GetModules(bool getResourceModules) - { - return ResolveModuleSymbols(UnderlyingAssembly.GetModules(getResourceModules)); - } - - /// - public AssemblyIdentity GetIdentity() - { - return UnderlyingAssembly.GetName().Pack(); - } - - /// - public AssemblyIdentity[] GetReferencedAssemblies() - { - return UnderlyingAssembly.GetReferencedAssemblies().Pack(); - } - - /// - public ITypeSymbol? GetType(string name, bool throwOnError) - { - return ResolveTypeSymbol(UnderlyingAssembly.GetType(name, throwOnError)); - } - - /// - public ITypeSymbol? GetType(string name, bool throwOnError, bool ignoreCase) - { - return ResolveTypeSymbol(UnderlyingAssembly.GetType(name, throwOnError, ignoreCase)); - } - - /// - public ITypeSymbol? GetType(string name) - { - return ResolveTypeSymbol(UnderlyingAssembly.GetType(name)); - } - - /// - public ITypeSymbol[] GetTypes() - { - return ResolveTypeSymbols(UnderlyingAssembly.GetTypes()); - } - - /// - public CustomAttribute[] GetCustomAttributes(bool inherit = false) - { - return ResolveCustomAttributes(UnderlyingAssembly.GetCustomAttributesData()); - } - - /// - public CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) - { - var _attributeType = attributeType.Unpack(); - return ResolveCustomAttributes(UnderlyingAssembly.GetCustomAttributesData().Where(i => i.AttributeType == _attributeType).ToArray()); - } - - /// - public CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) - { - var _attributeType = attributeType.Unpack(); - return ResolveCustomAttribute(UnderlyingAssembly.GetCustomAttributesData().Where(i => i.AttributeType == _attributeType).FirstOrDefault()); - } - - /// - public bool IsDefined(ITypeSymbol attributeType, bool inherit = false) - { - return UnderlyingAssembly.IsDefined(attributeType.Unpack(), inherit); - } - - /// - public ManifestResourceInfo? GetManifestResourceInfo(string resourceName) - { - return ResolveManifestResourceInfo(UnderlyingAssembly.GetManifestResourceInfo(resourceName)); - } - - /// - public Stream? GetManifestResourceStream(string name) - { - return UnderlyingAssembly.GetManifestResourceStream(name); - } - - /// - public Stream? GetManifestResourceStream(ITypeSymbol type, string name) - { - return UnderlyingAssembly.GetManifestResourceStream(type.Unpack(), name); - } + public override bool IsComplete => _assembly != null; #endregion diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionConstructorSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionConstructorSymbolBuilder.cs index ab93503cd..58c089f67 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionConstructorSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionConstructorSymbolBuilder.cs @@ -1,19 +1,25 @@ using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; using System.Reflection; using System.Reflection.Emit; +using IKVM.CoreLib.Collections; +using IKVM.CoreLib.Reflection; using IKVM.CoreLib.Symbols.Emit; namespace IKVM.CoreLib.Symbols.Reflection.Emit { - class ReflectionConstructorSymbolBuilder : ReflectionMethodBaseSymbolBuilder, IReflectionConstructorSymbolBuilder + class ReflectionConstructorSymbolBuilder : ReflectionConstructorSymbol, IReflectionConstructorSymbolBuilder { readonly ConstructorBuilder _builder; ConstructorInfo? _ctor; ReflectionILGenerator? _il; + List? _incompleteCustomAttributes; /// /// Initializes a new instance. @@ -24,39 +30,30 @@ class ReflectionConstructorSymbolBuilder : ReflectionMethodBaseSymbolBuilder, IR /// /// public ReflectionConstructorSymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbolBuilder resolvingModule, IReflectionTypeSymbolBuilder resolvingType, ConstructorBuilder builder) : - base(context, resolvingModule, resolvingType) + base(context, resolvingModule, resolvingType, builder) { _builder = builder ?? throw new ArgumentNullException(nameof(builder)); } /// - public ConstructorInfo UnderlyingConstructor => _ctor ?? _builder; - - /// - public ConstructorInfo UnderlyingEmitConstructor => _builder; - - /// - public ConstructorInfo UnderlyingDynamicEmitConstructor => _ctor ?? throw new InvalidOperationException(); - - /// - public override MethodBase UnderlyingMethodBase => UnderlyingConstructor; + public ConstructorBuilder UnderlyingConstructorBuilder => _builder; /// - public override MethodBase UnderlyingEmitMethodBase => UnderlyingEmitConstructor; + public override ConstructorInfo UnderlyingRuntimeConstructor => _ctor ?? throw new InvalidOperationException(); /// - public ConstructorBuilder UnderlyingConstructorBuilder => _builder; + public IReflectionModuleSymbolBuilder ResolvingModuleBuilder => (IReflectionModuleSymbolBuilder)ResolvingModule; #region IConstructorSymbolBuilder /// - public override void SetImplementationFlags(MethodImplAttributes attributes) + public void SetImplementationFlags(MethodImplAttributes attributes) { UnderlyingConstructorBuilder.SetImplementationFlags(attributes); } /// - public override IParameterSymbolBuilder DefineParameter(int iSequence, ParameterAttributes attributes, string? strParamName) + public IParameterSymbolBuilder DefineParameter(int iSequence, ParameterAttributes attributes, string? strParamName) { if (iSequence <= 0) throw new ArgumentOutOfRangeException(nameof(iSequence)); @@ -65,54 +62,80 @@ public override IParameterSymbolBuilder DefineParameter(int iSequence, Parameter } /// - public override IILGenerator GetILGenerator() + public IILGenerator GetILGenerator() { return _il ??= new ReflectionILGenerator(Context, UnderlyingConstructorBuilder.GetILGenerator()); } /// - public override IILGenerator GetILGenerator(int streamSize) + public IILGenerator GetILGenerator(int streamSize) { return _il ??= new ReflectionILGenerator(Context, UnderlyingConstructorBuilder.GetILGenerator(streamSize)); } + #endregion + + #region IConstructorSymbol + /// - public override void SetCustomAttribute(ICustomAttributeBuilder customBuilder) - { - UnderlyingConstructorBuilder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); - } + public override bool IsComplete => _ctor != null; + + #endregion + + #region ICustomAttributeProviderBuilder /// - public override void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) + public void SetCustomAttribute(CustomAttribute attribute) { - UnderlyingConstructorBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); + UnderlyingConstructorBuilder.SetCustomAttribute(attribute.Unpack()); + _incompleteCustomAttributes ??= []; + _incompleteCustomAttributes.Add(attribute); } #endregion - #region IConstructorSymbol + #region ICustomAttributeProvider /// - public override bool IsComplete => _ctor != null; - - #endregion + public override CustomAttribute[] GetCustomAttributes(bool inherit = false) + { + if (IsComplete) + return ResolveCustomAttributes(UnderlyingRuntimeConstructor.GetCustomAttributesData(inherit).ToArray()); + else + return _incompleteCustomAttributes?.ToArray() ?? []; + } - #region IMethodBaseSymbol + /// + public override CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) + { + if (IsComplete) + { + var _attributeType = attributeType.Unpack(); + return ResolveCustomAttributes(UnderlyingRuntimeConstructor.GetCustomAttributesData().Where(i => i.AttributeType == _attributeType).ToArray()); + } + else + return GetCustomAttributes(inherit).Where(i => i.AttributeType == attributeType).ToArray(); + } /// - public override ITypeSymbol[] GetGenericArguments() + public override CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) { - // constructor never has generic arguments - return []; + if (IsComplete) + { + var _attributeType = attributeType.Unpack(); + return ResolveCustomAttribute(UnderlyingRuntimeConstructor.GetCustomAttributesData().FirstOrDefault(i => i.AttributeType == _attributeType)); + } + else + return GetCustomAttributes(inherit).FirstOrDefault(i => i.AttributeType == attributeType); } #endregion /// - public override void OnComplete() + public void OnComplete() { _ctor = (ConstructorInfo?)ResolvingModule.UnderlyingModule.ResolveMethod(MetadataToken) ?? throw new InvalidOperationException(); - base.OnComplete(); + _incompleteCustomAttributes = null; } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionCustomAttributeBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionCustomAttributeBuilder.cs deleted file mode 100644 index eed10e2cb..000000000 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionCustomAttributeBuilder.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using System.Reflection.Emit; - -using IKVM.CoreLib.Symbols.Emit; - -namespace IKVM.CoreLib.Symbols.Reflection.Emit -{ - - class ReflectionCustomAttributeBuilder : ICustomAttributeBuilder - { - - readonly CustomAttributeBuilder _builder; - - /// - /// Initializes a new instance. - /// - public ReflectionCustomAttributeBuilder(CustomAttributeBuilder builder) - { - _builder = builder ?? throw new ArgumentNullException(nameof(builder)); - } - - /// - /// Gets the underlying reflection . - /// - internal CustomAttributeBuilder UnderlyingBuilder => _builder; - - } - -} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionEventBuilderInfo.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionEventBuilderInfo.cs index 7a87c506d..58f091946 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionEventBuilderInfo.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionEventBuilderInfo.cs @@ -1,6 +1,7 @@ using System; using System.Reflection; using System.Reflection.Emit; + using IKVM.CoreLib.Reflection; namespace IKVM.CoreLib.Symbols.Reflection.Emit diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionEventSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionEventSymbolBuilder.cs index 9525d0045..2ca8260cd 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionEventSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionEventSymbolBuilder.cs @@ -7,11 +7,10 @@ namespace IKVM.CoreLib.Symbols.Reflection.Emit { - class ReflectionEventSymbolBuilder : ReflectionMemberSymbolBuilder, IReflectionEventSymbolBuilder + class ReflectionEventSymbolBuilder : ReflectionEventSymbol, IReflectionEventSymbolBuilder { readonly EventBuilder _builder; - readonly ReflectionEventBuilderInfo _builderInfo; EventInfo? _event; /// @@ -23,23 +22,19 @@ class ReflectionEventSymbolBuilder : ReflectionMemberSymbolBuilder, IReflectionE /// /// public ReflectionEventSymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbolBuilder resolvingModule, IReflectionTypeSymbolBuilder resolvingType, EventBuilder builder) : - base(context, resolvingModule, resolvingType) + base(context, resolvingModule, resolvingType, new ReflectionEventBuilderInfo(builder)) { _builder = builder ?? throw new ArgumentNullException(nameof(builder)); - _builderInfo = new ReflectionEventBuilderInfo(_builder); } /// - public EventInfo UnderlyingEvent => _event ?? _builderInfo; + public EventBuilder UnderlyingEventBuilder => _builder; /// - public EventInfo UnderlyingEmitEvent => UnderlyingEvent; + public override EventInfo UnderlyingRuntimeEvent => _event ?? throw new InvalidOperationException(); /// - public EventBuilder UnderlyingEventBuilder => _builder ?? throw new NotImplementedException(); - - /// - public override MemberInfo UnderlyingMember => UnderlyingEvent; + public IReflectionModuleSymbolBuilder ResolvingModuleBuilder => (IReflectionModuleSymbolBuilder)ResolvingModule; #region IEventSymbolBuilder @@ -67,98 +62,29 @@ public void AddOtherMethod(IMethodSymbolBuilder mdBuilder) UnderlyingEventBuilder.AddOtherMethod(((IReflectionMethodSymbolBuilder)mdBuilder).UnderlyingMethodBuilder); } - /// - public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) - { - UnderlyingEventBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); - } + #endregion + + #region ICustomAttributeProviderBuilder /// - public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) + public void SetCustomAttribute(CustomAttribute attribute) { - UnderlyingEventBuilder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); + UnderlyingEventBuilder.SetCustomAttribute(attribute.Unpack()); } #endregion #region IEventSymbol - /// - public System.Reflection.EventAttributes Attributes => UnderlyingEvent.Attributes; - - /// - public ITypeSymbol? EventHandlerType => ResolveTypeSymbol(UnderlyingEvent.EventHandlerType); - - /// - public bool IsSpecialName => UnderlyingEvent.IsSpecialName; - - /// - public IMethodSymbol? AddMethod => ResolveMethodSymbol(UnderlyingEvent.AddMethod); - - /// - public IMethodSymbol? RemoveMethod => ResolveMethodSymbol(UnderlyingEvent.RemoveMethod); - - /// - public IMethodSymbol? RaiseMethod => ResolveMethodSymbol(UnderlyingEvent.RaiseMethod); - /// public override bool IsComplete => _event != null; - /// - public IMethodSymbol? GetAddMethod() - { - return ResolveMethodSymbol(UnderlyingEvent.GetAddMethod()); - } - - /// - public IMethodSymbol? GetAddMethod(bool nonPublic) - { - return ResolveMethodSymbol(UnderlyingEvent.GetAddMethod(nonPublic)); - } - - /// - public IMethodSymbol? GetRemoveMethod() - { - return ResolveMethodSymbol(UnderlyingEvent.GetRemoveMethod()); - } - - /// - public IMethodSymbol? GetRemoveMethod(bool nonPublic) - { - return ResolveMethodSymbol(UnderlyingEvent.GetRemoveMethod(nonPublic)); - } - - /// - public IMethodSymbol? GetRaiseMethod() - { - return ResolveMethodSymbol(UnderlyingEvent.GetRaiseMethod()); - } - - /// - public IMethodSymbol? GetRaiseMethod(bool nonPublic) - { - return ResolveMethodSymbol(UnderlyingEvent.GetRaiseMethod(nonPublic)); - } - - /// - public IMethodSymbol[] GetOtherMethods() - { - return ResolveMethodSymbols(UnderlyingEvent.GetOtherMethods()); - } - - /// - public IMethodSymbol[] GetOtherMethods(bool nonPublic) - { - return ResolveMethodSymbols(UnderlyingEvent.GetOtherMethods(nonPublic)); - } - #endregion /// - public override void OnComplete() + public void OnComplete() { _event = (EventInfo?)ResolvingModule.UnderlyingModule.ResolveMember(MetadataToken) ?? throw new InvalidOperationException(); - base.OnComplete(); } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionFieldSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionFieldSymbolBuilder.cs index 91186b5ad..6e99440cf 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionFieldSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionFieldSymbolBuilder.cs @@ -7,7 +7,7 @@ namespace IKVM.CoreLib.Symbols.Reflection.Emit { - class ReflectionFieldSymbolBuilder : ReflectionMemberSymbolBuilder, IReflectionFieldSymbolBuilder + class ReflectionFieldSymbolBuilder : ReflectionFieldSymbol, IReflectionFieldSymbolBuilder { readonly FieldBuilder _builder; @@ -22,25 +22,26 @@ class ReflectionFieldSymbolBuilder : ReflectionMemberSymbolBuilder, IReflectionF /// /// public ReflectionFieldSymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbolBuilder resolvingModule, IReflectionTypeSymbolBuilder? resolvingType, FieldBuilder builder) : - base(context, resolvingModule, resolvingType) + base(context, resolvingModule, resolvingType, builder) { _builder = builder ?? throw new ArgumentNullException(nameof(builder)); } /// - public FieldInfo UnderlyingField => _field ?? _builder; + public FieldBuilder UnderlyingFieldBuilder => _builder; /// - public FieldInfo UnderlyingEmitField => _builder; + public override FieldInfo UnderlyingRuntimeField => _field ?? throw new InvalidOperationException(); /// - public FieldInfo UnderlyingDynamicEmitField => _field ?? throw new InvalidOperationException(); + public IReflectionModuleSymbolBuilder ResolvingModuleBuilder => (IReflectionModuleSymbolBuilder)ResolvingModule; - /// - public override MemberInfo UnderlyingMember => UnderlyingField; + #region IFieldSymbol - /// - public FieldBuilder UnderlyingFieldBuilder => _builder; + /// + public override bool IsComplete => _field != null; + + #endregion #region IFieldSymbolBuilder @@ -56,92 +57,22 @@ public void SetOffset(int iOffset) UnderlyingFieldBuilder.SetOffset(iOffset); } - /// - public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) - { - UnderlyingFieldBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); - } - - /// - public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) - { - UnderlyingFieldBuilder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); - } - #endregion - #region IFieldSymbol - - /// - public FieldAttributes Attributes => UnderlyingField.Attributes; - - /// - public ITypeSymbol FieldType => ResolveTypeSymbol(UnderlyingField.FieldType); - - /// - public bool IsSpecialName => UnderlyingField.IsSpecialName; - - /// - public bool IsAssembly => UnderlyingField.IsAssembly; - - /// - public bool IsFamily => UnderlyingField.IsFamily; - - /// - public bool IsFamilyAndAssembly => UnderlyingField.IsFamilyAndAssembly; + #region ICustomAttributeProviderBuilder - /// - public bool IsFamilyOrAssembly => UnderlyingField.IsFamilyOrAssembly; - - /// - public bool IsInitOnly => UnderlyingField.IsInitOnly; - - /// - public bool IsLiteral => UnderlyingField.IsLiteral; - - /// - public bool IsNotSerialized => UnderlyingField.IsNotSerialized; - - /// - public bool IsPinvokeImpl => UnderlyingField.IsPinvokeImpl; - - /// - public bool IsPrivate => UnderlyingField.IsPrivate; - - /// - public bool IsPublic => UnderlyingField.IsPublic; - - /// - public bool IsStatic => UnderlyingField.IsStatic; - - /// - public override bool IsComplete => _field != null; - - /// - public ITypeSymbol[] GetOptionalCustomModifiers() - { - return ResolveTypeSymbols(UnderlyingField.GetOptionalCustomModifiers()); - } - - /// - public ITypeSymbol[] GetRequiredCustomModifiers() - { - return ResolveTypeSymbols(UnderlyingField.GetRequiredCustomModifiers()); - } - - /// - public object? GetRawConstantValue() + /// + public void SetCustomAttribute(CustomAttribute attribute) { - return UnderlyingField.GetRawConstantValue(); + UnderlyingFieldBuilder.SetCustomAttribute(attribute.Unpack()); } #endregion /// - public override void OnComplete() + public void OnComplete() { _field = ResolvingModule.UnderlyingModule.ResolveField(MetadataToken) ?? throw new InvalidOperationException(); - base.OnComplete(); } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionGenericTypeParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionGenericTypeParameterSymbolBuilder.cs index 37c8c2b5c..f181b5f3d 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionGenericTypeParameterSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionGenericTypeParameterSymbolBuilder.cs @@ -1,21 +1,15 @@ using System; -using System.Reflection; using System.Reflection.Emit; -using IKVM.CoreLib.Reflection; - namespace IKVM.CoreLib.Symbols.Reflection.Emit { - class ReflectionGenericTypeParameterSymbolBuilder : ReflectionMemberSymbolBuilder, IReflectionGenericTypeParameterSymbolBuilder + class ReflectionGenericTypeParameterSymbolBuilder : ReflectionGenericTypeParameterSymbol, IReflectionGenericTypeParameterSymbolBuilder { - readonly IReflectionMemberSymbol? _resolvingMember; readonly GenericTypeParameterBuilder _builder; Type? _type; - ReflectionTypeSpecTable _specTable; - /// /// Initializes a new instance. /// @@ -25,145 +19,28 @@ class ReflectionGenericTypeParameterSymbolBuilder : ReflectionMemberSymbolBuilde /// /// public ReflectionGenericTypeParameterSymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbolBuilder resolvingModule, IReflectionMemberSymbolBuilder resolvingMember, GenericTypeParameterBuilder builder) : - base(context, resolvingModule, resolvingMember as IReflectionTypeSymbolBuilder) + base(context, resolvingModule, resolvingMember, builder) { - _resolvingMember = resolvingMember ?? throw new ArgumentNullException(nameof(resolvingMember)); _builder = builder ?? throw new ArgumentNullException(nameof(builder)); - _specTable = new ReflectionTypeSpecTable(); } /// - public Type UnderlyingType => _type ?? _builder; - - /// - public Type UnderlyingEmitType => UnderlyingType; - - /// - public Type UnderlyingDynamicEmitType => _type ?? throw new InvalidOperationException(); - - /// - public override MemberInfo UnderlyingMember => UnderlyingType; + public override Type UnderlyingRuntimeType => _type ?? throw new InvalidOperationException(); #region IReflectionGenericTypeParameterSymbolBuilder /// public GenericTypeParameterBuilder UnderlyingGenericTypeParameterBuilder => _builder ?? throw new InvalidOperationException(); - #endregion - - #region IReflectionTypeSymbol - - /// - public IReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method) - { - throw new NotSupportedException(); - } - - /// - public IReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) - { - throw new NotSupportedException(); - } - - /// - public IReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor) - { - throw new NotSupportedException(); - } - - /// - public IReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) - { - throw new NotSupportedException(); - } - - /// - public IReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method) - { - throw new NotSupportedException(); - } - - /// - public IReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) - { - throw new NotSupportedException(); - } - - /// - public IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field) - { - throw new NotSupportedException(); - } - - /// - public IReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) - { - throw new NotSupportedException(); - } - - /// - public IReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property) - { - throw new NotSupportedException(); - } - - /// - public IReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) - { - throw new NotSupportedException(); - } - - /// - public IReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event) - { - throw new NotSupportedException(); - } - - /// - public IReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type type) - { - throw new NotSupportedException(); - } - - /// - public IReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeSymbol(GenericTypeParameterBuilder genericType) - { - throw new NotSupportedException(); - } - - /// - public IReflectionTypeSymbol GetOrCreateSZArrayTypeSymbol() - { - return _specTable.GetOrCreateSZArrayTypeSymbol(); - } - /// - public IReflectionTypeSymbol GetOrCreateArrayTypeSymbol(int rank) + public void OnComplete(Type type) { - return _specTable.GetOrCreateArrayTypeSymbol(rank); - } - - /// - public IReflectionTypeSymbol GetOrCreatePointerTypeSymbol() - { - return _specTable.GetOrCreatePointerTypeSymbol(); - } - - /// - public IReflectionTypeSymbol GetOrCreateByRefTypeSymbol() - { - return _specTable.GetOrCreateByRefTypeSymbol(); - } - - /// - public IReflectionTypeSymbol GetOrCreateGenericTypeSymbol(IReflectionTypeSymbol[] genericTypeDefinition) - { - return _specTable.GetOrCreateGenericTypeSymbol(genericTypeDefinition); + _type = type; } #endregion - #region ITypeSymbolBuilder + #region IGenericTypeParameterSymbolBuilder /// public void SetBaseTypeConstraint(ITypeSymbol? baseTypeConstraint) @@ -174,7 +51,7 @@ public void SetBaseTypeConstraint(ITypeSymbol? baseTypeConstraint) /// public void SetGenericParameterAttributes(System.Reflection.GenericParameterAttributes genericParameterAttributes) { - UnderlyingGenericTypeParameterBuilder.SetGenericParameterAttributes((GenericParameterAttributes)genericParameterAttributes); + UnderlyingGenericTypeParameterBuilder.SetGenericParameterAttributes(genericParameterAttributes); } /// @@ -188,535 +65,20 @@ public void SetInterfaceConstraints(params ITypeSymbol[]? interfaceConstraints) #region ITypeSymbol /// - public IAssemblySymbol Assembly => ResolveAssemblySymbol(UnderlyingType.Assembly); - - /// - public string? AssemblyQualifiedName => UnderlyingType.AssemblyQualifiedName; - - /// - public System.Reflection.TypeAttributes Attributes => (System.Reflection.TypeAttributes)UnderlyingType.Attributes; - - /// - public ITypeSymbol? BaseType => ResolveTypeSymbol(UnderlyingType.BaseType); - - /// - public bool ContainsGenericParameters => UnderlyingType.ContainsGenericParameters; - - /// - public IMethodBaseSymbol? DeclaringMethod => ResolveMethodBaseSymbol(UnderlyingType.DeclaringMethod); - - /// - public string? FullName => UnderlyingType.FullName; - - /// - public string? Namespace => UnderlyingType.Namespace; - - /// - public System.Reflection.GenericParameterAttributes GenericParameterAttributes => (System.Reflection.GenericParameterAttributes)UnderlyingType.GenericParameterAttributes; - - /// - public int GenericParameterPosition => UnderlyingType.GenericParameterPosition; - - /// - public ITypeSymbol[] GenericTypeArguments => ResolveTypeSymbols(UnderlyingType.GenericTypeArguments); - - /// - public bool HasElementType => UnderlyingType.HasElementType; - - /// - public TypeCode TypeCode => Type.GetTypeCode(UnderlyingType); - - /// - public bool IsAbstract => UnderlyingType.IsAbstract; - - /// - public bool IsSZArray => UnderlyingType.IsSZArray(); - - /// - public bool IsArray => UnderlyingType.IsArray; - - /// - public bool IsAutoLayout => UnderlyingType.IsAutoLayout; - - /// - public bool IsExplicitLayout => UnderlyingType.IsExplicitLayout; - - /// - public bool IsByRef => UnderlyingType.IsByRef; - - /// - public bool IsClass => UnderlyingType.IsClass; - - /// - public bool IsEnum => UnderlyingType.IsEnum; - - /// - public bool IsInterface => UnderlyingType.IsInterface; - - /// - public bool IsConstructedGenericType => UnderlyingType.IsConstructedGenericType; - - /// - public bool IsGenericParameter => UnderlyingType.IsGenericParameter; - - /// - public bool IsGenericType => UnderlyingType.IsGenericType; - - /// - public bool IsGenericTypeDefinition => UnderlyingType.IsGenericTypeDefinition; - - /// - public bool IsLayoutSequential => UnderlyingType.IsLayoutSequential; - - /// - public bool IsNested => UnderlyingType.IsNested; - - /// - public bool IsNestedAssembly => UnderlyingType.IsNestedAssembly; - - /// - public bool IsNestedFamANDAssem => UnderlyingType.IsNestedFamANDAssem; - - /// - public bool IsNestedFamORAssem => UnderlyingType.IsNestedFamORAssem; - - /// - public bool IsNestedFamily => UnderlyingType.IsNestedFamily; - - /// - public bool IsNestedPrivate => UnderlyingType.IsNestedPrivate; - - /// - public bool IsNestedPublic => UnderlyingType.IsNestedPublic; - - /// - public bool IsNotPublic => UnderlyingType.IsNotPublic; - - /// - public bool IsPointer => UnderlyingType.IsPointer; - -#if NET8_0_OR_GREATER - - /// - public bool IsFunctionPointer => UnderlyingType.IsFunctionPointer; - - /// - public bool IsUnmanagedFunctionPointer => UnderlyingType.IsUnmanagedFunctionPointer; - -#else - - /// - public bool IsFunctionPointer => throw new NotImplementedException(); - - /// - public bool IsUnmanagedFunctionPointer => throw new NotImplementedException(); - -#endif - - /// - public bool IsPrimitive => UnderlyingType.IsPrimitive; - - /// - public bool IsPublic => UnderlyingType.IsPublic; - - /// - public bool IsSealed => UnderlyingType.IsSealed; - - /// - public bool IsSerializable => UnderlyingType.IsSerializable; - - /// - public bool IsValueType => UnderlyingType.IsValueType; - - /// - public bool IsVisible => UnderlyingType.IsVisible; - - /// - public bool IsSignatureType => throw new NotImplementedException(); - - /// - public bool IsSpecialName => UnderlyingType.IsSpecialName; - - /// - public IConstructorSymbol? TypeInitializer => ResolveConstructorSymbol(UnderlyingType.TypeInitializer); - - /// - public int GetArrayRank() - { - return UnderlyingType.GetArrayRank(); - } - - /// - public IConstructorSymbol? GetConstructor(System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) - { - return ResolveConstructorSymbol(UnderlyingType.GetConstructor((BindingFlags)bindingAttr, binder: null, types.Unpack(), modifiers: null)); - } - - /// - public IConstructorSymbol? GetConstructor(ITypeSymbol[] types) - { - return ResolveConstructorSymbol(UnderlyingType.GetConstructor(types.Unpack())); - } - - /// - public IConstructorSymbol[] GetConstructors() - { - return ResolveConstructorSymbols(UnderlyingType.GetConstructors()); - } - - /// - public IConstructorSymbol[] GetConstructors(System.Reflection.BindingFlags bindingAttr) - { - return ResolveConstructorSymbols(UnderlyingType.GetConstructors((BindingFlags)bindingAttr)); - } - - /// - public IMemberSymbol[] GetDefaultMembers() - { - return ResolveMemberSymbols(UnderlyingType.GetDefaultMembers()); - } - - /// - public ITypeSymbol? GetElementType() - { - return ResolveTypeSymbol(UnderlyingType.GetElementType()); - } - - /// - public string? GetEnumName(object value) - { - return UnderlyingType.GetEnumName(value); - } - - /// - public string[] GetEnumNames() - { - return UnderlyingType.GetEnumNames(); - } - - /// - public ITypeSymbol GetEnumUnderlyingType() - { - return ResolveTypeSymbol(UnderlyingType.GetEnumUnderlyingType()); - } - - /// - public Array GetEnumValues() - { - return UnderlyingType.GetEnumValues(); - } - - /// - public IEventSymbol? GetEvent(string name) - { - return ResolveEventSymbol(UnderlyingType.GetEvent(name)); - } - - /// - public IEventSymbol? GetEvent(string name, System.Reflection.BindingFlags bindingAttr) - { - return ResolveEventSymbol(UnderlyingType.GetEvent(name, (BindingFlags)bindingAttr)); - } - - /// - public IEventSymbol[] GetEvents() - { - return ResolveEventSymbols(UnderlyingType.GetEvents()); - } - - /// - public IEventSymbol[] GetEvents(System.Reflection.BindingFlags bindingAttr) - { - return ResolveEventSymbols(UnderlyingType.GetEvents((BindingFlags)bindingAttr)); - } - - /// - public IFieldSymbol? GetField(string name) - { - return ResolveFieldSymbol(UnderlyingType.GetField(name)); - } - - /// - public IFieldSymbol? GetField(string name, System.Reflection.BindingFlags bindingAttr) - { - return ResolveFieldSymbol(UnderlyingType.GetField(name, (BindingFlags)bindingAttr)); - } - - /// - public IFieldSymbol[] GetFields() - { - return ResolveFieldSymbols(UnderlyingType.GetFields()); - } - - /// - public IFieldSymbol[] GetFields(System.Reflection.BindingFlags bindingAttr) - { - return ResolveFieldSymbols(UnderlyingType.GetFields((BindingFlags)bindingAttr)); - } - - /// - public ITypeSymbol[] GetGenericArguments() - { - return ResolveTypeSymbols(UnderlyingType.GetGenericArguments()); - } - - /// - public ITypeSymbol[] GetGenericParameterConstraints() - { - return ResolveTypeSymbols(UnderlyingType.GetGenericParameterConstraints()); - } - - /// - public ITypeSymbol GetGenericTypeDefinition() - { - return ResolveTypeSymbol(UnderlyingType.GetGenericTypeDefinition()); - } - - /// - public ITypeSymbol? GetInterface(string name) - { - return ResolveTypeSymbol(UnderlyingType.GetInterface(name)); - } - - /// - public ITypeSymbol? GetInterface(string name, bool ignoreCase) - { - return ResolveTypeSymbol(UnderlyingType.GetInterface(name, ignoreCase)); - } - - /// - public InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) - { - return ResolveInterfaceMapping(UnderlyingType.GetInterfaceMap(interfaceType.Unpack())); - } + public override bool IsComplete => _type != null; - /// - public ITypeSymbol[] GetInterfaces(bool inherit = true) - { - if (inherit) - return ResolveTypeSymbols(UnderlyingType.GetInterfaces()); - else - throw new NotImplementedException(); - } - - /// - public IMemberSymbol[] GetMember(string name) - { - return ResolveMemberSymbols(UnderlyingType.GetMember(name)); - } - - /// - public IMemberSymbol[] GetMember(string name, System.Reflection.BindingFlags bindingAttr) - { - return ResolveMemberSymbols(UnderlyingType.GetMember(name, (BindingFlags)bindingAttr)); - } - - /// - public IMemberSymbol[] GetMember(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) - { - return ResolveMemberSymbols(UnderlyingType.GetMember(name, (MemberTypes)type, (BindingFlags)bindingAttr)); - } - - /// - public IMemberSymbol[] GetMembers(System.Reflection.BindingFlags bindingAttr) - { - return ResolveMemberSymbols(UnderlyingType.GetMembers((BindingFlags)bindingAttr)); - } - - /// - public IMemberSymbol[] GetMembers() - { - return ResolveMemberSymbols(UnderlyingType.GetMembers()); - } - - /// - public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr) - { - return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr)); - } - - /// - public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) - { - return ResolveMethodSymbol(UnderlyingType.GetMethod(name, types.Unpack())); - } - - /// - public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types) - { - return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), null)); - } - - /// - public IMethodSymbol? GetMethod(string name) - { - return ResolveMethodSymbol(UnderlyingType.GetMethod(name)); - } - - /// - public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) - { - return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, (CallingConventions)callConvention, types.Unpack(), modifiers?.Unpack())); - } - - /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) - { - throw new NotImplementedException(); - } - - /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) - { - throw new NotImplementedException(); - } - - /// - public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) - { - return ResolveMethodSymbol(UnderlyingType.GetMethod(name, (BindingFlags)bindingAttr, null, types.Unpack(), modifiers?.Unpack())); - } - - /// - public IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) - { - throw new NotImplementedException(); - } - - /// - public IMethodSymbol[] GetMethods(System.Reflection.BindingFlags bindingAttr) - { - return ResolveMethodSymbols(UnderlyingType.GetMethods((BindingFlags)bindingAttr)); - } - - /// - public IMethodSymbol[] GetMethods() - { - return ResolveMethodSymbols(UnderlyingType.GetMethods()); - } - - /// - public ITypeSymbol? GetNestedType(string name) - { - return ResolveTypeSymbol(UnderlyingType.GetNestedType(name)); - } - - /// - public ITypeSymbol? GetNestedType(string name, System.Reflection.BindingFlags bindingAttr) - { - return ResolveTypeSymbol(UnderlyingType.GetNestedType(name, (BindingFlags)bindingAttr)); - } - - /// - public ITypeSymbol[] GetNestedTypes() - { - return ResolveTypeSymbols(UnderlyingType.GetNestedTypes()); - } - - /// - public ITypeSymbol[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr) - { - return ResolveTypeSymbols(UnderlyingType.GetNestedTypes((BindingFlags)bindingAttr)); - } - - /// - public IPropertySymbol[] GetProperties() - { - return ResolvePropertySymbols(UnderlyingType.GetProperties()); - } - - /// - public IPropertySymbol[] GetProperties(System.Reflection.BindingFlags bindingAttr) - { - return ResolvePropertySymbols(UnderlyingType.GetProperties((BindingFlags)bindingAttr)); - } - - /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol[] types) - { - return ResolvePropertySymbol(UnderlyingType.GetProperty(name, types.Unpack())); - } - - /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types) - { - return ResolvePropertySymbol(UnderlyingType.GetProperty(name, returnType?.Unpack(), types.Unpack())); - } - - /// - public IPropertySymbol? GetProperty(string name, System.Reflection.BindingFlags bindingAttr) - { - return ResolvePropertySymbol(UnderlyingType.GetProperty(name, (BindingFlags)bindingAttr)); - } - - /// - public IPropertySymbol? GetProperty(string name) - { - return ResolvePropertySymbol(UnderlyingType.GetProperty(name)); - } - - /// - public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) - { - return ResolvePropertySymbol(UnderlyingType.GetProperty(name, returnType?.Unpack())); - } - - /// - public bool IsAssignableFrom(ITypeSymbol? c) - { - return UnderlyingType.IsAssignableFrom(c?.Unpack()); - } - - /// - public bool IsEnumDefined(object value) - { - return UnderlyingType.IsEnumDefined(value); - } - - /// - public bool IsSubclassOf(ITypeSymbol c) - { - return UnderlyingType.IsSubclassOf(c.Unpack()); - } - - /// - public ITypeSymbol MakeArrayType() - { - return ResolveTypeSymbol(UnderlyingType.MakeArrayType()); - } - - /// - public ITypeSymbol MakeArrayType(int rank) - { - return ResolveTypeSymbol(UnderlyingType.MakeArrayType(rank)); - } + #endregion - /// - public ITypeSymbol MakeByRefType() - { - return ResolveTypeSymbol(UnderlyingType.MakeByRefType()); - } + #region ICustomAttributeProviderBuilder /// - public ITypeSymbol MakePointerType() + public void SetCustomAttribute(CustomAttribute attribute) { - return ResolveTypeSymbol(UnderlyingType.MakePointerType()); - } - - /// - public ITypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments) - { - return ResolveTypeSymbol(UnderlyingType.MakeGenericType(typeArguments.Unpack())); + UnderlyingGenericTypeParameterBuilder.SetCustomAttribute(attribute.Unpack()); } #endregion - /// - public override void OnComplete() - { - - } - } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionILGenerator.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionILGenerator.cs index 4cbac54c0..43505cd31 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionILGenerator.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionILGenerator.cs @@ -42,11 +42,10 @@ public ReflectionILGenerator(ReflectionSymbolContext context, ILGenerator il, bo [return: NotNullIfNotNull(nameof(symbol))] Type? GetEmitType(ITypeSymbol? symbol) { - var n = symbol.Name; if (_dynamic) - return ((IReflectionTypeSymbol?)symbol)?.UnderlyingDynamicEmitType; + return ((IReflectionTypeSymbol?)symbol)?.UnderlyingRuntimeType; else - return ((IReflectionTypeSymbol?)symbol)?.UnderlyingEmitType; + return ((IReflectionTypeSymbol?)symbol)?.UnderlyingType; } /// @@ -58,9 +57,9 @@ public ReflectionILGenerator(ReflectionSymbolContext context, ILGenerator il, bo FieldInfo? GetEmitField(IFieldSymbol? symbol) { if (_dynamic) - return ((IReflectionFieldSymbol?)symbol)?.UnderlyingDynamicEmitField; + return ((IReflectionFieldSymbol?)symbol)?.UnderlyingRuntimeField; else - return ((IReflectionFieldSymbol?)symbol)?.UnderlyingEmitField; + return ((IReflectionFieldSymbol?)symbol)?.UnderlyingField; } /// @@ -72,9 +71,9 @@ public ReflectionILGenerator(ReflectionSymbolContext context, ILGenerator il, bo ConstructorInfo? GetEmitConstructor(IConstructorSymbol? symbol) { if (_dynamic) - return ((IReflectionConstructorSymbol?)symbol)?.UnderlyingDynamicEmitConstructor; + return ((IReflectionConstructorSymbol?)symbol)?.UnderlyingRuntimeConstructor; else - return ((IReflectionConstructorSymbol?)symbol)?.UnderlyingEmitConstructor; + return ((IReflectionConstructorSymbol?)symbol)?.UnderlyingConstructor; } /// @@ -86,9 +85,9 @@ public ReflectionILGenerator(ReflectionSymbolContext context, ILGenerator il, bo MethodInfo? GetEmitMethod(IMethodSymbol? symbol) { if (_dynamic) - return ((IReflectionMethodSymbol?)symbol)?.UnderlyingDynamicEmitMethod; + return ((IReflectionMethodSymbol?)symbol)?.UnderlyingRuntimeMethod; else - return ((IReflectionMethodSymbol?)symbol)?.UnderlyingEmitMethod; + return ((IReflectionMethodSymbol?)symbol)?.UnderlyingMethod; } /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMemberSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMemberSymbolBuilder.cs deleted file mode 100644 index b093a18e1..000000000 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMemberSymbolBuilder.cs +++ /dev/null @@ -1,348 +0,0 @@ -using System; -using System.Diagnostics.CodeAnalysis; -using System.Linq; -using System.Reflection; -using System.Reflection.Emit; - -using IKVM.CoreLib.Reflection; - -namespace IKVM.CoreLib.Symbols.Reflection.Emit -{ - - abstract class ReflectionMemberSymbolBuilder : ReflectionSymbolBuilder, IReflectionMemberSymbolBuilder - { - - readonly IReflectionModuleSymbolBuilder _resolvingModule; - readonly IReflectionTypeSymbolBuilder? _resolvingType; - - /// - /// Initializes a new instance. - /// - /// - /// - /// - public ReflectionMemberSymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbolBuilder resolvingModule, IReflectionTypeSymbolBuilder? resolvingType) : - base(context) - { - _resolvingModule = resolvingModule ?? throw new ArgumentNullException(nameof(resolvingModule)); - _resolvingType = resolvingType; - } - - #region IReflectionMemberSymbol - - /// - public abstract MemberInfo UnderlyingMember { get; } - - /// - public virtual MemberInfo UnderlyingEmitMember => UnderlyingMember; - - /// - public IReflectionModuleSymbol ResolvingModule => _resolvingModule; - - /// - public IReflectionModuleSymbolBuilder ResolvingModuleBuilder => _resolvingModule; - - /// - public IReflectionTypeSymbol? ResolvingType => _resolvingType; - - #endregion - - #region IReflectionSymbolBuilder - - /// - [return: NotNullIfNotNull("type")] - public override IReflectionTypeSymbolBuilder ResolveTypeSymbol(TypeBuilder type) - { - if (type is null) - throw new ArgumentNullException(nameof(type)); - - if (UnderlyingMember == type) - return (IReflectionTypeSymbolBuilder)this; - - if (_resolvingType != null && type == _resolvingType.UnderlyingType) - return (IReflectionTypeSymbolBuilder)_resolvingType; - - if (type.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateTypeSymbol(type); - - return base.ResolveTypeSymbol(type); - } - - /// - [return: NotNullIfNotNull(nameof(ctor))] - public override IReflectionConstructorSymbolBuilder ResolveConstructorSymbol(ConstructorBuilder ctor) - { - if (ctor is null) - throw new ArgumentNullException(nameof(ctor)); - - if (UnderlyingMember == ctor) - return (IReflectionConstructorSymbolBuilder)this; - - if (ctor.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateConstructorSymbol(ctor); - - return base.ResolveConstructorSymbol(ctor); - } - - /// - [return: NotNullIfNotNull(nameof(method))] - public override IReflectionMethodSymbolBuilder ResolveMethodSymbol(MethodBuilder method) - { - if (method is null) - throw new ArgumentNullException(nameof(method)); - - if (UnderlyingMember == method) - return (IReflectionMethodSymbolBuilder)this; - - if (method.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateMethodSymbol(method); - - return base.ResolveMethodSymbol(method); - } - - /// - [return: NotNullIfNotNull(nameof(field))] - public override IReflectionFieldSymbolBuilder ResolveFieldSymbol(FieldBuilder field) - { - if (field is null) - throw new ArgumentNullException(nameof(field)); - - if (UnderlyingMember == field) - return (IReflectionFieldSymbolBuilder)this; - - if (field.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateFieldSymbol(field); - - return base.ResolveFieldSymbol(field); - } - - /// - [return: NotNullIfNotNull(nameof(property))] - public override IReflectionPropertySymbolBuilder ResolvePropertySymbol(PropertyBuilder property) - { - if (property is null) - throw new ArgumentNullException(nameof(property)); - - if (UnderlyingMember == property) - return (IReflectionPropertySymbolBuilder)this; - - if (property.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreatePropertySymbol(property); - - return base.ResolvePropertySymbol(property); - } - - /// - [return: NotNullIfNotNull(nameof(@event))] - public override IReflectionEventSymbolBuilder ResolveEventSymbol(EventBuilder @event) - { - if (@event is null) - throw new ArgumentNullException(nameof(@event)); - - if (@event.GetModuleBuilder() == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateEventSymbol(@event); - - return base.ResolveEventSymbol(@event); - } - - /// - [return: NotNullIfNotNull(nameof(parameter))] - public override IReflectionParameterSymbolBuilder? ResolveParameterSymbol(IReflectionMethodBaseSymbolBuilder method, ParameterBuilder parameter) - { - if (parameter is null) - return null; - - if (parameter.GetModuleBuilder() == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateParameterSymbol(method, parameter); - - return base.ResolveParameterSymbol(method, parameter); - } - - /// - [return: NotNullIfNotNull(nameof(parameter))] - public override IReflectionParameterSymbolBuilder? ResolveParameterSymbol(IReflectionPropertySymbolBuilder property, ParameterBuilder parameter) - { - if (parameter is null) - return null; - - if (parameter.GetMethodBuilder().Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateParameterSymbol(property, parameter); - - return base.ResolveParameterSymbol(property, parameter); - } - - #endregion - - #region IReflectionSymbol - - /// - [return: NotNullIfNotNull(nameof(type))] - public override IReflectionTypeSymbol? ResolveTypeSymbol(Type? type) - { - if (type is null) - return null; - - if (UnderlyingMember == type) - return (IReflectionTypeSymbol)this; - - if (_resolvingType != null && type == _resolvingType.UnderlyingType) - return _resolvingType; - - if (type.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateTypeSymbol(type); - - return base.ResolveTypeSymbol(type); - } - - /// - [return: NotNullIfNotNull(nameof(ctor))] - public override IReflectionConstructorSymbol? ResolveConstructorSymbol(ConstructorInfo? ctor) - { - if (ctor is null) - return null; - - if (UnderlyingMember == ctor) - return (IReflectionConstructorSymbol)this; - - if (ctor.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateConstructorSymbol(ctor); - - return base.ResolveConstructorSymbol(ctor); - } - - /// - [return: NotNullIfNotNull(nameof(method))] - public override IReflectionMethodSymbol? ResolveMethodSymbol(MethodInfo? method) - { - if (method is null) - return null; - - if (UnderlyingMember == method) - return (IReflectionMethodSymbol)this; - - if (method.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateMethodSymbol(method); - - return base.ResolveMethodSymbol(method); - } - - /// - [return: NotNullIfNotNull(nameof(field))] - public override IReflectionFieldSymbol? ResolveFieldSymbol(FieldInfo? field) - { - if (field is null) - return null; - - if (UnderlyingMember == field) - return (IReflectionFieldSymbol)this; - - if (field.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateFieldSymbol(field); - - return base.ResolveFieldSymbol(field); - } - - /// - [return: NotNullIfNotNull(nameof(property))] - public override IReflectionPropertySymbol? ResolvePropertySymbol(PropertyInfo? property) - { - if (property is null) - return null; - - if (UnderlyingMember == property) - return (IReflectionPropertySymbol)this; - - if (property.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreatePropertySymbol(property); - - return base.ResolvePropertySymbol(property); - } - - /// - [return: NotNullIfNotNull(nameof(@event))] - public override IReflectionEventSymbol? ResolveEventSymbol(EventInfo? @event) - { - if (@event is null) - return null; - - if (UnderlyingMember == @event) - return (IReflectionEventSymbol)this; - - if (@event.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateEventSymbol(@event); - - return base.ResolveEventSymbol(@event); - } - - /// - [return: NotNullIfNotNull(nameof(parameter))] - public override IReflectionParameterSymbol? ResolveParameterSymbol(ParameterInfo? parameter) - { - if (parameter is null) - throw new ArgumentNullException(nameof(parameter)); - - if (parameter.Member.Module == _resolvingModule.UnderlyingModule) - return _resolvingModule.GetOrCreateParameterSymbol(parameter); - - return base.ResolveParameterSymbol(parameter); - } - - #endregion - - #region IMemberSymbol - - /// - public virtual IModuleSymbol Module => ResolveModuleSymbol(UnderlyingMember.Module)!; - - /// - public virtual ITypeSymbol? DeclaringType => ResolveTypeSymbol(UnderlyingMember.DeclaringType)!; - - /// - public virtual System.Reflection.MemberTypes MemberType => (System.Reflection.MemberTypes)UnderlyingMember.MemberType; - - /// - public virtual int MetadataToken => UnderlyingMember.GetMetadataTokenSafe(); - - /// - public virtual string Name => UnderlyingMember.Name; - - /// - public CustomAttribute[] GetCustomAttributes(bool inherit = false) - { - return ResolveCustomAttributes(UnderlyingMember.GetCustomAttributesData()); - } - - /// - public CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) - { - var _attributeType = attributeType.Unpack(); - return ResolveCustomAttributes(UnderlyingMember.GetCustomAttributesData().Where(i => i.AttributeType == _attributeType).ToArray()); - } - - /// - public CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) - { - var _attributeType = attributeType.Unpack(); - return ResolveCustomAttribute(UnderlyingMember.GetCustomAttributesData().Where(i => i.AttributeType == _attributeType).FirstOrDefault()); - } - - /// - public virtual bool IsDefined(ITypeSymbol attributeType, bool inherit = false) - { - return UnderlyingMember.IsDefined(attributeType.Unpack(), inherit); - } - - #endregion - - /// - public virtual void OnComplete() - { - - } - - /// - public override string? ToString() => UnderlyingMember.ToString(); - - } - -} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodBaseSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodBaseSymbolBuilder.cs deleted file mode 100644 index eabf450d1..000000000 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodBaseSymbolBuilder.cs +++ /dev/null @@ -1,167 +0,0 @@ -using System.Reflection; -using System.Reflection.Emit; - -using IKVM.CoreLib.Symbols.Emit; - -namespace IKVM.CoreLib.Symbols.Reflection.Emit -{ - - abstract class ReflectionMethodBaseSymbolBuilder : ReflectionMemberSymbolBuilder, IReflectionMethodBaseSymbolBuilder - { - - ReflectionParameterTable _parameterTable; - - /// - /// Initializes a new instance. - /// - /// - /// - /// - public ReflectionMethodBaseSymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbolBuilder resolvingModule, IReflectionTypeSymbolBuilder? resolvingType) : - base(context, resolvingModule, resolvingType) - { - _parameterTable = new ReflectionParameterTable(context, resolvingModule, this); - } - - /// - public abstract MethodBase UnderlyingMethodBase { get; } - - /// - public virtual MethodBase UnderlyingEmitMethodBase => UnderlyingMethodBase; - - /// - public override MemberInfo UnderlyingMember => UnderlyingMethodBase; - - /// - public override MemberInfo UnderlyingEmitMember => UnderlyingEmitMethodBase; - - #region IReflectionMethodBaseSymbol - - /// - public IReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) - { - return _parameterTable.GetOrCreateParameterSymbol(parameter); - } - - #endregion - - #region IMethodBaseSymbolBuilder - - /// - public abstract void SetImplementationFlags(System.Reflection.MethodImplAttributes attributes); - - /// - public abstract IParameterSymbolBuilder DefineParameter(int position, System.Reflection.ParameterAttributes attributes, string? strParamName); - - /// - public abstract IILGenerator GetILGenerator(); - - /// - public abstract IILGenerator GetILGenerator(int streamSize); - - /// - public abstract void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute); - - /// - public abstract void SetCustomAttribute(ICustomAttributeBuilder customBuilder); - - /// - public IReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter) - { - return _parameterTable.GetOrCreateParameterSymbol(parameter); - } - - #endregion - - #region IMethodBaseSymbol - - /// - public System.Reflection.MethodAttributes Attributes => (System.Reflection.MethodAttributes)UnderlyingMethodBase.Attributes; - - /// - public System.Reflection.CallingConventions CallingConvention => (System.Reflection.CallingConventions)UnderlyingMethodBase.CallingConvention; - - /// - public bool ContainsGenericParameters => UnderlyingMethodBase.ContainsGenericParameters; - - /// - public bool IsAbstract => UnderlyingMethodBase.IsAbstract; - - /// - public bool IsAssembly => UnderlyingMethodBase.IsAssembly; - - /// - public bool IsConstructor => UnderlyingMethodBase.IsConstructor; - - /// - public bool IsFamily => UnderlyingMethodBase.IsFamily; - - /// - public bool IsFamilyAndAssembly => UnderlyingMethodBase.IsFamilyAndAssembly; - - /// - public bool IsFamilyOrAssembly => UnderlyingMethodBase.IsFamilyOrAssembly; - - /// - public bool IsFinal => UnderlyingMethodBase.IsFinal; - - /// - public bool IsGenericMethod => UnderlyingMethodBase.IsGenericMethod; - - /// - public bool IsGenericMethodDefinition => UnderlyingMethodBase.IsGenericMethodDefinition; - - /// - public bool IsHideBySig => UnderlyingMethodBase.IsHideBySig; - - /// - public bool IsPrivate => UnderlyingMethodBase.IsPrivate; - - /// - public bool IsPublic => UnderlyingMethodBase.IsPublic; - - /// - public bool IsStatic => UnderlyingMethodBase.IsStatic; - - /// - public bool IsVirtual => UnderlyingMethodBase.IsVirtual; - - /// - public bool IsSpecialName => UnderlyingMethodBase.IsSpecialName; - - /// - public MethodImplAttributes MethodImplementationFlags => UnderlyingMethodBase.MethodImplementationFlags; - - /// - public virtual ITypeSymbol[] GetGenericArguments() - { - return ResolveTypeSymbols(UnderlyingMethodBase.GetGenericArguments()); - } - - /// - public System.Reflection.MethodImplAttributes GetMethodImplementationFlags() - { - return UnderlyingMethodBase.GetMethodImplementationFlags(); - } - - /// - public IParameterSymbol[] GetParameters() - { - return ResolveParameterSymbols(UnderlyingMethodBase.GetParameters()); - } - - #endregion - - /// - public override void OnComplete() - { - foreach (var i in GetGenericArguments()) - if (i is IReflectionGenericTypeParameterSymbolBuilder b) - b.OnComplete(); - - base.OnComplete(); - } - - } - -} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs index c43c26618..2dc1d53f1 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs @@ -1,22 +1,23 @@ using System; +using System.Collections.Generic; +using System.Linq; using System.Reflection; using System.Reflection.Emit; +using IKVM.CoreLib.Reflection; using IKVM.CoreLib.Symbols.Emit; namespace IKVM.CoreLib.Symbols.Reflection.Emit { - class ReflectionMethodSymbolBuilder : ReflectionMethodBaseSymbolBuilder, IReflectionMethodSymbolBuilder + class ReflectionMethodSymbolBuilder : ReflectionMethodSymbol, IReflectionMethodSymbolBuilder { readonly MethodBuilder _builder; MethodInfo? _method; - ReflectionGenericTypeParameterTable _genericTypeParameterTable; - ReflectionMethodSpecTable _specTable; - ReflectionILGenerator? _il; + List? _incompleteCustomAttributes; /// /// Initializes a new instance. @@ -27,103 +28,43 @@ class ReflectionMethodSymbolBuilder : ReflectionMethodBaseSymbolBuilder, IReflec /// /// public ReflectionMethodSymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbolBuilder resolvingModule, IReflectionTypeSymbolBuilder? resolvingType, MethodBuilder builder) : - base(context, resolvingModule, resolvingType) + base(context, resolvingModule, resolvingType, builder) { - _builder = builder ?? throw new ArgumentNullException(nameof(builder)); - _genericTypeParameterTable = new ReflectionGenericTypeParameterTable(context, resolvingModule, this); - _specTable = new ReflectionMethodSpecTable(context, resolvingModule, resolvingType, this); + _builder = builder; } - /// - public MethodInfo UnderlyingMethod => _method ?? _builder; - - /// - public MethodInfo UnderlyingEmitMethod => _builder; - - /// - public MethodInfo UnderlyingDynamicEmitMethod => _method ?? throw new InvalidOperationException(); - - /// - public override MethodBase UnderlyingMethodBase => UnderlyingMethod; - - /// - public override MethodBase UnderlyingEmitMethodBase => UnderlyingEmitMethod; - /// public MethodBuilder UnderlyingMethodBuilder => _builder; - #region IReflectionMethodSymbolBuilder - /// - public IReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeParameterSymbol(GenericTypeParameterBuilder genericTypeParameter) - { - return _genericTypeParameterTable.GetOrCreateGenericTypeParameterSymbol(genericTypeParameter); - } - - #endregion - - #region IReflectionMethodSymbol - - /// - public IReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type genericTypeParameter) - { - return _genericTypeParameterTable.GetOrCreateGenericTypeParameterSymbol(genericTypeParameter); - } - - /// - public IReflectionMethodSymbol GetOrCreateGenericMethodSymbol(MethodInfo method) - { - return _specTable.GetOrCreateGenericMethodSymbol(ResolveTypeSymbols(method.GetGenericArguments())); - } - - #endregion - - #region IReflectionMethodBaseSymbol - - #endregion - - #region IReflectionMethodBaseSymbolBuilder - - #endregion + public override MethodInfo UnderlyingRuntimeMethod => _method ?? throw new InvalidOperationException(); #region IMethodBaseSymbolBuilder /// - public override void SetImplementationFlags(System.Reflection.MethodImplAttributes attributes) + public void SetImplementationFlags(System.Reflection.MethodImplAttributes attributes) { UnderlyingMethodBuilder.SetImplementationFlags((MethodImplAttributes)attributes); } /// - public override IParameterSymbolBuilder DefineParameter(int position, System.Reflection.ParameterAttributes attributes, string? strParamName) + public IParameterSymbolBuilder DefineParameter(int position, System.Reflection.ParameterAttributes attributes, string? strParamName) { return ResolveParameterSymbol(this, UnderlyingMethodBuilder.DefineParameter(position, (ParameterAttributes)attributes, strParamName)); } /// - public override IILGenerator GetILGenerator() + public IILGenerator GetILGenerator() { return _il ??= new ReflectionILGenerator(Context, UnderlyingMethodBuilder.GetILGenerator()); } /// - public override IILGenerator GetILGenerator(int streamSize) + public IILGenerator GetILGenerator(int streamSize) { return _il ??= new ReflectionILGenerator(Context, UnderlyingMethodBuilder.GetILGenerator(streamSize)); } - /// - public override void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) - { - UnderlyingMethodBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); - } - - /// - public override void SetCustomAttribute(ICustomAttributeBuilder customBuilder) - { - UnderlyingMethodBuilder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); - } - #endregion #region IMethodSymbolBuilder @@ -161,43 +102,76 @@ public IGenericTypeParameterSymbolBuilder[] DefineGenericParameters(params strin #region IMethodSymbol /// - public IParameterSymbol ReturnParameter => ResolveParameterSymbol(UnderlyingMethod.ReturnParameter); + public override bool IsComplete => _method != null; - /// - public ITypeSymbol ReturnType => ResolveTypeSymbol(UnderlyingMethod.ReturnType); + public IReflectionModuleSymbolBuilder ResolvingModuleBuilder => throw new NotImplementedException(); - /// - public ICustomAttributeProvider ReturnTypeCustomAttributes => throw new NotImplementedException(); + #endregion + + #region ICustomAttributeProviderBuilder /// - public override bool IsComplete => _method != null; + public void SetCustomAttribute(CustomAttribute attribute) + { + UnderlyingMethodBuilder.SetCustomAttribute(attribute.Unpack()); + _incompleteCustomAttributes ??= []; + _incompleteCustomAttributes.Add(attribute); + } + + #endregion + + #region ICustomAttributeProvider /// - public IMethodSymbol GetBaseDefinition() + public override CustomAttribute[] GetCustomAttributes(bool inherit = false) { - return ResolveMethodSymbol(UnderlyingMethod.GetBaseDefinition()); + if (IsComplete) + return ResolveCustomAttributes(UnderlyingRuntimeMethod.GetCustomAttributesData(inherit).ToArray()); + else if (inherit == false || GetBaseDefinition() == null) + return _incompleteCustomAttributes?.ToArray() ?? []; + else + return Enumerable.Concat(_incompleteCustomAttributes?.ToArray() ?? [], ResolveCustomAttributes(GetBaseDefinition().Unpack().GetInheritedCustomAttributesData())).ToArray(); } /// - public IMethodSymbol GetGenericMethodDefinition() + public override CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) { - return ResolveMethodSymbol(UnderlyingMethod.GetGenericMethodDefinition()); + if (IsComplete) + { + var _attributeType = attributeType.Unpack(); + return ResolveCustomAttributes(UnderlyingRuntimeMethod.GetCustomAttributesData().Where(i => i.AttributeType == _attributeType).ToArray()); + } + else + return GetCustomAttributes(inherit).Where(i => i.AttributeType == attributeType).ToArray(); } /// - public IMethodSymbol MakeGenericMethod(params ITypeSymbol[] typeArguments) + public override CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) { - return ResolveMethodSymbol(UnderlyingMethod.MakeGenericMethod(typeArguments.Unpack())); + if (IsComplete) + { + var _attributeType = attributeType.Unpack(); + return ResolveCustomAttribute(UnderlyingRuntimeMethod.GetCustomAttributesData().FirstOrDefault(i => i.AttributeType == _attributeType)); + } + else + return GetCustomAttributes(inherit).FirstOrDefault(i => i.AttributeType == attributeType); } #endregion /// - public override void OnComplete() + public void OnComplete() { _method = (MethodInfo?)ResolvingModule.UnderlyingModule.ResolveMethod(MetadataToken) ?? throw new InvalidOperationException(); - base.OnComplete(); + _incompleteCustomAttributes = null; + + // apply the runtime generic type parameters + var genericTypeParameters = ResolveTypeSymbols(UnderlyingRuntimeMethod.GetGenericArguments()) ?? []; + for (int i = 0; i < genericTypeParameters.Length; i++) + if (genericTypeParameters[i] is IReflectionGenericTypeParameterSymbolBuilder b) + b.OnComplete(genericTypeParameters[i].UnderlyingRuntimeType); } + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionModuleSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionModuleSymbolBuilder.cs index 9882c333a..527bd3f7b 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionModuleSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionModuleSymbolBuilder.cs @@ -1,27 +1,20 @@ using System; using System.Diagnostics.SymbolStore; using System.IO; -using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Resources; -using IKVM.CoreLib.Reflection; using IKVM.CoreLib.Symbols.Emit; namespace IKVM.CoreLib.Symbols.Reflection.Emit { - class ReflectionModuleSymbolBuilder : ReflectionSymbolBuilder, IReflectionModuleSymbolBuilder + class ReflectionModuleSymbolBuilder : ReflectionModuleSymbol, IReflectionModuleSymbolBuilder { - readonly IReflectionAssemblySymbol _resolvingAssembly; - Module _module; - ModuleBuilder? _builder; - - ReflectionTypeTable _typeTable; - ReflectionMethodTable _methodTable; - ReflectionFieldTable _fieldTable; + readonly ModuleBuilder _builder; + Module? _module; /// /// Initializes a new instance. @@ -31,173 +24,47 @@ class ReflectionModuleSymbolBuilder : ReflectionSymbolBuilder, IReflectionModule /// /// public ReflectionModuleSymbolBuilder(ReflectionSymbolContext context, IReflectionAssemblySymbol resolvingAssembly, ModuleBuilder builder) : - base(context) + base(context, resolvingAssembly, builder) { - _resolvingAssembly = resolvingAssembly ?? throw new ArgumentNullException(nameof(resolvingAssembly)); _builder = builder ?? throw new ArgumentNullException(nameof(builder)); - _module = _builder; - - _typeTable = new ReflectionTypeTable(context, this, null); - _methodTable = new ReflectionMethodTable(context, this, null); - _fieldTable = new ReflectionFieldTable(context, this, null); } - /// - public Module UnderlyingModule => _module; - /// public ModuleBuilder UnderlyingModuleBuilder => _builder ?? throw new InvalidOperationException(); /// - public IReflectionAssemblySymbol ResolvingAssembly => _resolvingAssembly; - - #region IReflectionModuleSymbol + public override Module UnderlyingRuntimeModule => _module ?? throw new InvalidOperationException(); - /// - public IReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) - { - if (type.IsTypeDefinition()) - return _typeTable.GetOrCreateTypeSymbol(type); - else if (type.IsGenericType) - return ResolveTypeSymbol(type.GetGenericTypeDefinition()).GetOrCreateGenericTypeSymbol(ResolveTypeSymbols(type.GetGenericArguments())); - else if (type.IsSZArray()) - return ResolveTypeSymbol(type.GetElementType()!).GetOrCreateSZArrayTypeSymbol(); - else if (type.IsArray) - return ResolveTypeSymbol(type.GetElementType()!).GetOrCreateArrayTypeSymbol(type.GetArrayRank()); - else if (type.IsPointer) - return ResolveTypeSymbol(type.GetElementType()!).GetOrCreatePointerTypeSymbol(); - else if (type.IsByRef) - return ResolveTypeSymbol(type.GetElementType()!).GetOrCreateByRefTypeSymbol(); - else if (type.IsGenericParameter && type.DeclaringMethod is MethodInfo dm) - return ResolveMethodSymbol(dm).GetOrCreateGenericTypeParameterSymbol(type); - else if (type.IsGenericParameter) - return ResolveTypeSymbol(type.DeclaringType!).GetOrCreateGenericTypeParameterSymbol(type); - else - throw new InvalidOperationException(); - } - - /// - public IReflectionTypeSymbolBuilder GetOrCreateTypeSymbol(TypeBuilder type) - { - return (IReflectionTypeSymbolBuilder)_typeTable.GetOrCreateTypeSymbol((Type)type); - } - - /// - public IReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method) - { - if (method.DeclaringType is { } dt) - return ResolveTypeSymbol(dt).GetOrCreateMethodBaseSymbol(method); - else - return _methodTable.GetOrCreateMethodBaseSymbol(method); - } - - /// - public IReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) - { - return ResolveTypeSymbol(ctor.DeclaringType!).GetOrCreateConstructorSymbol(ctor); - } - - /// - public IReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor) - { - return ResolveTypeSymbol((TypeBuilder)ctor.DeclaringType!).GetOrCreateConstructorSymbol(ctor); - } - - /// - public IReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) - { - if (method.DeclaringType is { } dt) - return ResolveTypeSymbol(dt).GetOrCreateMethodSymbol(method); - else - return _methodTable.GetOrCreateMethodSymbol(method); - } - - /// - public IReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method) - { - if (method.DeclaringType is { } dt) - return ResolveTypeSymbol((TypeBuilder)dt).GetOrCreateMethodSymbol(method); - else - return _methodTable.GetOrCreateMethodSymbol(method); - } - - /// - public IReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) - { - if (field.DeclaringType is { } dt) - return ResolveTypeSymbol(dt).GetOrCreateFieldSymbol(field); - else - return _fieldTable.GetOrCreateFieldSymbol(field); - } - - /// - public IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field) - { - if (field.DeclaringType is { } dt) - return ResolveTypeSymbol((TypeBuilder)dt).GetOrCreateFieldSymbol(field); - else - return _fieldTable.GetOrCreateFieldSymbol(field); - } - - /// - public IReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) - { - return ResolveTypeSymbol(property.DeclaringType!).GetOrCreatePropertySymbol(property); - } + #region IModuleSymbol /// - public IReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property) - { - return ResolveTypeSymbol(property.GetTypeBuilder()).GetOrCreatePropertySymbol(property); - } + public override bool IsComplete => _module != null; - /// - public IReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) - { - return ResolveTypeSymbol(@event.DeclaringType!).GetOrCreateEventSymbol(@event); - } + #endregion - /// - public IReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event) - { - return ResolveTypeSymbol(@event.GetTypeBuilder()).GetOrCreateEventSymbol(@event); - } + #region IModuleSymbolBuilder /// - public IReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) + public ulong ImageBase { - return ResolveMemberSymbol(parameter.Member) switch - { - IReflectionMethodBaseSymbol method => method.GetOrCreateParameterSymbol(parameter), - IReflectionPropertySymbol property => property.GetOrCreateParameterSymbol(parameter), - _ => throw new InvalidOperationException(), - }; + get => throw new NotSupportedException(); + set => throw new NotSupportedException(); } /// - public IReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(IReflectionMemberSymbolBuilder member, ParameterBuilder parameter) + public uint FileAlignment { - return member switch - { - IReflectionMethodBaseSymbolBuilder method => method.GetOrCreateParameterSymbol(parameter), - IReflectionPropertySymbolBuilder property => property.GetOrCreateParameterSymbol(parameter), - _ => throw new InvalidOperationException(), - }; + get => throw new NotSupportedException(); + set => throw new NotSupportedException(); } /// - public IReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeParameterSymbol(GenericTypeParameterBuilder genericParameterType) + public System.Reflection.PortableExecutable.DllCharacteristics DllCharacteristics { - if (genericParameterType.DeclaringMethod is MethodBuilder dm) - return ResolveMethodSymbol(dm).GetOrCreateGenericTypeParameterSymbol(genericParameterType); - else - return ResolveTypeSymbol((TypeBuilder)genericParameterType.DeclaringType!).GetOrCreateGenericTypeParameterSymbol(genericParameterType); + get => throw new NotSupportedException(); + set => throw new NotSupportedException(); } - #endregion - - #region IModuleSymbolBuilder - /// public ISymbolDocumentWriter? DefineDocument(string url, Guid language, Guid languageVendor, Guid documentType) { @@ -299,15 +166,9 @@ public ITypeSymbolBuilder DefineType(string name, System.Reflection.TypeAttribut } /// - public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) - { - UnderlyingModuleBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); - } - - /// - public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) + public void SetCustomAttribute(CustomAttribute attribute) { - UnderlyingModuleBuilder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); + UnderlyingModuleBuilder.SetCustomAttribute(attribute.Unpack()); } /// @@ -331,7 +192,7 @@ public void Complete() if (type is IReflectionTypeSymbolBuilder t) t.Complete(); - _builder = null; + _module = _builder; } /// @@ -342,222 +203,6 @@ public void Save(System.Reflection.PortableExecutableKinds portableExecutableKin #endregion - #region IModuleSymbol - - /// - public IAssemblySymbol Assembly => ResolveAssemblySymbol(UnderlyingModule.Assembly); - - /// - public string FullyQualifiedName => UnderlyingModule.FullyQualifiedName; - - /// - public int MetadataToken => UnderlyingModule.MetadataToken; - - /// - public Guid ModuleVersionId => UnderlyingModule.ModuleVersionId; - - /// - public string Name => UnderlyingModule.Name; - - /// - public string ScopeName => UnderlyingModule.ScopeName; - - /// - public ulong ImageBase - { - get => throw new NotSupportedException(); - set => throw new NotSupportedException(); - } - - /// - public uint FileAlignment - { - get => throw new NotSupportedException(); - set => throw new NotSupportedException(); - } - - /// - public System.Reflection.PortableExecutable.DllCharacteristics DllCharacteristics - { - get => throw new NotSupportedException(); - set => throw new NotSupportedException(); - } - - /// - public override bool IsComplete => _builder == null; - - /// - public IFieldSymbol? GetField(string name) - { - return ResolveFieldSymbol(UnderlyingModule.GetField(name)); - } - - /// - public IFieldSymbol? GetField(string name, System.Reflection.BindingFlags bindingAttr) - { - return ResolveFieldSymbol(UnderlyingModule.GetField(name, (BindingFlags)bindingAttr)); - } - - /// - public IFieldSymbol[] GetFields(System.Reflection.BindingFlags bindingFlags) - { - return ResolveFieldSymbols(UnderlyingModule.GetFields((BindingFlags)bindingFlags))!; - } - - /// - public IFieldSymbol[] GetFields() - { - return ResolveFieldSymbols(UnderlyingModule.GetFields())!; - } - - /// - public IMethodSymbol? GetMethod(string name) - { - return ResolveMethodSymbol(UnderlyingModule.GetMethod(name)); - } - - /// - public IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) - { - return ResolveMethodSymbol(UnderlyingModule.GetMethod(name, types.Unpack())); - } - - /// - public IMethodSymbol? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.CallingConventions callConvention, ITypeSymbol[] types, System.Reflection.ParameterModifier[]? modifiers) - { - return ResolveMethodSymbol(UnderlyingModule.GetMethod(name, (BindingFlags)bindingAttr, null, (CallingConventions)callConvention, types.Unpack(), modifiers?.Unpack())); - } - - /// - public IMethodSymbol[] GetMethods() - { - return ResolveMethodSymbols(UnderlyingModule.GetMethods())!; - } - - /// - public IMethodSymbol[] GetMethods(System.Reflection.BindingFlags bindingFlags) - { - return ResolveMethodSymbols(UnderlyingModule.GetMethods((BindingFlags)bindingFlags))!; - } - - /// - public ITypeSymbol? GetType(string className) - { - return ResolveTypeSymbol(UnderlyingModule.GetType(className)); - } - - /// - public ITypeSymbol? GetType(string className, bool ignoreCase) - { - return ResolveTypeSymbol(UnderlyingModule.GetType(className, ignoreCase)); - } - - /// - public ITypeSymbol? GetType(string className, bool throwOnError, bool ignoreCase) - { - return ResolveTypeSymbol(UnderlyingModule.GetType(className, throwOnError, ignoreCase)); - } - - /// - public ITypeSymbol[] GetTypes() - { - return ResolveTypeSymbols(UnderlyingModule.GetTypes())!; - } - - /// - public bool IsResource() - { - return UnderlyingModule.IsResource(); - } - - /// - public IFieldSymbol? ResolveField(int metadataToken) - { - return ResolveFieldSymbol(UnderlyingModule.ResolveField(metadataToken)); - } - - /// - public IFieldSymbol? ResolveField(int metadataToken, ITypeSymbol[]? genericTypeArguments, ITypeSymbol[]? genericMethodArguments) - { - return ResolveFieldSymbol(UnderlyingModule.ResolveField(metadataToken, genericTypeArguments?.Unpack(), genericMethodArguments?.Unpack())); - } - - /// - public IMemberSymbol? ResolveMember(int metadataToken) - { - return ResolveMemberSymbol(UnderlyingModule.ResolveMember(metadataToken)); - } - - /// - public IMemberSymbol? ResolveMember(int metadataToken, ITypeSymbol[]? genericTypeArguments, ITypeSymbol[]? genericMethodArguments) - { - return ResolveMemberSymbol(UnderlyingModule.ResolveMember(metadataToken, genericTypeArguments?.Unpack(), genericMethodArguments?.Unpack())); - } - - /// - public IMethodBaseSymbol? ResolveMethod(int metadataToken, ITypeSymbol[]? genericTypeArguments, ITypeSymbol[]? genericMethodArguments) - { - return ResolveMethodBaseSymbol(UnderlyingModule.ResolveMethod(metadataToken, genericTypeArguments?.Unpack(), genericMethodArguments?.Unpack())); - } - - /// - public IMethodBaseSymbol? ResolveMethod(int metadataToken) - { - return ResolveMethodBaseSymbol(UnderlyingModule.ResolveMethod(metadataToken)); - } - - /// - public byte[] ResolveSignature(int metadataToken) - { - return UnderlyingModule.ResolveSignature(metadataToken); - } - - /// - public string ResolveString(int metadataToken) - { - return UnderlyingModule.ResolveString(metadataToken); - } - - /// - public ITypeSymbol ResolveType(int metadataToken) - { - return ResolveTypeSymbol(UnderlyingModule.ResolveType(metadataToken)); - } - - /// - public ITypeSymbol ResolveType(int metadataToken, ITypeSymbol[]? genericTypeArguments, ITypeSymbol[]? genericMethodArguments) - { - return ResolveTypeSymbol(UnderlyingModule.ResolveType(metadataToken, genericTypeArguments?.Unpack(), genericMethodArguments?.Unpack())); - } - - /// - public CustomAttribute[] GetCustomAttributes(bool inherit = false) - { - return ResolveCustomAttributes(UnderlyingModule.GetCustomAttributesData()); - } - - /// - public virtual CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) - { - var _attributeType = attributeType.Unpack(); - return ResolveCustomAttributes(UnderlyingModule.GetCustomAttributesData().Where(i => i.AttributeType == _attributeType).ToArray()); - } - - /// - public virtual CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) - { - var _attributeType = attributeType.Unpack(); - return ResolveCustomAttribute(UnderlyingModule.GetCustomAttributesData().Where(i => i.AttributeType == _attributeType).FirstOrDefault()); - } - - /// - public bool IsDefined(ITypeSymbol attributeType, bool inherit = false) - { - return UnderlyingModule.IsDefined(attributeType.Unpack(), false); - } - - #endregion - } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionParameterSymbolBuilder.cs index 760ce9921..47c5ee036 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionParameterSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionParameterSymbolBuilder.cs @@ -16,7 +16,7 @@ class ReflectionParameterSymbolBuilder : ReflectionSymbolBuilder, IReflectionPar readonly ParameterBuilder _builder; readonly ReflectionParameterBuilderInfo _builderInfo; - ParameterInfo _parameter; + ParameterInfo? _parameter; object? _constant; @@ -37,19 +37,19 @@ public ReflectionParameterSymbolBuilder(ReflectionSymbolContext context, IReflec } /// - public IReflectionModuleSymbol ResolvingModule => _module; + public ParameterBuilder UnderlyingParameterBuilder => _builder; /// - public IReflectionMemberSymbol ResolvingMember => _member; + public ParameterInfo UnderlyingParameter => _builderInfo; /// - public ParameterInfo UnderlyingParameter => _parameter ?? _builderInfo; + public ParameterInfo UnderlyingRuntimeParameter => _parameter ?? throw new InvalidOperationException(); /// - public ParameterInfo UnderlyingEmitParameter => _parameter ?? throw new InvalidOperationException(); + public IReflectionModuleSymbol ResolvingModule => _module; /// - public ParameterBuilder UnderlyingParameterBuilder => _builder; + public IReflectionMemberSymbol ResolvingMember => _member; #region IParameterSymbolBuilder @@ -60,15 +60,9 @@ public void SetConstant(object? defaultValue) } /// - public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) - { - UnderlyingParameterBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); - } - - /// - public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) + public void SetCustomAttribute(CustomAttribute attribute) { - UnderlyingParameterBuilder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); + UnderlyingParameterBuilder.SetCustomAttribute(attribute.Unpack()); } #endregion diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionPropertySymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionPropertySymbolBuilder.cs index d25067236..3fa9773c6 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionPropertySymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionPropertySymbolBuilder.cs @@ -7,14 +7,12 @@ namespace IKVM.CoreLib.Symbols.Reflection.Emit { - class ReflectionPropertySymbolBuilder : ReflectionMemberSymbolBuilder, IReflectionPropertySymbolBuilder + class ReflectionPropertySymbolBuilder : ReflectionPropertySymbol, IReflectionPropertySymbolBuilder { - PropertyBuilder _builder; + readonly PropertyBuilder _builder; PropertyInfo? _property; - ReflectionParameterTable _parameterTable; - /// /// Initializes a new instance. /// @@ -24,44 +22,34 @@ class ReflectionPropertySymbolBuilder : ReflectionMemberSymbolBuilder, IReflecti /// /// public ReflectionPropertySymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbolBuilder resolvingModule, IReflectionTypeSymbolBuilder resolvingType, PropertyBuilder builder) : - base(context, resolvingModule, resolvingType) + base(context, resolvingModule, resolvingType, builder) { _builder = builder ?? throw new ArgumentNullException(nameof(builder)); - _parameterTable = new ReflectionParameterTable(context, resolvingModule, this); } - /// - public PropertyInfo UnderlyingProperty => _property ?? _builder; - - /// - public PropertyInfo UnderlyingEmitProperty => UnderlyingProperty; - /// public PropertyBuilder UnderlyingPropertyBuilder => _builder ?? throw new InvalidOperationException(); /// - public override MemberInfo UnderlyingMember => UnderlyingProperty; + public override PropertyInfo UnderlyingRuntimeProperty => _property ?? throw new InvalidOperationException(); /// - public override MemberInfo UnderlyingEmitMember => UnderlyingEmitProperty; + public IReflectionModuleSymbolBuilder ResolvingModuleBuilder => (IReflectionModuleSymbolBuilder)ResolvingModule; - #region IReflectionPropertySymbolBuilder + #region ICustomAttributeProviderBuilder /// - public IReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter) + public void SetCustomAttribute(CustomAttribute attribute) { - return _parameterTable.GetOrCreateParameterSymbol(parameter); + UnderlyingPropertyBuilder.SetCustomAttribute(attribute.Unpack()); } #endregion - #region IReflectionPropertySymbol + #region IPropertySymbol /// - public IReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) - { - return _parameterTable.GetOrCreateParameterSymbol(parameter); - } + public override bool IsComplete => _property != null; #endregion @@ -91,119 +79,12 @@ public void AddOtherMethod(IMethodSymbolBuilder mdBuilder) UnderlyingPropertyBuilder.AddOtherMethod(((IReflectionMethodSymbolBuilder)mdBuilder).UnderlyingMethodBuilder); } - /// - public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) - { - UnderlyingPropertyBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); - } - - /// - public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) - { - UnderlyingPropertyBuilder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); - } - - #endregion - - #region IPropertySymbol - - /// - public System.Reflection.PropertyAttributes Attributes => (System.Reflection.PropertyAttributes)UnderlyingProperty.Attributes; - - /// - public bool CanRead => UnderlyingProperty.CanRead; - - /// - public bool CanWrite => UnderlyingProperty.CanWrite; - - /// - public bool IsSpecialName => UnderlyingProperty.IsSpecialName; - - /// - public ITypeSymbol PropertyType => ResolveTypeSymbol(UnderlyingProperty.PropertyType); - - /// - public IMethodSymbol? GetMethod => ResolveMethodSymbol(UnderlyingProperty.GetMethod); - - /// - public IMethodSymbol? SetMethod => ResolveMethodSymbol(UnderlyingProperty.SetMethod); - - /// - public override bool IsComplete => _property != null; - - /// - public object? GetRawConstantValue() - { - return UnderlyingProperty.GetRawConstantValue(); - } - - /// - public IMethodSymbol[] GetAccessors() - { - return ResolveMethodSymbols(UnderlyingProperty.GetAccessors()); - } - - /// - public IMethodSymbol[] GetAccessors(bool nonPublic) - { - return ResolveMethodSymbols(UnderlyingProperty.GetAccessors(nonPublic)); - } - - /// - public IParameterSymbol[] GetIndexParameters() - { - return ResolveParameterSymbols(UnderlyingProperty.GetIndexParameters()); - } - - /// - public IMethodSymbol? GetGetMethod() - { - return ResolveMethodSymbol(UnderlyingProperty.GetGetMethod()); - } - - /// - public IMethodSymbol? GetGetMethod(bool nonPublic) - { - return ResolveMethodSymbol(UnderlyingProperty.GetGetMethod(nonPublic)); - } - - /// - public IMethodSymbol? GetSetMethod() - { - return ResolveMethodSymbol(UnderlyingProperty.GetSetMethod()); - } - - /// - public IMethodSymbol? GetSetMethod(bool nonPublic) - { - return ResolveMethodSymbol(UnderlyingProperty.GetSetMethod(nonPublic)); - } - - /// - public ITypeSymbol GetModifiedPropertyType() - { - throw new NotImplementedException(); - } - - /// - public ITypeSymbol[] GetOptionalCustomModifiers() - { - return ResolveTypeSymbols(UnderlyingProperty.GetOptionalCustomModifiers()); - } - - /// - public ITypeSymbol[] GetRequiredCustomModifiers() - { - return ResolveTypeSymbols(UnderlyingProperty.GetRequiredCustomModifiers()); - } - #endregion /// - public override void OnComplete() + public void OnComplete() { _property = (PropertyInfo?)ResolvingModule.UnderlyingModule.ResolveMember(MetadataToken) ?? throw new InvalidOperationException(); - base.OnComplete(); } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionSymbolBuilder.cs index a21ac8944..aff7f0300 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionSymbolBuilder.cs @@ -1,7 +1,4 @@ -using System.Diagnostics.CodeAnalysis; -using System.Reflection.Emit; - -using IKVM.CoreLib.Symbols.Emit; +using IKVM.CoreLib.Symbols.Emit; namespace IKVM.CoreLib.Symbols.Reflection.Emit { @@ -22,13 +19,6 @@ protected ReflectionSymbolBuilder(ReflectionSymbolContext context) : } - /// - [return: NotNullIfNotNull(nameof(genericTypeParameter))] - public IReflectionGenericTypeParameterSymbolBuilder? ResolveGenericTypeParameterSymbol(GenericTypeParameterBuilder genericTypeParameter) - { - return Context.GetOrCreateGenericTypeParameterSymbol(genericTypeParameter); - } - } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs index df41d1cb6..9130e6a35 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs @@ -1,11 +1,12 @@ using System; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; +using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.InteropServices; +using IKVM.CoreLib.Reflection; using IKVM.CoreLib.Symbols.Emit; namespace IKVM.CoreLib.Symbols.Reflection.Emit @@ -18,6 +19,7 @@ class ReflectionTypeSymbolBuilder : ReflectionTypeSymbolBase, IReflectionTypeSym Type? _type; List? _incompleteMethods; + List? _incompleteCustomAttributes; /// /// Initializes a new instance. @@ -31,65 +33,17 @@ public ReflectionTypeSymbolBuilder(ReflectionSymbolContext context, IReflectionM _builder = builder ?? throw new ArgumentNullException(nameof(builder)); } - /// - public override Type UnderlyingType => UnderlyingTypeBuilder; - - /// - public override Type UnderlyingEmitType => UnderlyingTypeBuilder; - - /// - public override Type UnderlyingDynamicEmitType => _type ?? throw new InvalidOperationException(); - /// public TypeBuilder UnderlyingTypeBuilder => _builder; /// - public IReflectionModuleSymbolBuilder ResolvingModuleBuilder => (IReflectionModuleSymbolBuilder)ResolvingModule; - - #region IReflectionSymbolBuilder - - /// - [return: NotNullIfNotNull("genericTypeParameter")] - public IReflectionGenericTypeParameterSymbolBuilder? ResolveGenericTypeParameterSymbol(GenericTypeParameterBuilder genericTypeParameter) - { - return Context.GetOrCreateGenericTypeParameterSymbol(genericTypeParameter); - } - - #endregion - - #region IReflectionTypeSymbolBuilder - - /// - public IReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor) - { - return _methodTable.GetOrCreateConstructorSymbol(ctor); - } + public override Type UnderlyingType => _builder; /// - public IReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method) - { - return _methodTable.GetOrCreateMethodSymbol(method); - } + public override Type UnderlyingRuntimeType => _type ?? throw new InvalidOperationException(); /// - public IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field) - { - return _fieldTable.GetOrCreateFieldSymbol(field); - } - - /// - public IReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property) - { - return _propertyTable.GetOrCreatePropertySymbol(property); - } - - /// - public IReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event) - { - return _eventTable.GetOrCreateEventSymbol(@event); - } - - #endregion + public IReflectionModuleSymbolBuilder ResolvingModuleBuilder => (IReflectionModuleSymbolBuilder)ResolvingModule; #region ITypeSymbolBuilder @@ -298,20 +252,22 @@ public IConstructorSymbolBuilder DefineTypeInitializer() { return (IConstructorSymbolBuilder)ResolveConstructorSymbol(UnderlyingTypeBuilder.DefineTypeInitializer()); } - /// - public void SetCustomAttribute(IConstructorSymbol con, byte[] binaryAttribute) - { - UnderlyingTypeBuilder.SetCustomAttribute(con.Unpack(), binaryAttribute); - } /// - public void SetCustomAttribute(ICustomAttributeBuilder customBuilder) + public void SetCustomAttribute(CustomAttribute attribute) { - UnderlyingTypeBuilder.SetCustomAttribute(((ReflectionCustomAttributeBuilder)customBuilder).UnderlyingBuilder); + UnderlyingTypeBuilder.SetCustomAttribute(attribute.Unpack()); + _incompleteCustomAttributes ??= []; + _incompleteCustomAttributes.Add(attribute); } #endregion + #region ITypeSymbol + + /// + public override bool IsComplete => _type != null; + /// public override IMethodSymbol? GetMethod(string name) { @@ -369,8 +325,34 @@ IMethodSymbol[] GetIncompleteMethods(BindingFlags bindingAttr = BindingFlags.Pub return SymbolUtil.FilterMethods(this, _incompleteMethods, bindingAttr).Cast().ToArray(); } + #endregion + + #region ICustomAttributeProvider + /// - public override bool IsComplete => _type != null; + public override CustomAttribute[] GetCustomAttributes(bool inherit = false) + { + if (IsComplete) + return ResolveCustomAttributes(UnderlyingRuntimeMember.GetCustomAttributesData(inherit).ToArray()); + else if (inherit == false || BaseType == null) + return _incompleteCustomAttributes?.ToArray() ?? []; + else + return Enumerable.Concat(_incompleteCustomAttributes?.ToArray() ?? [], ResolveCustomAttributes(BaseType.Unpack().GetInheritedCustomAttributesData())).ToArray(); + } + + /// + public override CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) + { + return GetCustomAttributes(inherit).FirstOrDefault(i => i.AttributeType == attributeType); + } + + /// + public override CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) + { + return GetCustomAttributes(inherit).Where(i => i.AttributeType == attributeType).ToArray(); + } + + #endregion /// public void Complete() @@ -379,7 +361,11 @@ public void Complete() { // complete type if (_builder.IsCreated() == false) - _type = _builder.CreateType()!; + { + _type = _builder.CreateType() ?? throw new InvalidOperationException(); + _incompleteMethods = null; + _incompleteCustomAttributes = null; + } // force module to reresolve Context.GetOrCreateModuleSymbol(ResolvingModule.UnderlyingModule); @@ -392,9 +378,13 @@ public void OnComplete() { const BindingFlags DefaultBindingFlags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static; - foreach (var i in GetGenericArguments() ?? []) - if (i is IReflectionGenericTypeParameterSymbolBuilder b) - b.OnComplete(); + // apply the runtime generic type parameters and pass them to the symbols for completion + var srcGenericArgs = UnderlyingRuntimeType.GetGenericArguments() ?? []; + var dstGenericArgs = GetGenericArguments() ?? []; + Debug.Assert(srcGenericArgs.Length == dstGenericArgs.Length); + for (int i = 0; i < srcGenericArgs.Length; i++) + if (dstGenericArgs[i] is IReflectionGenericTypeParameterSymbolBuilder b) + b.OnComplete(srcGenericArgs[i]); foreach (var i in GetConstructors(DefaultBindingFlags) ?? []) if (i is IReflectionConstructorSymbolBuilder b) diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionAssemblySymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionAssemblySymbol.cs index b85865404..73a6c9c3c 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionAssemblySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionAssemblySymbol.cs @@ -11,6 +11,11 @@ interface IReflectionAssemblySymbol : IReflectionSymbol, IAssemblySymbol /// Assembly UnderlyingAssembly { get; } + /// + /// Gets a reference to the underlying . + /// + Assembly UnderlyingRuntimeAssembly { get; } + /// /// Gets or creates a for the specified . /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionConstructorSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionConstructorSymbol.cs index 43d116030..f477b99df 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionConstructorSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionConstructorSymbol.cs @@ -14,12 +14,7 @@ interface IReflectionConstructorSymbol : IReflectionMethodBaseSymbol, IConstruct /// /// Gets the underlying used for IL emit operations. /// - ConstructorInfo UnderlyingEmitConstructor { get; } - - /// - /// Gets the underlying used for IL emit operations against dynamic methods. - /// - ConstructorInfo UnderlyingDynamicEmitConstructor { get; } + ConstructorInfo UnderlyingRuntimeConstructor { get; } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionEventSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionEventSymbol.cs index f2c411fc9..2f0374c38 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionEventSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionEventSymbol.cs @@ -12,9 +12,9 @@ interface IReflectionEventSymbol : IReflectionMemberSymbol, IEventSymbol EventInfo UnderlyingEvent { get; } /// - /// Gets the underlying used for IL emit operations. + /// Gets the underlying . /// - EventInfo UnderlyingEmitEvent { get; } + EventInfo UnderlyingRuntimeEvent { get; } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionFieldSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionFieldSymbol.cs index 86094cd8d..e21b606ba 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionFieldSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionFieldSymbol.cs @@ -12,14 +12,9 @@ interface IReflectionFieldSymbol : IReflectionMemberSymbol, IFieldSymbol FieldInfo UnderlyingField { get; } /// - /// Gets the underlying used for IL emit operations. - /// - FieldInfo UnderlyingEmitField { get; } - - /// - /// Gets the underlying used for IL emit operations against dynamic methods. + /// Gets the underlying . /// - FieldInfo UnderlyingDynamicEmitField { get; } + FieldInfo UnderlyingRuntimeField { get; } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMemberSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMemberSymbol.cs index b62765637..b309b0ee0 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMemberSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMemberSymbol.cs @@ -22,9 +22,9 @@ interface IReflectionMemberSymbol : IReflectionSymbol, IMemberSymbol MemberInfo UnderlyingMember { get; } /// - /// Gets the underlying used for IL emit operations. + /// Gets the underlying used when the runtime information is required. /// - MemberInfo UnderlyingEmitMember { get; } + MemberInfo UnderlyingRuntimeMember { get; } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMethodBaseSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMethodBaseSymbol.cs index b46e914f7..f3e89783f 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMethodBaseSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMethodBaseSymbol.cs @@ -1,4 +1,7 @@ using System.Reflection; +using System.Reflection.Emit; + +using IKVM.CoreLib.Symbols.Reflection.Emit; namespace IKVM.CoreLib.Symbols.Reflection { @@ -14,7 +17,7 @@ interface IReflectionMethodBaseSymbol : IReflectionMemberSymbol, IMethodBaseSymb /// /// Gets the underlying . /// - MethodBase UnderlyingEmitMethodBase { get; } + MethodBase UnderlyingRuntimeMethodBase { get; } /// /// Gets or creates a for the given . @@ -23,6 +26,13 @@ interface IReflectionMethodBaseSymbol : IReflectionMemberSymbol, IMethodBaseSymb /// public IReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter); + /// + /// Gets or creates a for the given . + /// + /// + /// + public IReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter); + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMethodSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMethodSymbol.cs index 07cc3b253..21dfd7dcf 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMethodSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionMethodSymbol.cs @@ -1,5 +1,8 @@ using System; using System.Reflection; +using System.Reflection.Emit; + +using IKVM.CoreLib.Symbols.Reflection.Emit; namespace IKVM.CoreLib.Symbols.Reflection { @@ -13,21 +16,23 @@ interface IReflectionMethodSymbol : IReflectionMethodBaseSymbol, IMethodSymbol MethodInfo UnderlyingMethod { get; } /// - /// Gets the underlying used for IL emit operations. + /// Gets the underlying . /// - MethodInfo UnderlyingEmitMethod { get; } + MethodInfo UnderlyingRuntimeMethod { get; } /// - /// Gets the underlying used for IL emit operations against dynamic methods. + /// Gets or creates a for the given generic type parameter. /// - MethodInfo UnderlyingDynamicEmitMethod { get; } + /// + /// + IReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type genericTypeParameter); /// - /// Gets or creates a for the given generic type parameter. + /// Gets or creates a for the given . /// /// /// - IReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type genericTypeParameter); + IReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeParameterSymbol(GenericTypeParameterBuilder genericTypeParameter); /// /// Gets or creates a for the given generic version of this method definition. diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionModuleSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionModuleSymbol.cs index d91499c77..9b559b577 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionModuleSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionModuleSymbol.cs @@ -1,5 +1,8 @@ using System; using System.Reflection; +using System.Reflection.Emit; + +using IKVM.CoreLib.Symbols.Reflection.Emit; namespace IKVM.CoreLib.Symbols.Reflection { @@ -17,6 +20,11 @@ interface IReflectionModuleSymbol : IReflectionSymbol, IModuleSymbol /// Module UnderlyingModule { get; } + /// + /// Gets the underlying . + /// + Module UnderlyingRuntimeModule { get; } + /// /// Gets or creates a for the specified . /// @@ -24,6 +32,13 @@ interface IReflectionModuleSymbol : IReflectionSymbol, IModuleSymbol /// IReflectionTypeSymbol GetOrCreateTypeSymbol(Type type); + /// + /// Gets or creates a for the specified . + /// + /// + /// + IReflectionTypeSymbolBuilder GetOrCreateTypeSymbol(TypeBuilder type); + /// /// Gets or creates a for the specified . /// @@ -38,6 +53,13 @@ interface IReflectionModuleSymbol : IReflectionSymbol, IModuleSymbol /// IReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor); + /// + /// Gets or creates a for the specified . + /// + /// + /// + IReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor); + /// /// Gets or creates a for the specified . /// @@ -45,6 +67,13 @@ interface IReflectionModuleSymbol : IReflectionSymbol, IModuleSymbol /// IReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method); + /// + /// Gets or creates a for the specified . + /// + /// + /// + IReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method); + /// /// Gets or creates a for the specified . /// @@ -52,6 +81,13 @@ interface IReflectionModuleSymbol : IReflectionSymbol, IModuleSymbol /// IReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field); + /// + /// Gets or creates a for the specified . + /// + /// + /// + IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field); + /// /// Gets or creates a for the specified . /// @@ -59,6 +95,13 @@ interface IReflectionModuleSymbol : IReflectionSymbol, IModuleSymbol /// IReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property); + /// + /// Gets or creates a for the specified . + /// + /// + /// + IReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property); + /// /// Gets or creates a for the specified . /// @@ -66,6 +109,13 @@ interface IReflectionModuleSymbol : IReflectionSymbol, IModuleSymbol /// IReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event); + /// + /// Gets or creates a for the specified . + /// + /// + /// + IReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event); + /// /// Gets or creates a for the specified . /// @@ -73,6 +123,21 @@ interface IReflectionModuleSymbol : IReflectionSymbol, IModuleSymbol /// IReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter); + /// + /// Gets or creates a for the specified . + /// + /// + /// + /// + IReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(IReflectionMemberSymbolBuilder member, ParameterBuilder parameter); + + /// + /// Gets or creates a for the specified . + /// + /// + /// + IReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeParameterSymbol(GenericTypeParameterBuilder genericTypeParameter); + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionParameterSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionParameterSymbol.cs index 55d9de63c..3c0288354 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionParameterSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionParameterSymbol.cs @@ -22,9 +22,9 @@ interface IReflectionParameterSymbol : IReflectionSymbol, IParameterSymbol ParameterInfo UnderlyingParameter { get; } /// - /// Gets the underlying used for IL emit operations. + /// Gets the underlying . /// - ParameterInfo UnderlyingEmitParameter { get; } + ParameterInfo UnderlyingRuntimeParameter { get; } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionPropertySymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionPropertySymbol.cs index c1f545f79..12da5d1a9 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionPropertySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionPropertySymbol.cs @@ -1,4 +1,7 @@ using System.Reflection; +using System.Reflection.Emit; + +using IKVM.CoreLib.Symbols.Reflection.Emit; namespace IKVM.CoreLib.Symbols.Reflection { @@ -12,9 +15,9 @@ interface IReflectionPropertySymbol : IReflectionMemberSymbol, IPropertySymbol PropertyInfo UnderlyingProperty { get; } /// - /// Gets the underlying used for IL emit operations. + /// Gets the underlying . /// - PropertyInfo UnderlyingEmitProperty { get; } + PropertyInfo UnderlyingRuntimeProperty { get; } /// /// Gets or creates a for the given . @@ -23,6 +26,13 @@ interface IReflectionPropertySymbol : IReflectionMemberSymbol, IPropertySymbol /// public IReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter); + /// + /// Gets or creates a for the given . + /// + /// + /// + public IReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter); + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionSymbol.cs index c2a970c28..3928a4815 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionSymbol.cs @@ -3,6 +3,9 @@ using System.Collections.Immutable; using System.Diagnostics.CodeAnalysis; using System.Reflection; +using System.Reflection.Emit; + +using IKVM.CoreLib.Symbols.Reflection.Emit; namespace IKVM.CoreLib.Symbols.Reflection { @@ -31,6 +34,14 @@ interface IReflectionSymbol : ISymbol [return: NotNullIfNotNull(nameof(assemblies))] IReflectionAssemblySymbol[]? ResolveAssemblySymbols(Assembly[]? assemblies); + /// + /// Resolves the symbol for the specified assembly builder. + /// + /// + /// + [return: NotNullIfNotNull(nameof(assembly))] + IReflectionAssemblySymbolBuilder ResolveAssemblySymbol(AssemblyBuilder assembly); + /// /// Resolves the symbol for the specified module. /// @@ -54,6 +65,14 @@ interface IReflectionSymbol : ISymbol /// IEnumerable ResolveModuleSymbols(IEnumerable modules); + /// + /// Resolves the symbol for the specified module. + /// + /// + /// + [return: NotNullIfNotNull(nameof(module))] + IReflectionModuleSymbolBuilder ResolveModuleSymbol(ModuleBuilder module); + /// /// Resolves the symbol for the specified member. /// @@ -93,6 +112,14 @@ interface IReflectionSymbol : ISymbol /// IEnumerable ResolveTypeSymbols(IEnumerable types); + /// + /// Resolves the symbol for the specified type. + /// + /// + /// + [return: NotNullIfNotNull(nameof(type))] + IReflectionTypeSymbolBuilder ResolveTypeSymbol(TypeBuilder type); + /// /// Resolves the symbol for the specified method. /// @@ -117,6 +144,14 @@ interface IReflectionSymbol : ISymbol [return: NotNullIfNotNull(nameof(ctors))] IReflectionConstructorSymbol[]? ResolveConstructorSymbols(ConstructorInfo[]? ctors); + /// + /// Resolves the symbol for the specified constructor. + /// + /// + /// + [return: NotNullIfNotNull(nameof(ctor))] + IReflectionConstructorSymbolBuilder ResolveConstructorSymbol(ConstructorBuilder ctor); + /// /// Resolves the symbol for the specified method. /// @@ -133,6 +168,14 @@ interface IReflectionSymbol : ISymbol [return: NotNullIfNotNull(nameof(methods))] IReflectionMethodSymbol[]? ResolveMethodSymbols(MethodInfo[]? methods); + /// + /// Resolves the symbol for the specified method. + /// + /// + /// + [return: NotNullIfNotNull(nameof(method))] + IReflectionMethodSymbolBuilder ResolveMethodSymbol(MethodBuilder method); + /// /// Resolves the symbol for the specified field. /// @@ -149,6 +192,14 @@ interface IReflectionSymbol : ISymbol [return: NotNullIfNotNull(nameof(fields))] IReflectionFieldSymbol[]? ResolveFieldSymbols(FieldInfo[]? fields); + /// + /// Resolves the symbol for the specified field. + /// + /// + /// + [return: NotNullIfNotNull(nameof(field))] + IReflectionFieldSymbolBuilder ResolveFieldSymbol(FieldBuilder field); + /// /// Resolves the symbol for the specified property. /// @@ -165,6 +216,14 @@ interface IReflectionSymbol : ISymbol [return: NotNullIfNotNull(nameof(properties))] IReflectionPropertySymbol[]? ResolvePropertySymbols(PropertyInfo[]? properties); + /// + /// Resolves the symbol for the specified property. + /// + /// + /// + [return: NotNullIfNotNull(nameof(property))] + IReflectionPropertySymbolBuilder ResolvePropertySymbol(PropertyBuilder property); + /// /// Resolves the symbol for the specified event. /// @@ -181,6 +240,14 @@ interface IReflectionSymbol : ISymbol [return: NotNullIfNotNull(nameof(events))] IReflectionEventSymbol[]? ResolveEventSymbols(EventInfo[]? events); + /// + /// Resolves the symbol for the specified event. + /// + /// + /// + [return: NotNullIfNotNull(nameof(@event))] + IReflectionEventSymbolBuilder ResolveEventSymbol(EventBuilder @event); + /// /// Resolves the symbol for the specified parameter. /// @@ -197,6 +264,22 @@ interface IReflectionSymbol : ISymbol [return: NotNullIfNotNull(nameof(parameters))] IReflectionParameterSymbol[]? ResolveParameterSymbols(ParameterInfo[]? parameters); + /// + /// Resolves the symbol for the specified generic type parameter. + /// + /// + /// + [return: NotNullIfNotNull(nameof(genericTypeParameter))] + IReflectionGenericTypeParameterSymbolBuilder? ResolveGenericTypeParameterSymbol(GenericTypeParameterBuilder? genericTypeParameter); + + /// + /// Resolves the symbol for the specified generic type parameters. + /// + /// + /// + [return: NotNullIfNotNull(nameof(genericTypeParameters))] + IReflectionGenericTypeParameterSymbolBuilder[]? ResolveGenericTypeParameterSymbols(GenericTypeParameterBuilder[]? genericTypeParameters); + /// /// Transforms a custom set of custom attribute data records to a symbol record. /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionTypeSymbol.cs index a36c6f0a4..47da7f1b4 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionTypeSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionTypeSymbol.cs @@ -1,5 +1,8 @@ using System; using System.Reflection; +using System.Reflection.Emit; + +using IKVM.CoreLib.Symbols.Reflection.Emit; namespace IKVM.CoreLib.Symbols.Reflection { @@ -13,14 +16,16 @@ interface IReflectionTypeSymbol : IReflectionMemberSymbol, ITypeSymbol Type UnderlyingType { get; } /// - /// Gets the underlying used for IL emit operations. + /// Gets the underlying used for IL emit operations for dynamic methods. /// - Type UnderlyingEmitType { get; } + Type UnderlyingRuntimeType { get; } /// - /// Gets the underlying used for IL emit operations for dynamic methods. + /// Gets or creates a for the given element type. /// - Type UnderlyingDynamicEmitType { get; } + /// + /// + IReflectionTypeSymbol GetOrCreateGenericTypeSymbol(IReflectionTypeSymbol[] genericTypeDefinition); /// /// Gets or creates a for the given . @@ -36,6 +41,13 @@ interface IReflectionTypeSymbol : IReflectionMemberSymbol, ITypeSymbol /// IReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor); + /// + /// Gets or creates a for the given . + /// + /// + /// + IReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor); + /// /// Gets or creates a for the given . /// @@ -43,6 +55,13 @@ interface IReflectionTypeSymbol : IReflectionMemberSymbol, ITypeSymbol /// IReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method); + /// + /// Gets or creates a for the given . + /// + /// + /// + IReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method); + /// /// Gets or creates a for the given . /// @@ -50,6 +69,13 @@ interface IReflectionTypeSymbol : IReflectionMemberSymbol, ITypeSymbol /// IReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field); + /// + /// Gets or creates a for the given . + /// + /// + /// + IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field); + /// /// Gets or creates a for the given . /// @@ -57,6 +83,13 @@ interface IReflectionTypeSymbol : IReflectionMemberSymbol, ITypeSymbol /// IReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property); + /// + /// Gets or creates a for the given . + /// + /// + /// + IReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property); + /// /// Gets or creates a for the given . /// @@ -64,6 +97,13 @@ interface IReflectionTypeSymbol : IReflectionMemberSymbol, ITypeSymbol /// IReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event); + /// + /// Gets or creates a for the given . + /// + /// + /// + IReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event); + /// /// Gets or creates a for the given generic type parameter type. /// @@ -71,6 +111,13 @@ interface IReflectionTypeSymbol : IReflectionMemberSymbol, ITypeSymbol /// IReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type genericTypeParameter); + /// + /// Gets or creates a for the given . + /// + /// + /// + IReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeParameterSymbol(GenericTypeParameterBuilder genericTypeParameter); + /// /// Gets or creates a for the given element type. /// @@ -96,13 +143,6 @@ interface IReflectionTypeSymbol : IReflectionMemberSymbol, ITypeSymbol /// IReflectionTypeSymbol GetOrCreateByRefTypeSymbol(); - /// - /// Gets or creates a for the given element type. - /// - /// - /// - IReflectionTypeSymbol GetOrCreateGenericTypeSymbol(IReflectionTypeSymbol[] genericTypeDefinition); - } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionArrayTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionArrayTypeSymbol.cs index 99a1f0236..d11a94fcf 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionArrayTypeSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionArrayTypeSymbol.cs @@ -24,10 +24,7 @@ public ReflectionArrayTypeSymbol(ReflectionSymbolContext context, IReflectionMod public override Type UnderlyingType => ElementType.UnderlyingType.MakeArrayType(rank); /// - public override Type UnderlyingEmitType => ElementType.UnderlyingEmitType.MakeArrayType(rank); - - /// - public override Type UnderlyingDynamicEmitType => ElementType.UnderlyingDynamicEmitType.MakeArrayType(rank); + public override Type UnderlyingRuntimeType => ElementType.UnderlyingRuntimeType.MakeArrayType(rank); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs index 7496acfff..c5dffa008 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs @@ -29,9 +29,14 @@ public ReflectionAssemblySymbol(ReflectionSymbolContext context, Assembly assemb /// /// Gets the underlying instance. /// - public Assembly UnderlyingAssembly => _assembly; + public virtual Assembly UnderlyingAssembly => _assembly; - #region IAssemblySymbol + /// + /// Gets the underlying instance. + /// + public virtual Assembly UnderlyingRuntimeAssembly => _assembly; + + #region IReflectionAssemblySymbol /// public IReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionByRefTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionByRefTypeSymbol.cs index 70320ff0b..9e0c79d87 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionByRefTypeSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionByRefTypeSymbol.cs @@ -22,10 +22,7 @@ public ReflectionByRefTypeSymbol(ReflectionSymbolContext context, IReflectionMod public override Type UnderlyingType => ElementType.UnderlyingType.MakeByRefType(); /// - public override Type UnderlyingEmitType => ElementType.UnderlyingEmitType.MakeByRefType(); - - /// - public override Type UnderlyingDynamicEmitType => ElementType.UnderlyingDynamicEmitType.MakeByRefType(); + public override Type UnderlyingRuntimeType => ElementType.UnderlyingRuntimeType.MakeByRefType(); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionConstructorSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionConstructorSymbol.cs index ce5d37ac2..6049e8f84 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionConstructorSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionConstructorSymbol.cs @@ -23,16 +23,16 @@ public ReflectionConstructorSymbol(ReflectionSymbolContext context, IReflectionM } /// - public ConstructorInfo UnderlyingConstructor => _ctor; + public virtual ConstructorInfo UnderlyingConstructor => _ctor; /// - public ConstructorInfo UnderlyingEmitConstructor => UnderlyingConstructor; + public virtual ConstructorInfo UnderlyingRuntimeConstructor => UnderlyingConstructor; /// - public ConstructorInfo UnderlyingDynamicEmitConstructor => UnderlyingEmitConstructor; + public override MethodBase UnderlyingMethodBase => UnderlyingConstructor; /// - public override MethodBase UnderlyingMethodBase => UnderlyingConstructor; + public override MethodBase UnderlyingRuntimeMethodBase => UnderlyingRuntimeConstructor; } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionEventSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionEventSymbol.cs index 33a0c5721..b62385d45 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionEventSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionEventSymbol.cs @@ -23,14 +23,17 @@ public ReflectionEventSymbol(ReflectionSymbolContext context, IReflectionModuleS } /// - public EventInfo UnderlyingEvent => _event; + public virtual EventInfo UnderlyingEvent => _event; /// - public EventInfo UnderlyingEmitEvent => _event; + public virtual EventInfo UnderlyingRuntimeEvent => _event; /// public override MemberInfo UnderlyingMember => UnderlyingEvent; + /// + public override MemberInfo UnderlyingRuntimeMember => UnderlyingRuntimeEvent; + #region IEventSymbol /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionFieldSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionFieldSymbol.cs index 39b5c3273..f6095d471 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionFieldSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionFieldSymbol.cs @@ -23,21 +23,21 @@ public ReflectionFieldSymbol(ReflectionSymbolContext context, IReflectionModuleS } /// - public FieldInfo UnderlyingField => _field; + public virtual FieldInfo UnderlyingField => _field; /// - public FieldInfo UnderlyingEmitField => UnderlyingField; + public virtual FieldInfo UnderlyingRuntimeField => _field; /// - public FieldInfo UnderlyingDynamicEmitField => UnderlyingEmitField; + public override MemberInfo UnderlyingMember => UnderlyingField; /// - public override MemberInfo UnderlyingMember => UnderlyingField; + public override MemberInfo UnderlyingRuntimeMember => UnderlyingRuntimeField; #region IFieldSymbol /// - public System.Reflection.FieldAttributes Attributes => (System.Reflection.FieldAttributes)UnderlyingField.Attributes; + public FieldAttributes Attributes => UnderlyingField.Attributes; /// public ITypeSymbol FieldType => ResolveTypeSymbol(UnderlyingField.FieldType); diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericSpecTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericSpecTypeSymbol.cs index f7c5cadfc..3470c6b2f 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericSpecTypeSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericSpecTypeSymbol.cs @@ -26,10 +26,7 @@ public ReflectionGenericSpecTypeSymbol(ReflectionSymbolContext context, IReflect public override Type UnderlyingType => ElementType.UnderlyingType.MakeGenericType(genericTypeArguments.Select(i => i.UnderlyingType).ToArray()); /// - public override Type UnderlyingEmitType => ElementType.UnderlyingEmitType.MakeGenericType(genericTypeArguments.Select(i => i.UnderlyingEmitType).ToArray()); - - /// - public override Type UnderlyingDynamicEmitType => ElementType.UnderlyingDynamicEmitType.MakeGenericType(genericTypeArguments.Select(i => i.UnderlyingDynamicEmitType).ToArray()); + public override Type UnderlyingRuntimeType => ElementType.UnderlyingRuntimeType.MakeGenericType(genericTypeArguments.Select(i => i.UnderlyingRuntimeType).ToArray()); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericTypeParameterSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericTypeParameterSymbol.cs index 5000896e3..5aa9ccfad 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericTypeParameterSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericTypeParameterSymbol.cs @@ -1,8 +1,10 @@ using System; using System.Diagnostics.CodeAnalysis; using System.Reflection; +using System.Reflection.Emit; using IKVM.CoreLib.Reflection; +using IKVM.CoreLib.Symbols.Reflection.Emit; namespace IKVM.CoreLib.Symbols.Reflection { @@ -32,16 +34,16 @@ public ReflectionGenericTypeParameterSymbol(ReflectionSymbolContext context, IRe } /// - public Type UnderlyingType => _type; + public virtual Type UnderlyingType => _type; /// - public Type UnderlyingEmitType => UnderlyingType; + public virtual Type UnderlyingRuntimeType => _type; /// - public Type UnderlyingDynamicEmitType => _type; + public override MemberInfo UnderlyingMember => UnderlyingType; /// - public override MemberInfo UnderlyingMember => UnderlyingType; + public override MemberInfo UnderlyingRuntimeMember => UnderlyingRuntimeType; /// /// Gets the method base that declares this type parameter. @@ -64,6 +66,12 @@ public ReflectionGenericTypeParameterSymbol(ReflectionSymbolContext context, IRe #region IReflectionTypeSymbol + /// + public IReflectionTypeSymbol GetOrCreateGenericTypeSymbol(IReflectionTypeSymbol[] genericTypeDefinition) + { + return _specTable.GetOrCreateGenericTypeSymbol(genericTypeDefinition); + } + /// public IReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method) { @@ -76,36 +84,66 @@ public IReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo throw new NotSupportedException(); } + public IReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor) + { + throw new NotImplementedException(); + } + /// public IReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) { throw new NotSupportedException(); } + public IReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method) + { + throw new NotImplementedException(); + } + /// public IReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) { throw new NotSupportedException(); } + public IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field) + { + throw new NotImplementedException(); + } + /// public IReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) { throw new NotSupportedException(); } + public IReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property) + { + throw new NotImplementedException(); + } + /// public IReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) { throw new NotSupportedException(); } + public IReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event) + { + throw new NotImplementedException(); + } + /// public IReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type type) { throw new NotSupportedException(); } + public IReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeParameterSymbol(GenericTypeParameterBuilder genericTypeParameter) + { + throw new NotImplementedException(); + } + /// public IReflectionTypeSymbol GetOrCreateSZArrayTypeSymbol() { @@ -130,12 +168,6 @@ public IReflectionTypeSymbol GetOrCreateByRefTypeSymbol() return _specTable.GetOrCreateByRefTypeSymbol(); } - /// - public IReflectionTypeSymbol GetOrCreateGenericTypeSymbol(IReflectionTypeSymbol[] genericTypeDefinition) - { - return _specTable.GetOrCreateGenericTypeSymbol(genericTypeDefinition); - } - #endregion #region ITypeSymbol @@ -662,7 +694,7 @@ public ITypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments) return ResolveTypeSymbol(UnderlyingType.MakeGenericType(typeArguments.Unpack())); } -#endregion + #endregion } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs index 229278112..783d68a8d 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs @@ -3,6 +3,8 @@ using System.Linq; using System.Reflection; +using IKVM.CoreLib.Reflection; + namespace IKVM.CoreLib.Symbols.Reflection { @@ -21,7 +23,6 @@ abstract class ReflectionMemberSymbol : ReflectionSymbol, IReflectionMemberSymbo /// /// /// - /// public ReflectionMemberSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol? resolvingType) : base(context) { @@ -33,7 +34,7 @@ public ReflectionMemberSymbol(ReflectionSymbolContext context, IReflectionModule public abstract MemberInfo UnderlyingMember { get; } /// - public virtual MemberInfo UnderlyingEmitMember => UnderlyingMember; + public abstract MemberInfo UnderlyingRuntimeMember { get; } /// /// Gets the which contains the metadata of this member. @@ -166,10 +167,10 @@ public ReflectionMemberSymbol(ReflectionSymbolContext context, IReflectionModule public virtual ITypeSymbol? DeclaringType => ResolveTypeSymbol(UnderlyingMember.DeclaringType)!; /// - public virtual System.Reflection.MemberTypes MemberType => (System.Reflection.MemberTypes)UnderlyingMember.MemberType; + public virtual MemberTypes MemberType => UnderlyingMember.MemberType; /// - public virtual int MetadataToken => UnderlyingMember.MetadataToken; + public virtual int MetadataToken => UnderlyingMember.GetMetadataTokenSafe(); /// public virtual string Name => UnderlyingMember.Name; diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodBaseSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodBaseSymbol.cs index c16020d4c..8e7fdc126 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodBaseSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodBaseSymbol.cs @@ -1,4 +1,7 @@ using System.Reflection; +using System.Reflection.Emit; + +using IKVM.CoreLib.Symbols.Reflection.Emit; namespace IKVM.CoreLib.Symbols.Reflection { @@ -28,6 +31,12 @@ public IReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo param return _parameterTable.GetOrCreateParameterSymbol(parameter); } + /// + public IReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter) + { + return _parameterTable.GetOrCreateParameterSymbol(parameter); + } + #endregion #region IMethodBaseSymbol @@ -36,10 +45,13 @@ public IReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo param public abstract MethodBase UnderlyingMethodBase { get; } /// - public virtual MethodBase UnderlyingEmitMethodBase => UnderlyingMethodBase; + public abstract MethodBase UnderlyingRuntimeMethodBase { get; } + + /// + public override sealed MemberInfo UnderlyingMember => UnderlyingMethodBase; /// - public override MemberInfo UnderlyingMember => UnderlyingMethodBase; + public override sealed MemberInfo UnderlyingRuntimeMember => UnderlyingRuntimeMethodBase; /// public System.Reflection.MethodAttributes Attributes => (System.Reflection.MethodAttributes)UnderlyingMethodBase.Attributes; diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs index 35b421e48..358d8b886 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs @@ -1,5 +1,8 @@ using System; using System.Reflection; +using System.Reflection.Emit; + +using IKVM.CoreLib.Symbols.Reflection.Emit; namespace IKVM.CoreLib.Symbols.Reflection { @@ -28,16 +31,16 @@ public ReflectionMethodSymbol(ReflectionSymbolContext context, IReflectionModule } /// - public MethodInfo UnderlyingMethod => _method; + public virtual MethodInfo UnderlyingMethod => _method; /// - public MethodInfo UnderlyingEmitMethod => UnderlyingMethod; + public virtual MethodInfo UnderlyingRuntimeMethod => _method; /// - public MethodInfo UnderlyingDynamicEmitMethod => UnderlyingEmitMethod; + public override MethodBase UnderlyingMethodBase => UnderlyingMethod; /// - public override MethodBase UnderlyingMethodBase => UnderlyingMethod; + public override MethodBase UnderlyingRuntimeMethodBase => UnderlyingRuntimeMethod; #region IReflectionMethodSymbol @@ -47,6 +50,12 @@ public IReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type genericT return _genericTypeParameterTable.GetOrCreateGenericTypeParameterSymbol(genericTypeParameter); } + /// + public IReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeParameterSymbol(GenericTypeParameterBuilder genericTypeParameter) + { + return _genericTypeParameterTable.GetOrCreateGenericTypeParameterSymbol(genericTypeParameter); + } + /// public IReflectionMethodSymbol GetOrCreateGenericMethodSymbol(MethodInfo method) { diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs index 7f1bd1ed1..5e6ba8deb 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs @@ -1,8 +1,10 @@ using System; using System.Linq; using System.Reflection; +using System.Reflection.Emit; using IKVM.CoreLib.Reflection; +using IKVM.CoreLib.Symbols.Reflection.Emit; namespace IKVM.CoreLib.Symbols.Reflection { @@ -39,7 +41,10 @@ public ReflectionModuleSymbol(ReflectionSymbolContext context, IReflectionAssemb } /// - public Module UnderlyingModule => _module; + public virtual Module UnderlyingModule => _module; + + /// + public virtual Module UnderlyingRuntimeModule => _module; /// public IReflectionAssemblySymbol ResolvingAssembly => _resolvingAssembly; @@ -261,6 +266,15 @@ public IReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) throw new InvalidOperationException(); } + /// + public IReflectionTypeSymbolBuilder GetOrCreateTypeSymbol(TypeBuilder type) + { + if (type.IsTypeDefinition()) + return (IReflectionTypeSymbolBuilder)_typeTable.GetOrCreateTypeSymbol(type); + + throw new InvalidOperationException(); + } + /// public IReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method) { @@ -276,6 +290,12 @@ public IReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo return ResolveTypeSymbol(ctor.DeclaringType!).GetOrCreateConstructorSymbol(ctor); } + /// + public IReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor) + { + return ResolveTypeSymbol((TypeBuilder)ctor.DeclaringType!).GetOrCreateConstructorSymbol(ctor); + } + /// public IReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) { @@ -285,6 +305,15 @@ public IReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) return _methodTable.GetOrCreateMethodSymbol(method); } + /// + public IReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method) + { + if (method.DeclaringType is { } dt) + return ResolveTypeSymbol((TypeBuilder)dt).GetOrCreateMethodSymbol(method); + else + return _methodTable.GetOrCreateMethodSymbol(method); + } + /// public IReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) { @@ -294,18 +323,39 @@ public IReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) return _fieldTable.GetOrCreateFieldSymbol(field); } + /// + public IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field) + { + if (field.DeclaringType is { } dt) + return ResolveTypeSymbol((TypeBuilder)dt).GetOrCreateFieldSymbol(field); + else + return _fieldTable.GetOrCreateFieldSymbol(field); + } + /// public IReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) { return ResolveTypeSymbol(property.DeclaringType!).GetOrCreatePropertySymbol(property); } + /// + public IReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property) + { + return ResolveTypeSymbol(property.GetTypeBuilder()).GetOrCreatePropertySymbol(property); + } + /// public IReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) { return ResolveTypeSymbol(@event.DeclaringType!).GetOrCreateEventSymbol(@event); } + /// + public IReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event) + { + return ResolveTypeSymbol(@event.GetTypeBuilder()).GetOrCreateEventSymbol(@event); + } + /// public IReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo parameter) { @@ -317,6 +367,26 @@ public IReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo param }; } + /// + public IReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(IReflectionMemberSymbolBuilder member, ParameterBuilder parameter) + { + return member switch + { + IReflectionMethodBaseSymbolBuilder method => method.GetOrCreateParameterSymbol(parameter), + IReflectionPropertySymbolBuilder property => property.GetOrCreateParameterSymbol(parameter), + _ => throw new InvalidOperationException(), + }; + } + + /// + public IReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeParameterSymbol(GenericTypeParameterBuilder genericParameterType) + { + if (genericParameterType.DeclaringMethod is MethodBuilder dm) + return ResolveMethodSymbol(dm).GetOrCreateGenericTypeParameterSymbol(genericParameterType); + else + return ResolveTypeSymbol((TypeBuilder)genericParameterType.DeclaringType!).GetOrCreateGenericTypeParameterSymbol(genericParameterType); + } + #endregion /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleTable.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleTable.cs index 38f817272..951bb374b 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleTable.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleTable.cs @@ -1,7 +1,6 @@ using System; using System.Reflection; using System.Reflection.Emit; -using System.Reflection.Metadata.Ecma335; using System.Threading; using IKVM.CoreLib.Collections; @@ -60,16 +59,6 @@ public IReflectionModuleSymbol GetOrCreateModuleSymbol(Module module) } } - /// - /// Gets or creates the cached for the module. - /// - /// - /// - public IReflectionModuleSymbolBuilder GetOrCreateModuleSymbol(ModuleBuilder module) - { - return (IReflectionModuleSymbolBuilder)GetOrCreateModuleSymbol((Module)module); - } - } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterSymbol.cs index 5d9c95446..ff2e53811 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterSymbol.cs @@ -37,7 +37,7 @@ public ReflectionParameterSymbol(ReflectionSymbolContext context, IReflectionMod public ParameterInfo UnderlyingParameter => _parameter; /// - public ParameterInfo UnderlyingEmitParameter => UnderlyingParameter; + public ParameterInfo UnderlyingRuntimeParameter => UnderlyingParameter; #region IParameterSymbol diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionPointerTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionPointerTypeSymbol.cs index 0ac878770..195f15544 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionPointerTypeSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionPointerTypeSymbol.cs @@ -22,10 +22,7 @@ public ReflectionPointerTypeSymbol(ReflectionSymbolContext context, IReflectionM public override Type UnderlyingType => ElementType.UnderlyingType.MakePointerType(); /// - public override Type UnderlyingEmitType => ElementType.UnderlyingEmitType.MakePointerType(); - - /// - public override Type UnderlyingDynamicEmitType => ElementType.UnderlyingDynamicEmitType.MakePointerType(); + public override Type UnderlyingRuntimeType => ElementType.UnderlyingRuntimeType.MakePointerType(); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionPropertySymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionPropertySymbol.cs index ca77f5d84..fab3b8cde 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionPropertySymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionPropertySymbol.cs @@ -1,5 +1,8 @@ using System; using System.Reflection; +using System.Reflection.Emit; + +using IKVM.CoreLib.Symbols.Reflection.Emit; namespace IKVM.CoreLib.Symbols.Reflection { @@ -26,14 +29,17 @@ public ReflectionPropertySymbol(ReflectionSymbolContext context, IReflectionModu } /// - public PropertyInfo UnderlyingProperty => _property; + public virtual PropertyInfo UnderlyingProperty => _property; /// - public PropertyInfo UnderlyingEmitProperty => UnderlyingProperty; + public virtual PropertyInfo UnderlyingRuntimeProperty => UnderlyingProperty; /// public override MemberInfo UnderlyingMember => UnderlyingProperty; + /// + public override MemberInfo UnderlyingRuntimeMember => UnderlyingRuntimeProperty; + #region IReflectionPropertySymbol /// @@ -42,6 +48,12 @@ public IReflectionParameterSymbol GetOrCreateParameterSymbol(ParameterInfo param return _parameterTable.GetOrCreateParameterSymbol(parameter); } + /// + public IReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBuilder parameter) + { + return _parameterTable.GetOrCreateParameterSymbol(parameter); + } + #endregion #region IPropertySymbol diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSZArrayTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSZArrayTypeSymbol.cs index 63845863f..c50573f6c 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSZArrayTypeSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSZArrayTypeSymbol.cs @@ -22,10 +22,7 @@ public ReflectionSZArrayTypeSymbol(ReflectionSymbolContext context, IReflectionM public override Type UnderlyingType => ElementType.UnderlyingType.MakeArrayType(); /// - public override Type UnderlyingEmitType => ElementType.UnderlyingEmitType.MakeArrayType(); - - /// - public override Type UnderlyingDynamicEmitType => ElementType.UnderlyingDynamicEmitType.MakeArrayType(); + public override Type UnderlyingRuntimeType => ElementType.UnderlyingRuntimeType.MakeArrayType(); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbol.cs index ae1c1f317..b6c191b51 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbol.cs @@ -27,6 +27,8 @@ public ReflectionSymbol(ReflectionSymbolContext context) _context = context ?? throw new ArgumentNullException(nameof(context)); } + #region IReflectionSymbol + /// /// Gets the associated . /// @@ -433,6 +435,33 @@ public virtual IReflectionPropertySymbolBuilder ResolvePropertySymbol(PropertyBu return a; } + /// + [return: NotNullIfNotNull(nameof(genericTypeParameter))] + public IReflectionGenericTypeParameterSymbolBuilder? ResolveGenericTypeParameterSymbol(GenericTypeParameterBuilder? genericTypeParameter) + { + if (genericTypeParameter == null) + return null; + + return _context.GetOrCreateGenericTypeParameterSymbol(genericTypeParameter); + } + + /// + [return: NotNullIfNotNull(nameof(genericTypeParameters))] + public IReflectionGenericTypeParameterSymbolBuilder[]? ResolveGenericTypeParameterSymbols(GenericTypeParameterBuilder[]? genericTypeParameters) + { + if (genericTypeParameters == null) + return null; + if (genericTypeParameters.Length == 0) + return []; + + var a = new IReflectionGenericTypeParameterSymbolBuilder[genericTypeParameters.Length]; + for (int i = 0; i < genericTypeParameters.Length; i++) + if (ResolveGenericTypeParameterSymbol(genericTypeParameters[i]) is { } symbol) + a[i] = symbol; + + return a; + } + /// [return: NotNullIfNotNull(nameof(attributes))] public CustomAttribute[]? ResolveCustomAttributes(IList? attributes) @@ -553,6 +582,8 @@ public InterfaceMapping ResolveInterfaceMapping(System.Reflection.InterfaceMappi return info != null ? new ManifestResourceInfo((System.Reflection.ResourceLocation)info.ResourceLocation, info.FileName, ResolveAssemblySymbol(info.ReferencedAssembly)) : null; } + #endregion + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs index d4f421bb9..b10d2f16a 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Concurrent; +using System.Collections.Immutable; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; @@ -54,11 +55,10 @@ public IAssemblySymbolBuilder DefineAssembly(AssemblyIdentity name, bool collect } /// - public IAssemblySymbolBuilder DefineAssembly(AssemblyIdentity name, ICustomAttributeBuilder[]? assemblyAttributes, bool collectable, bool saveable) + public IAssemblySymbolBuilder DefineAssembly(AssemblyIdentity name, ImmutableArray attributes, bool collectable, bool saveable) { if (name is null) throw new ArgumentNullException(nameof(name)); - if (collectable && saveable) throw new NotSupportedException("Assembly cannot be both colletable and saveable."); @@ -66,16 +66,16 @@ public IAssemblySymbolBuilder DefineAssembly(AssemblyIdentity name, ICustomAttri if (saveable) throw new NotSupportedException("Assembly cannot be saveable."); else if (collectable) - return GetOrCreateAssemblySymbol(AssemblyBuilder.DefineDynamicAssembly(name.Unpack(), AssemblyBuilderAccess.RunAndCollect, assemblyAttributes?.Unpack())); + return GetOrCreateAssemblySymbol(AssemblyBuilder.DefineDynamicAssembly(name.Unpack(), AssemblyBuilderAccess.RunAndCollect, attributes.Unpack())); else - return GetOrCreateAssemblySymbol(AssemblyBuilder.DefineDynamicAssembly(name.Unpack(), AssemblyBuilderAccess.Run, assemblyAttributes?.Unpack())); + return GetOrCreateAssemblySymbol(AssemblyBuilder.DefineDynamicAssembly(name.Unpack(), AssemblyBuilderAccess.Run, attributes.Unpack())); #else if (saveable) - return GetOrCreateAssemblySymbol(AssemblyBuilder.DefineDynamicAssembly(name.Unpack(), AssemblyBuilderAccess.RunAndSave, assemblyAttributes?.Unpack())); + return GetOrCreateAssemblySymbol(AssemblyBuilder.DefineDynamicAssembly(name.Unpack(), AssemblyBuilderAccess.RunAndSave, attributes.Unpack())); else if (collectable) - return GetOrCreateAssemblySymbol(AssemblyBuilder.DefineDynamicAssembly(name.Unpack(), AssemblyBuilderAccess.RunAndCollect, assemblyAttributes?.Unpack())); + return GetOrCreateAssemblySymbol(AssemblyBuilder.DefineDynamicAssembly(name.Unpack(), AssemblyBuilderAccess.RunAndCollect, attributes.Unpack())); else - return GetOrCreateAssemblySymbol(AssemblyBuilder.DefineDynamicAssembly(name.Unpack(), AssemblyBuilderAccess.Run, assemblyAttributes?.Unpack())); + return GetOrCreateAssemblySymbol(AssemblyBuilder.DefineDynamicAssembly(name.Unpack(), AssemblyBuilderAccess.Run, attributes.Unpack())); #endif } @@ -349,30 +349,6 @@ public IReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeParame return GetOrCreateModuleSymbol((ModuleBuilder)genericTypeParameter.Module).GetOrCreateGenericTypeParameterSymbol(genericTypeParameter); } - /// - public ICustomAttributeBuilder CreateCustomAttribute(IConstructorSymbol con, object?[] constructorArgs) - { - return new ReflectionCustomAttributeBuilder(new CustomAttributeBuilder(con.Unpack(), UnpackArguments(constructorArgs))); - } - - /// - public ICustomAttributeBuilder CreateCustomAttribute(IConstructorSymbol con, object?[] constructorArgs, IFieldSymbol[] namedFields, object?[] fieldValues) - { - return new ReflectionCustomAttributeBuilder(new CustomAttributeBuilder(con.Unpack(), UnpackArguments(constructorArgs), namedFields.Unpack(), UnpackArguments(fieldValues))); - } - - /// - public ICustomAttributeBuilder CreateCustomAttribute(IConstructorSymbol con, object?[] constructorArgs, IPropertySymbol[] namedProperties, object?[] propertyValues) - { - return new ReflectionCustomAttributeBuilder(new CustomAttributeBuilder(con.Unpack(), UnpackArguments(constructorArgs), namedProperties.Unpack(), UnpackArguments(propertyValues))); - } - - /// - public ICustomAttributeBuilder CreateCustomAttribute(IConstructorSymbol con, object?[] constructorArgs, IPropertySymbol[] namedProperties, object?[] propertyValues, IFieldSymbol[] namedFields, object?[] fieldValues) - { - return new ReflectionCustomAttributeBuilder(new CustomAttributeBuilder(con.Unpack(), UnpackArguments(constructorArgs), namedProperties.Unpack(), UnpackArguments(propertyValues), namedFields.Unpack(), UnpackArguments(fieldValues))); - } - /// /// Unpacks a single constructor argument. /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbol.cs index f8476934b..1f10ce439 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbol.cs @@ -24,6 +24,9 @@ public ReflectionTypeSymbol(ReflectionSymbolContext context, IReflectionModuleSy /// public override Type UnderlyingType => _type; + /// + public override Type UnderlyingRuntimeType => _type; + #region IReflectionSymbol /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbolBase.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbolBase.cs index 833571069..4edd57cb3 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbolBase.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbolBase.cs @@ -38,22 +38,34 @@ public ReflectionTypeSymbolBase(ReflectionSymbolContext context, IReflectionModu public abstract Type UnderlyingType { get; } /// - public virtual Type UnderlyingEmitType => UnderlyingType; + public abstract Type UnderlyingRuntimeType { get; } /// - public virtual Type UnderlyingDynamicEmitType => UnderlyingEmitType; + public override sealed MemberInfo UnderlyingMember => UnderlyingType; /// - public override MemberInfo UnderlyingMember => UnderlyingType; + public override sealed MemberInfo UnderlyingRuntimeMember => UnderlyingRuntimeType; #region IReflectionTypeSymbol + /// + public IReflectionTypeSymbol GetOrCreateGenericTypeSymbol(IReflectionTypeSymbol[] genericTypeDefinition) + { + return _specTable.GetOrCreateGenericTypeSymbol(genericTypeDefinition); + } + /// public IReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor) { return _methodTable.GetOrCreateConstructorSymbol(ctor); } + /// + public IReflectionConstructorSymbolBuilder GetOrCreateConstructorSymbol(ConstructorBuilder ctor) + { + return _methodTable.GetOrCreateConstructorSymbol(ctor); + } + /// public IReflectionMethodBaseSymbol GetOrCreateMethodBaseSymbol(MethodBase method) { @@ -72,30 +84,60 @@ public IReflectionMethodSymbol GetOrCreateMethodSymbol(MethodInfo method) return ResolveMethodSymbol(method.GetGenericMethodDefinition()).GetOrCreateGenericMethodSymbol(method); } + /// + public IReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder method) + { + return _methodTable.GetOrCreateMethodSymbol(method); + } + /// public IReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) { return _fieldTable.GetOrCreateFieldSymbol(field); } + /// + public IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field) + { + return _fieldTable.GetOrCreateFieldSymbol(field); + } + /// public IReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property) { return _propertyTable.GetOrCreatePropertySymbol(property); } + /// + public IReflectionPropertySymbolBuilder GetOrCreatePropertySymbol(PropertyBuilder property) + { + return _propertyTable.GetOrCreatePropertySymbol(property); + } + /// public IReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event) { return _eventTable.GetOrCreateEventSymbol(@event); } + /// + public IReflectionEventSymbolBuilder GetOrCreateEventSymbol(EventBuilder @event) + { + return _eventTable.GetOrCreateEventSymbol(@event); + } + /// public IReflectionTypeSymbol GetOrCreateGenericTypeParameterSymbol(Type genericType) { return _genericTypeParameterTable.GetOrCreateGenericTypeParameterSymbol(genericType); } + /// + public IReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeParameterSymbol(GenericTypeParameterBuilder genericTypeParameter) + { + return _genericTypeParameterTable.GetOrCreateGenericTypeParameterSymbol(genericTypeParameter); + } + /// public IReflectionTypeSymbol GetOrCreateSZArrayTypeSymbol() { @@ -120,22 +162,6 @@ public IReflectionTypeSymbol GetOrCreateByRefTypeSymbol() return _specTable.GetOrCreateByRefTypeSymbol(); } - /// - public IReflectionTypeSymbol GetOrCreateGenericTypeSymbol(IReflectionTypeSymbol[] genericTypeDefinition) - { - return _specTable.GetOrCreateGenericTypeSymbol(genericTypeDefinition); - } - - #endregion - - #region IReflectionTypeSymbolBuilder - - /// - public IReflectionGenericTypeParameterSymbolBuilder GetOrCreateGenericTypeParameterSymbol(GenericTypeParameterBuilder genericTypeParameter) - { - return _genericTypeParameterTable.GetOrCreateGenericTypeParameterSymbol(genericTypeParameter); - } - #endregion #region ITypeSymbol @@ -513,19 +539,19 @@ public virtual IMemberSymbol[] GetMembers() } /// - public virtual IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, ITypeSymbol[] types, ParameterModifier[]? modifiers) + public virtual IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers) { - throw new NotImplementedException(); + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, bindingAttr, null, callConvention, types.Unpack(), modifiers?.Unpack())); } /// - public virtual IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers) + public virtual IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, ParameterModifier[]? modifiers) { - return ResolveMethodSymbol(UnderlyingType.GetMethod(name, bindingAttr, null, callConvention, types.Unpack(), modifiers?.Unpack())); + throw new NotImplementedException(); } /// - public virtual IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, ParameterModifier[]? modifiers) + public virtual IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, ITypeSymbol[] types, ParameterModifier[]? modifiers) { throw new NotImplementedException(); } @@ -537,9 +563,9 @@ public virtual IMemberSymbol[] GetMembers() } /// - public virtual IMethodSymbol[] GetMethods(System.Reflection.BindingFlags bindingAttr) + public virtual IMethodSymbol[] GetMethods(BindingFlags bindingAttr) { - return ResolveMethodSymbols(UnderlyingType.GetMethods((BindingFlags)bindingAttr)); + return ResolveMethodSymbols(UnderlyingType.GetMethods(bindingAttr)); } /// @@ -557,7 +583,7 @@ public virtual IMethodSymbol[] GetMethods() /// public virtual ITypeSymbol? GetNestedType(string name, System.Reflection.BindingFlags bindingAttr) { - return ResolveTypeSymbol(UnderlyingType.GetNestedType(name, (BindingFlags)bindingAttr)); + return ResolveTypeSymbol(UnderlyingType.GetNestedType(name, bindingAttr)); } /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionUtil.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionUtil.cs index 5a19f7b9a..d8991850d 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionUtil.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionUtil.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Collections.Immutable; using System.Reflection; using System.Reflection.Emit; @@ -383,21 +384,58 @@ public static Label[] Unpack(this ILabel[] labels) } /// - /// Unpacks the . + /// Unpacks the . /// /// /// - public static CustomAttributeBuilder Unpack(this ICustomAttributeBuilder customAttributes) + public static CustomAttributeBuilder Unpack(this CustomAttribute attributes) { - return ((ReflectionCustomAttributeBuilder)customAttributes).UnderlyingBuilder; + // unpack constructor arg values + var constructorValues = new object?[attributes.ConstructorArguments.Length]; + for (int i = 0; i < attributes.ConstructorArguments.Length; i++) + constructorValues[i] = UnpackCustomAttributeValue(attributes.ConstructorArguments[i]); + + // unpack named arguments into sets of properties and fields + List? namedProperties = null; + List? propertyValues = null; + List? namedFields = null; + List? fieldValues = null; + + // split named arguments into two sets + foreach (var i in attributes.NamedArguments) + { + var v = UnpackCustomAttributeValue(i.TypedValue.Value); + if (i.IsField == false) + { + namedProperties ??= new(); + namedProperties.Add(((IPropertySymbol)i.MemberInfo).Unpack()); + propertyValues ??= new(); + propertyValues.Add(v); + } + else + { + namedFields ??= new(); + namedFields.Add(((IFieldSymbol)i.MemberInfo).Unpack()); + fieldValues ??= new(); + fieldValues.Add(v); + } + } + + return new CustomAttributeBuilder( + attributes.Constructor.Unpack(), + constructorValues, + namedProperties?.ToArray() ?? [], + propertyValues?.ToArray() ?? [], + namedFields?.ToArray() ?? [], + fieldValues?.ToArray() ?? []); } /// - /// Unpacks the s. + /// Unpacks the s. /// /// /// - public static CustomAttributeBuilder[] Unpack(this ICustomAttributeBuilder[] customAttributes) + public static CustomAttributeBuilder[] Unpack(this CustomAttribute[] customAttributes) { if (customAttributes.Length == 0) return []; @@ -409,6 +447,53 @@ public static CustomAttributeBuilder[] Unpack(this ICustomAttributeBuilder[] cus return a; } + /// + /// Unpacks the s. + /// + /// + /// + public static CustomAttributeBuilder[] Unpack(this ImmutableArray attributes) + { + if (attributes.Length == 0) + return []; + + var a = new CustomAttributeBuilder[attributes.Length]; + for (int i = 0; i < attributes.Length; i++) + a[i] = attributes[i].Unpack(); + + return a; + } + + /// + /// Unpacks the attribute value object. + /// + /// + /// + static object? UnpackCustomAttributeValue(object? value) + { + return value switch + { + IReadOnlyList l => UnpackCustomAttributeArrayValue(l), + ITypeSymbol t => t.Unpack(), + CustomAttributeTypedArgument a => UnpackCustomAttributeValue(a.Value), + _ => value, + }; + } + + /// + /// Unpacks the attribute value array. + /// + /// + /// + static object?[] UnpackCustomAttributeArrayValue(IReadOnlyList items) + { + var a = new object?[items.Count]; + for (int i = 0; i < items.Count; i++) + a[i] = UnpackCustomAttributeValue(items[i]); + + return a; + } + /// /// Returns true if the given type represents a type definition. /// diff --git a/src/IKVM.CoreLib/Symbols/SymbolUtil.cs b/src/IKVM.CoreLib/Symbols/SymbolUtil.cs index 7727345ac..2d7c43142 100644 --- a/src/IKVM.CoreLib/Symbols/SymbolUtil.cs +++ b/src/IKVM.CoreLib/Symbols/SymbolUtil.cs @@ -1,4 +1,6 @@ using System.Collections.Generic; +using System.ComponentModel; +using System.Reflection; namespace IKVM.CoreLib.Symbols { @@ -14,40 +16,40 @@ static class SymbolUtil /// /// /// - static bool BindingFlagsMatch(bool state, System.Reflection.BindingFlags flags, System.Reflection.BindingFlags trueFlag, System.Reflection.BindingFlags falseFlag) + static bool BindingFlagsMatch(bool state, BindingFlags flags, BindingFlags trueFlag, BindingFlags falseFlag) { return (state && (flags & trueFlag) == trueFlag) || (!state && (flags & falseFlag) == falseFlag); } /// - /// Evaluates whether the specified would match the . + /// Evaluates whether the specified would match the . /// /// /// /// - public static bool BindingFlagsMatch(IMethodSymbol member, System.Reflection.BindingFlags flags) + public static bool BindingFlagsMatch(IMethodSymbol member, BindingFlags flags) { - return BindingFlagsMatch(member.IsPublic, flags, System.Reflection.BindingFlags.Public, System.Reflection.BindingFlags.NonPublic) - && BindingFlagsMatch(member.IsStatic, flags, System.Reflection.BindingFlags.Static, System.Reflection.BindingFlags.Instance); + return BindingFlagsMatch(member.IsPublic, flags, BindingFlags.Public, BindingFlags.NonPublic) + && BindingFlagsMatch(member.IsStatic, flags, BindingFlags.Static, BindingFlags.Instance); } /// - /// Evaluates whether the specified would match the . + /// Evaluates whether the specified would match the . /// /// /// /// - public static bool BindingFlagsMatchInherited(IMethodSymbol method, System.Reflection.BindingFlags flags) + public static bool BindingFlagsMatchInherited(IMethodSymbol method, BindingFlags flags) { - return BindingFlagsMatch(method.IsPublic, flags, System.Reflection.BindingFlags.Public, System.Reflection.BindingFlags.NonPublic) - && BindingFlagsMatch(method.IsStatic, flags, System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.FlattenHierarchy, System.Reflection.BindingFlags.Instance); + return BindingFlagsMatch(method.IsPublic, flags, BindingFlags.Public, BindingFlags.NonPublic) + && BindingFlagsMatch(method.IsStatic, flags, BindingFlags.Static | BindingFlags.FlattenHierarchy, BindingFlags.Instance); } /// /// Filters the set of methods by the binding attributes. /// /// - public static IEnumerable FilterMethods(ITypeSymbol type, IEnumerable methods, System.Reflection.BindingFlags bindingAttr = System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Instance) + public static IEnumerable FilterMethods(ITypeSymbol type, IEnumerable methods, BindingFlags bindingAttr = BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance) { var list = new HashSet(); @@ -59,7 +61,7 @@ public static IEnumerable FilterMethods(ITypeSymbol type, IEnumer yield return mi; } - if ((bindingAttr & System.Reflection.BindingFlags.DeclaredOnly) == 0) + if ((bindingAttr & BindingFlags.DeclaredOnly) == 0) { var baseMethods = new List(); foreach (var mi in list) @@ -68,7 +70,7 @@ public static IEnumerable FilterMethods(ITypeSymbol type, IEnumer for (var baseType = type.BaseType; baseType != null; baseType = baseType.BaseType) { - foreach (var mi in baseType.GetMethods(System.Reflection.BindingFlags.DeclaredOnly | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Instance)) + foreach (var mi in baseType.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance)) { if (BindingFlagsMatchInherited(mi, bindingAttr)) { diff --git a/src/IKVM.JTReg.TestAdapter.Core/ErrorHandlerInterceptor.cs b/src/IKVM.JTReg.TestAdapter.Core/ErrorHandlerInterceptor.cs index 4bbf7b61a..70dfa0300 100644 --- a/src/IKVM.JTReg.TestAdapter.Core/ErrorHandlerInterceptor.cs +++ b/src/IKVM.JTReg.TestAdapter.Core/ErrorHandlerInterceptor.cs @@ -11,7 +11,7 @@ namespace IKVM.JTReg.TestAdapter.Core public class ErrorHandlerInterceptor : DispatchProxy { - static readonly MethodInfo CreateMethodInfo = typeof(DispatchProxy).GetMethods() + static readonly MethodInfo CreateMethodInfo = typeof(DispatchProxy).GetMethods(BindingFlags.Static | BindingFlags.Public) .Where(i => i.Name == "Create") .Where(i => i.GetGenericArguments().Length == 2) .First(); @@ -22,7 +22,7 @@ public class ErrorHandlerInterceptor : DispatchProxy /// public static ErrorHandlerInterceptor Create(IJTRegLoggerContext logger) { - var proxy = (ErrorHandlerInterceptor)CreateMethodInfo.MakeGenericMethod(JTRegTypes.TestFinder.ErrorHandler.Type, typeof(ErrorHandlerInterceptor)).Invoke(null, []); + var proxy = (ErrorHandlerInterceptor)CreateMethodInfo.MakeGenericMethod([JTRegTypes.TestFinder.ErrorHandler.Type, typeof(ErrorHandlerInterceptor)]).Invoke(null, []); proxy.SetLogger(logger); return proxy; } diff --git a/src/IKVM.Runtime/AttributeHelper.cs b/src/IKVM.Runtime/AttributeHelper.cs index 6bf07f89b..0373a8c05 100644 --- a/src/IKVM.Runtime/AttributeHelper.cs +++ b/src/IKVM.Runtime/AttributeHelper.cs @@ -49,10 +49,10 @@ class AttributeHelper readonly RuntimeContext context; - ICustomAttributeBuilder compilerGeneratedAttribute; - ICustomAttributeBuilder ghostInterfaceAttribute; - ICustomAttributeBuilder deprecatedAttribute; - ICustomAttributeBuilder editorBrowsableNever; + CustomAttribute? compilerGeneratedAttribute; + CustomAttribute? ghostInterfaceAttribute; + CustomAttribute? deprecatedAttribute; + CustomAttribute? editorBrowsableNever; IConstructorSymbol implementsAttribute; IConstructorSymbol throwsAttribute; IConstructorSymbol sourceFileAttribute; @@ -63,7 +63,7 @@ class AttributeHelper IConstructorSymbol methodParametersAttribute; IConstructorSymbol runtimeVisibleTypeAnnotationsAttribute; IConstructorSymbol constantPoolAttribute; - ICustomAttributeBuilder paramArrayAttribute; + CustomAttribute? paramArrayAttribute; IConstructorSymbol nonNestedInnerClassAttribute; IConstructorSymbol nonNestedOuterClassAttribute; @@ -95,8 +95,8 @@ class AttributeHelper ITypeSymbol typeofConstantPoolAttribute; ITypeSymbol typeofDebuggableAttribute; ITypeSymbol typeofCustomAssemblyClassLoaderAttribute; - ICustomAttributeBuilder hideFromJavaAttribute; - ICustomAttributeBuilder hideFromReflection; + CustomAttribute? hideFromJavaAttribute; + CustomAttribute? hideFromReflection; IConstructorSymbol debuggableAttribute; ITypeSymbol TypeOfModifiers => typeofModifiers ??= context.Resolver.ResolveRuntimeType(typeof(Modifiers).FullName); @@ -153,9 +153,9 @@ class AttributeHelper ITypeSymbol TypeOfCustomAssemblyClassLoaderAttribute => typeofCustomAssemblyClassLoaderAttribute ??= context.Resolver.ResolveRuntimeType(typeof(IKVM.Attributes.CustomAssemblyClassLoaderAttribute).FullName); - ICustomAttributeBuilder HideFromJavaAttributeBuilder => hideFromJavaAttribute ??= context.Resolver.Symbols.CreateCustomAttribute(TypeOfHideFromJavaAttribute.GetConstructor([]), []); + CustomAttribute HideFromJavaAttributeBuilder => hideFromJavaAttribute ??= CustomAttribute.Create(TypeOfHideFromJavaAttribute.GetConstructor([]), []); - ICustomAttributeBuilder HideFromReflectionBuilder => hideFromReflection ??= context.Resolver.Symbols.CreateCustomAttribute(TypeOfHideFromJavaAttribute.GetConstructor([TypeOfHideFromJavaFlags]), [HideFromJavaFlags.Reflection | HideFromJavaFlags.StackTrace | HideFromJavaFlags.StackWalk]); + CustomAttribute HideFromReflectionBuilder => hideFromReflection ??= CustomAttribute.Create(TypeOfHideFromJavaAttribute.GetConstructor([TypeOfHideFromJavaFlags]), [HideFromJavaFlags.Reflection | HideFromJavaFlags.StackTrace | HideFromJavaFlags.StackWalk]); /// /// Initializes a new instance. @@ -292,7 +292,7 @@ void GetAttributeArgsAndTypes(RuntimeClassLoader loader, IKVM.Tools.Importer.Map } } - ICustomAttributeBuilder CreateCustomAttribute(RuntimeClassLoader loader, IKVM.Tools.Importer.MapXml.Attribute attr) + CustomAttribute CreateCustomAttribute(RuntimeClassLoader loader, IKVM.Tools.Importer.MapXml.Attribute attr) { // TODO add error handling GetAttributeArgsAndTypes(loader, attr, out var argTypes, out var args); @@ -331,7 +331,7 @@ ICustomAttributeBuilder CreateCustomAttribute(RuntimeClassLoader loader, IKVM.To } } - return context.Resolver.Symbols.CreateCustomAttribute(ci, args, namedProperties, propertyValues, namedFields, fieldValues); + return CustomAttribute.Create(ci, args, namedProperties, propertyValues, namedFields, fieldValues); } else { @@ -363,33 +363,31 @@ ICustomAttributeBuilder CreateCustomAttribute(RuntimeClassLoader loader, IKVM.To mw.Link(); var ci = (mw.GetMethod() as IConstructorSymbol) ?? ((IConstructorSymbol)mw.GetMethod()); - return context.Resolver.Symbols.CreateCustomAttribute(ci, args, namedFields, fieldValues); + return CustomAttribute.Create(ci, args, namedFields, fieldValues); } } - ICustomAttributeBuilder GetEditorBrowsableNever() + CustomAttribute GetEditorBrowsableNever() { if (editorBrowsableNever == null) { var typeofEditorBrowsableAttribute = context.Resolver.ResolveSystemType(typeof(EditorBrowsableAttribute).FullName); var typeofEditorBrowsableState = context.Resolver.ResolveSystemType(typeof(EditorBrowsableState).FullName); var ctor = typeofEditorBrowsableAttribute.GetConstructor([typeofEditorBrowsableState]); - editorBrowsableNever = context.Resolver.Symbols.CreateCustomAttribute(ctor, [EditorBrowsableState.Never]); + editorBrowsableNever = CustomAttribute.Create(ctor, [EditorBrowsableState.Never]); } - return editorBrowsableNever; + return editorBrowsableNever.Value; } internal void SetCompilerGenerated(ITypeSymbolBuilder tb) { - compilerGeneratedAttribute ??= context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveSystemType(typeof(CompilerGeneratedAttribute).FullName).GetConstructor([]), []); - tb.SetCustomAttribute(compilerGeneratedAttribute); + tb.SetCustomAttribute(compilerGeneratedAttribute ??= CustomAttribute.Create(context.Resolver.ResolveSystemType(typeof(CompilerGeneratedAttribute).FullName).GetConstructor([]), [])); } internal void SetCompilerGenerated(IMethodBaseSymbolBuilder mb) { - compilerGeneratedAttribute ??= context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveSystemType(typeof(CompilerGeneratedAttribute).FullName).GetConstructor([]), []); - mb.SetCustomAttribute(compilerGeneratedAttribute); + mb.SetCustomAttribute(compilerGeneratedAttribute ??= CustomAttribute.Create(context.Resolver.ResolveSystemType(typeof(CompilerGeneratedAttribute).FullName).GetConstructor([]), [])); } internal void SetEditorBrowsableNever(ITypeSymbolBuilder tb) @@ -409,26 +407,22 @@ internal void SetEditorBrowsableNever(IPropertySymbolBuilder pb) internal void SetDeprecatedAttribute(IMethodBaseSymbolBuilder mb) { - deprecatedAttribute ??= context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveSystemType(typeof(ObsoleteAttribute).FullName).GetConstructor([]), []); - mb.SetCustomAttribute(deprecatedAttribute); + mb.SetCustomAttribute(deprecatedAttribute ??= CustomAttribute.Create(context.Resolver.ResolveSystemType(typeof(ObsoleteAttribute).FullName).GetConstructor([]), [])); } internal void SetDeprecatedAttribute(ITypeSymbolBuilder tb) { - deprecatedAttribute ??= context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveSystemType(typeof(ObsoleteAttribute).FullName).GetConstructor([]), []); - tb.SetCustomAttribute(deprecatedAttribute); + tb.SetCustomAttribute(deprecatedAttribute ??= CustomAttribute.Create(context.Resolver.ResolveSystemType(typeof(ObsoleteAttribute).FullName).GetConstructor([]), [])); } internal void SetDeprecatedAttribute(IFieldSymbolBuilder fb) { - deprecatedAttribute ??= context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveSystemType(typeof(ObsoleteAttribute).FullName).GetConstructor([]), []); - fb.SetCustomAttribute(deprecatedAttribute); + fb.SetCustomAttribute(CustomAttribute.Create(context.Resolver.ResolveSystemType(typeof(ObsoleteAttribute).FullName).GetConstructor([]), [])); } internal void SetDeprecatedAttribute(IPropertySymbolBuilder pb) { - deprecatedAttribute ??= context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveSystemType(typeof(ObsoleteAttribute).FullName).GetConstructor([]), []); - pb.SetCustomAttribute(deprecatedAttribute); + pb.SetCustomAttribute(deprecatedAttribute ??= CustomAttribute.Create(context.Resolver.ResolveSystemType(typeof(ObsoleteAttribute).FullName).GetConstructor([]), [])); } internal void SetThrowsAttribute(IMethodBaseSymbolBuilder mb, string[] exceptions) @@ -437,26 +431,25 @@ internal void SetThrowsAttribute(IMethodBaseSymbolBuilder mb, string[] exception { throwsAttribute ??= TypeOfThrowsAttribute.GetConstructor([context.Types.String.MakeArrayType()]); exceptions = UnicodeUtil.EscapeInvalidSurrogates(exceptions); - mb.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(throwsAttribute, [exceptions])); + mb.SetCustomAttribute(CustomAttribute.Create(throwsAttribute, [exceptions])); } } internal void SetGhostInterface(ITypeSymbolBuilder typeBuilder) { - ghostInterfaceAttribute ??= context.Resolver.Symbols.CreateCustomAttribute(TypeOfGhostInterfaceAttribute.GetConstructor([]), []); - typeBuilder.SetCustomAttribute(ghostInterfaceAttribute); + typeBuilder.SetCustomAttribute(ghostInterfaceAttribute ??= CustomAttribute.Create(TypeOfGhostInterfaceAttribute.GetConstructor([]), [])); } internal void SetNonNestedInnerClass(ITypeSymbolBuilder typeBuilder, string className) { nonNestedInnerClassAttribute ??= TypeOfNonNestedInnerClassAttribute.GetConstructor([context.Types.String]); - typeBuilder.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(nonNestedInnerClassAttribute, [UnicodeUtil.EscapeInvalidSurrogates(className)])); + typeBuilder.SetCustomAttribute(CustomAttribute.Create(nonNestedInnerClassAttribute, [UnicodeUtil.EscapeInvalidSurrogates(className)])); } internal void SetNonNestedOuterClass(ITypeSymbolBuilder typeBuilder, string className) { nonNestedOuterClassAttribute ??= TypeOfNonNestedOuterClassAttribute.GetConstructor([context.Types.String]); - typeBuilder.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(nonNestedOuterClassAttribute, [UnicodeUtil.EscapeInvalidSurrogates(className)])); + typeBuilder.SetCustomAttribute(CustomAttribute.Create(nonNestedOuterClassAttribute, [UnicodeUtil.EscapeInvalidSurrogates(className)])); } #endif // IMPORTER @@ -488,7 +481,7 @@ internal void HideFromJava(IMethodBaseSymbolBuilder ctor) internal void HideFromJava(IMethodBaseSymbolBuilder mb, HideFromJavaFlags flags) { - mb.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(TypeOfHideFromJavaAttribute.GetConstructor([TypeOfHideFromJavaFlags]), [flags])); + mb.SetCustomAttribute(CustomAttribute.Create(TypeOfHideFromJavaAttribute.GetConstructor([TypeOfHideFromJavaFlags]), [flags])); } internal void HideFromJava(IFieldSymbolBuilder fb) @@ -547,7 +540,7 @@ internal void SetImplementsAttribute(ITypeSymbolBuilder typeBuilder, RuntimeJava if (implementsAttribute == null) implementsAttribute = TypeOfImplementsAttribute.GetConstructor([context.Types.String.MakeArrayType()]); - typeBuilder.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(implementsAttribute, [interfaces])); + typeBuilder.SetCustomAttribute(CustomAttribute.Create(implementsAttribute, [interfaces])); } internal bool IsGhostInterface(ITypeSymbol type) @@ -694,56 +687,20 @@ internal ExModifiers GetModifiers(IFieldSymbol fi, bool assemblyIsPrivate) internal void SetDebuggingModes(IAssemblySymbolBuilder assemblyBuilder, DebuggableAttribute.DebuggingModes modes) { debuggableAttribute ??= TypeOfDebuggableAttribute.GetConstructor([TypeOfDebuggableAttribute.GetNestedType(nameof(DebuggableAttribute.DebuggingModes))]); - assemblyBuilder.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(debuggableAttribute, [modes])); + assemblyBuilder.SetCustomAttribute(CustomAttribute.Create(debuggableAttribute, [modes])); } - internal void SetModifiers(IMethodBaseSymbolBuilder mb, Modifiers modifiers, bool isInternal) + internal void SetModifiers(ICustomAttributeProviderBuilder fb, Modifiers modifiers, bool isInternal) { - ICustomAttributeBuilder customAttributeBuilder; if (isInternal) - customAttributeBuilder = context.Resolver.Symbols.CreateCustomAttribute(TypeOfModifiersAttribute.GetConstructor([TypeOfModifiers, context.Types.Boolean]), [modifiers, isInternal]); + fb.SetCustomAttribute(CustomAttribute.Create(TypeOfModifiersAttribute.GetConstructor([TypeOfModifiers, context.Types.Boolean]), [modifiers, isInternal])); else - customAttributeBuilder = context.Resolver.Symbols.CreateCustomAttribute(TypeOfModifiersAttribute.GetConstructor([TypeOfModifiers]), [modifiers]); - - mb.SetCustomAttribute(customAttributeBuilder); - } - - internal void SetModifiers(IFieldSymbolBuilder fb, Modifiers modifiers, bool isInternal) - { - ICustomAttributeBuilder customAttributeBuilder; - if (isInternal) - customAttributeBuilder = context.Resolver.Symbols.CreateCustomAttribute(TypeOfModifiersAttribute.GetConstructor([TypeOfModifiers, context.Types.Boolean]), [modifiers, isInternal]); - else - customAttributeBuilder = context.Resolver.Symbols.CreateCustomAttribute(TypeOfModifiersAttribute.GetConstructor([TypeOfModifiers]), [modifiers]); - - fb.SetCustomAttribute(customAttributeBuilder); - } - - internal void SetModifiers(IPropertySymbolBuilder pb, Modifiers modifiers, bool isInternal) - { - ICustomAttributeBuilder customAttributeBuilder; - if (isInternal) - customAttributeBuilder = context.Resolver.Symbols.CreateCustomAttribute(TypeOfModifiersAttribute.GetConstructor([TypeOfModifiers, context.Types.Boolean]), [modifiers, isInternal]); - else - customAttributeBuilder = context.Resolver.Symbols.CreateCustomAttribute(TypeOfModifiersAttribute.GetConstructor([TypeOfModifiers]), [modifiers]); - - pb.SetCustomAttribute(customAttributeBuilder); - } - - internal void SetModifiers(ITypeSymbolBuilder tb, Modifiers modifiers, bool isInternal) - { - ICustomAttributeBuilder customAttributeBuilder; - if (isInternal) - customAttributeBuilder = context.Resolver.Symbols.CreateCustomAttribute(TypeOfModifiersAttribute.GetConstructor([TypeOfModifiers, context.Types.Boolean]), [modifiers, isInternal]); - else - customAttributeBuilder = context.Resolver.Symbols.CreateCustomAttribute(TypeOfModifiersAttribute.GetConstructor([TypeOfModifiers]), [modifiers]); - - tb.SetCustomAttribute(customAttributeBuilder); + fb.SetCustomAttribute(CustomAttribute.Create(TypeOfModifiersAttribute.GetConstructor([TypeOfModifiers]), [modifiers])); } internal void SetNameSig(IMethodBaseSymbolBuilder mb, string name, string sig) { - var customAttributeBuilder = context.Resolver.Symbols.CreateCustomAttribute(TypeOfNameSigAttribute.GetConstructor([context.Types.String, context.Types.String]), [UnicodeUtil.EscapeInvalidSurrogates(name), UnicodeUtil.EscapeInvalidSurrogates(sig)]); + var customAttributeBuilder = CustomAttribute.Create(TypeOfNameSigAttribute.GetConstructor([context.Types.String, context.Types.String]), [UnicodeUtil.EscapeInvalidSurrogates(name), UnicodeUtil.EscapeInvalidSurrogates(sig)]); mb.SetCustomAttribute(customAttributeBuilder); } @@ -752,20 +709,20 @@ internal void SetInnerClass(ITypeSymbolBuilder typeBuilder, string innerClass, M var argTypes = new ITypeSymbol[] { context.Types.String, TypeOfModifiers }; var args = new object[] { UnicodeUtil.EscapeInvalidSurrogates(innerClass), modifiers }; var ci = TypeOfInnerClassAttribute.GetConstructor(argTypes); - var customAttributeBuilder = context.Resolver.Symbols.CreateCustomAttribute(ci, args); + var customAttributeBuilder = CustomAttribute.Create(ci, args); typeBuilder.SetCustomAttribute(customAttributeBuilder); } internal void SetSourceFile(ITypeSymbolBuilder typeBuilder, string filename) { sourceFileAttribute ??= TypeOfSourceFileAttribute.GetConstructor([context.Types.String]); - typeBuilder.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(sourceFileAttribute, [filename])); + typeBuilder.SetCustomAttribute(CustomAttribute.Create(sourceFileAttribute, [filename])); } internal void SetSourceFile(IModuleSymbolBuilder moduleBuilder, string filename) { sourceFileAttribute ??= TypeOfSourceFileAttribute.GetConstructor([context.Types.String]); - moduleBuilder.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(sourceFileAttribute, [filename])); + moduleBuilder.SetCustomAttribute(CustomAttribute.Create(sourceFileAttribute, [filename])); } internal void SetLineNumberTable(IMethodBaseSymbolBuilder mb, IKVM.Attributes.LineNumberTableAttribute.LineNumberWriter writer) @@ -785,37 +742,37 @@ internal void SetLineNumberTable(IMethodBaseSymbolBuilder mb, IKVM.Attributes.Li arg = writer.ToArray(); } - mb.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(con, [arg])); + mb.SetCustomAttribute(CustomAttribute.Create(con, [arg])); } internal void SetEnclosingMethodAttribute(ITypeSymbolBuilder tb, string className, string methodName, string methodSig) { enclosingMethodAttribute ??= TypeOfEnclosingMethodAttribute.GetConstructor([context.Types.String, context.Types.String, context.Types.String]); - tb.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(enclosingMethodAttribute, [UnicodeUtil.EscapeInvalidSurrogates(className), UnicodeUtil.EscapeInvalidSurrogates(methodName), UnicodeUtil.EscapeInvalidSurrogates(methodSig)])); + tb.SetCustomAttribute(CustomAttribute.Create(enclosingMethodAttribute, [UnicodeUtil.EscapeInvalidSurrogates(className), UnicodeUtil.EscapeInvalidSurrogates(methodName), UnicodeUtil.EscapeInvalidSurrogates(methodSig)])); } internal void SetSignatureAttribute(ITypeSymbolBuilder tb, string signature) { signatureAttribute ??= TypeOfSignatureAttribute.GetConstructor([context.Types.String]); - tb.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(signatureAttribute, [UnicodeUtil.EscapeInvalidSurrogates(signature)])); + tb.SetCustomAttribute(CustomAttribute.Create(signatureAttribute, [UnicodeUtil.EscapeInvalidSurrogates(signature)])); } internal void SetSignatureAttribute(IFieldSymbolBuilder fb, string signature) { signatureAttribute ??= TypeOfSignatureAttribute.GetConstructor([context.Types.String]); - fb.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(signatureAttribute, [UnicodeUtil.EscapeInvalidSurrogates(signature)])); + fb.SetCustomAttribute(CustomAttribute.Create(signatureAttribute, [UnicodeUtil.EscapeInvalidSurrogates(signature)])); } internal void SetSignatureAttribute(IMethodBaseSymbolBuilder mb, string signature) { signatureAttribute ??= TypeOfSignatureAttribute.GetConstructor([context.Types.String]); - mb.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(signatureAttribute, [UnicodeUtil.EscapeInvalidSurrogates(signature)])); + mb.SetCustomAttribute(CustomAttribute.Create(signatureAttribute, [UnicodeUtil.EscapeInvalidSurrogates(signature)])); } internal void SetMethodParametersAttribute(IMethodBaseSymbolBuilder mb, Modifiers[] modifiers) { methodParametersAttribute ??= TypeOfMethodParametersAttribute.GetConstructor([TypeOfModifiers.MakeArrayType()]); - mb.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(methodParametersAttribute, [modifiers])); + mb.SetCustomAttribute(CustomAttribute.Create(methodParametersAttribute, [modifiers])); } internal void SetRuntimeVisibleTypeAnnotationsAttribute(ITypeSymbolBuilder tb, ref readonly TypeAnnotationTable table) @@ -825,7 +782,7 @@ internal void SetRuntimeVisibleTypeAnnotationsAttribute(ITypeSymbolBuilder tb, r table.WriteTo(ref encoder); runtimeVisibleTypeAnnotationsAttribute ??= TypeOfRuntimeVisibleTypeAnnotationsAttribute.GetConstructor([context.Types.Byte.MakeArrayType()]); - tb.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(runtimeVisibleTypeAnnotationsAttribute, [builder.ToArray()])); + tb.SetCustomAttribute(CustomAttribute.Create(runtimeVisibleTypeAnnotationsAttribute, [builder.ToArray()])); } internal void SetRuntimeVisibleTypeAnnotationsAttribute(IFieldSymbolBuilder fb, ref readonly TypeAnnotationTable table) @@ -835,7 +792,7 @@ internal void SetRuntimeVisibleTypeAnnotationsAttribute(IFieldSymbolBuilder fb, table.WriteTo(ref encoder); runtimeVisibleTypeAnnotationsAttribute ??= TypeOfRuntimeVisibleTypeAnnotationsAttribute.GetConstructor([context.Types.Byte.MakeArrayType()]); - fb.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(runtimeVisibleTypeAnnotationsAttribute, [builder.ToArray()])); + fb.SetCustomAttribute(CustomAttribute.Create(runtimeVisibleTypeAnnotationsAttribute, [builder.ToArray()])); } internal void SetRuntimeVisibleTypeAnnotationsAttribute(IMethodBaseSymbolBuilder mb, ref readonly TypeAnnotationTable table) @@ -845,19 +802,18 @@ internal void SetRuntimeVisibleTypeAnnotationsAttribute(IMethodBaseSymbolBuilder table.WriteTo(ref encoder); runtimeVisibleTypeAnnotationsAttribute ??= TypeOfRuntimeVisibleTypeAnnotationsAttribute.GetConstructor([context.Types.Byte.MakeArrayType()]); - mb.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(runtimeVisibleTypeAnnotationsAttribute, [builder.ToArray()])); + mb.SetCustomAttribute(CustomAttribute.Create(runtimeVisibleTypeAnnotationsAttribute, [builder.ToArray()])); } internal void SetConstantPoolAttribute(ITypeSymbolBuilder tb, object[] constantPool) { constantPoolAttribute ??= TypeOfConstantPoolAttribute.GetConstructor([context.Types.Object.MakeArrayType()]); - tb.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(constantPoolAttribute, [constantPool])); + tb.SetCustomAttribute(CustomAttribute.Create(constantPoolAttribute, [constantPool])); } internal void SetParamArrayAttribute(IParameterSymbolBuilder pb) { - paramArrayAttribute ??= context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveCoreType(typeof(ParamArrayAttribute).FullName).GetConstructor([]), []); - pb.SetCustomAttribute(paramArrayAttribute); + pb.SetCustomAttribute(paramArrayAttribute ??= CustomAttribute.Create(context.Resolver.ResolveCoreType(typeof(ParamArrayAttribute).FullName).GetConstructor([]), [])); } internal NameSigAttribute GetNameSig(IMemberSymbol member) @@ -903,11 +859,11 @@ internal ThrowsAttribute GetThrows(IMethodBaseSymbol mb) } else if (args[0].ArgumentType == context.Types.Type.MakeArrayType()) { - return new ThrowsAttribute(DecodeArray(args[0]).AsReflection()); + return new ThrowsAttribute(DecodeArray(args[0]).GetUnderlyingTypes()); } else { - return new ThrowsAttribute(((ITypeSymbol)args[0].Value).AsReflection()); + return new ThrowsAttribute(((ITypeSymbol)args[0].Value).GetUnderlyingType()); } } @@ -989,7 +945,7 @@ internal RemappedInterfaceMethodAttribute[] GetRemappedInterfaceMethods(ITypeSym internal RemappedTypeAttribute GetRemappedType(ITypeSymbol type) { foreach (var cad in type.GetCustomAttributes(TypeOfRemappedTypeAttribute)) - return new RemappedTypeAttribute(((ITypeSymbol)cad.ConstructorArguments[0].Value).AsReflection()); + return new RemappedTypeAttribute(((ITypeSymbol)cad.ConstructorArguments[0].Value).GetUnderlyingType()); return null; } @@ -1004,7 +960,7 @@ internal RemappedClassAttribute[] GetRemappedClasses(IAssemblySymbol coreAssembl foreach (var cad in coreAssembly.GetCustomAttributes(TypeOfRemappedClassAttribute)) { var args = cad.ConstructorArguments; - attrs.Add(new RemappedClassAttribute((string)args[0].Value, ((ITypeSymbol)args[1].Value).AsReflection())); + attrs.Add(new RemappedClassAttribute((string)args[0].Value, ((ITypeSymbol)args[1].Value).GetUnderlyingType())); } return attrs.ToArray(); @@ -1097,43 +1053,43 @@ internal IKVM.Attributes.EnclosingMethodAttribute GetEnclosingMethodAttribute(IT internal void SetRemappedClass(IAssemblySymbolBuilder assemblyBuilder, string name, ITypeSymbol shadowType) { var remappedClassAttribute = TypeOfRemappedClassAttribute.GetConstructor([context.Types.String, context.Types.Type]); - assemblyBuilder.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(remappedClassAttribute, [name, shadowType])); + assemblyBuilder.SetCustomAttribute(CustomAttribute.Create(remappedClassAttribute, [name, shadowType])); } internal void SetRemappedType(ITypeSymbolBuilder typeBuilder, ITypeSymbol shadowType) { var remappedTypeAttribute = TypeOfRemappedTypeAttribute.GetConstructor([context.Types.Type]); - typeBuilder.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(remappedTypeAttribute, [shadowType])); + typeBuilder.SetCustomAttribute(CustomAttribute.Create(remappedTypeAttribute, [shadowType])); } internal void SetRemappedInterfaceMethod(ITypeSymbolBuilder typeBuilder, string name, string mappedTo, string[] throws) { - var cab = context.Resolver.Symbols.CreateCustomAttribute(TypeOfRemappedInterfaceMethodAttribute.GetConstructor([context.Types.String, context.Types.String, context.Types.String.MakeArrayType()]), [name, mappedTo, throws]); + var cab = CustomAttribute.Create(TypeOfRemappedInterfaceMethodAttribute.GetConstructor([context.Types.String, context.Types.String, context.Types.String.MakeArrayType()]), [name, mappedTo, throws]); typeBuilder.SetCustomAttribute(cab); } internal void SetExceptionIsUnsafeForMapping(ITypeSymbolBuilder typeBuilder) { - var cab = context.Resolver.Symbols.CreateCustomAttribute(TypeOfExceptionIsUnsafeForMappingAttribute.GetConstructor([]), []); + var cab = CustomAttribute.Create(TypeOfExceptionIsUnsafeForMappingAttribute.GetConstructor([]), []); typeBuilder.SetCustomAttribute(cab); } internal void SetRuntimeCompatibilityAttribute(IAssemblySymbolBuilder assemblyBuilder) { var runtimeCompatibilityAttribute = context.Resolver.ResolveCoreType(typeof(RuntimeCompatibilityAttribute).FullName); - assemblyBuilder.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(runtimeCompatibilityAttribute.GetConstructor([]), [], [runtimeCompatibilityAttribute.GetProperty("WrapNonExceptionThrows")], [true], [], [])); + assemblyBuilder.SetCustomAttribute(CustomAttribute.Create(runtimeCompatibilityAttribute.GetConstructor([]), [], [runtimeCompatibilityAttribute.GetProperty("WrapNonExceptionThrows")], [true], [], [])); } internal void SetInternalsVisibleToAttribute(IAssemblySymbolBuilder assemblyBuilder, string assemblyName) { var internalsVisibleToAttribute = context.Resolver.ResolveCoreType(typeof(InternalsVisibleToAttribute).FullName); - var cab = context.Resolver.Symbols.CreateCustomAttribute(internalsVisibleToAttribute.GetConstructor([context.Types.String]), [assemblyName]); + var cab = CustomAttribute.Create(internalsVisibleToAttribute.GetConstructor([context.Types.String]), [assemblyName]); assemblyBuilder.SetCustomAttribute(cab); } internal void SetCustomAssemblyClassLoaderAttribute(IAssemblySymbolBuilder assemblyBuilder, ITypeSymbol classLoaderType) { - var cab = context.Resolver.Symbols.CreateCustomAttribute(TypeOfCustomAssemblyClassLoaderAttribute.GetConstructor([context.Types.Type]), [classLoaderType]); + var cab = CustomAttribute.Create(TypeOfCustomAssemblyClassLoaderAttribute.GetConstructor([context.Types.Type]), [classLoaderType]); assemblyBuilder.SetCustomAttribute(cab); } diff --git a/src/IKVM.Runtime/ByteCodeHelper.cs b/src/IKVM.Runtime/ByteCodeHelper.cs index 5ba3bd635..a4b6db89a 100644 --- a/src/IKVM.Runtime/ByteCodeHelper.cs +++ b/src/IKVM.Runtime/ByteCodeHelper.cs @@ -128,7 +128,7 @@ public static object DynamicMultianewarray(int[] lengths, global::java.lang.Clas Profiler.Count("DynamicMultianewarray"); var wrapper = RuntimeJavaType.FromClass(clazz); - var obj = multianewarray(wrapper.TypeAsArrayType.AsReflection().TypeHandle, lengths); + var obj = multianewarray(wrapper.TypeAsArrayType.GetUnderlyingType().TypeHandle, lengths); if (wrapper.IsGhostArray) GhostTag.SetTag(obj, wrapper); @@ -147,7 +147,7 @@ public static object DynamicNewarray(int length, global::java.lang.Class clazz) throw new global::java.lang.NegativeArraySizeException(); var wrapper = RuntimeJavaType.FromClass(clazz); - var obj = Array.CreateInstance(wrapper.TypeAsArrayType.AsReflection(), length); + var obj = Array.CreateInstance(wrapper.TypeAsArrayType.GetUnderlyingType(), length); if (wrapper.IsGhost || wrapper.IsGhostArray) GhostTag.SetTag(obj, wrapper.MakeArrayType(1)); @@ -1108,7 +1108,7 @@ public static Exception DynamicMapException(Exception x, MapFlags mode, global:: mode |= MapFlags.NoRemapping; var exceptionType = exceptionTypeWrapper == JVM.Context.JavaBase.TypeOfjavaLangThrowable ? JVM.Context.Resolver.ResolveCoreType(typeof(System.Exception).FullName) : exceptionTypeWrapper.TypeAsBaseType; - return (Exception)JVM.Context.ByteCodeHelperMethods.MapException.MakeGenericMethod(exceptionType).AsReflection().Invoke(null, [x, mode]); + return (Exception)JVM.Context.ByteCodeHelperMethods.MapException.MakeGenericMethod(exceptionType).GetUnderlyingMethod().Invoke(null, [x, mode]); #endif } diff --git a/src/IKVM.Runtime/DynamicClassLoader.cs b/src/IKVM.Runtime/DynamicClassLoader.cs index ab9860866..2e906c98e 100644 --- a/src/IKVM.Runtime/DynamicClassLoader.cs +++ b/src/IKVM.Runtime/DynamicClassLoader.cs @@ -34,6 +34,8 @@ Jeroen Frijters using static System.Diagnostics.DebuggableAttribute; using IKVM.CoreLib.Symbols.Reflection; +using System.Collections.Immutable; + @@ -108,7 +110,7 @@ Assembly Resolve(ConcurrentDictionary dict, string name try { type.Finish(); - return type.TypeAsTBD.Assembly.AsReflection(); + return type.TypeAsTBD.Assembly.GetUnderlyingAssembly(); } catch (RetargetableJavaException e) { @@ -450,7 +452,7 @@ internal void FinishAll() internal static IModuleSymbolBuilder CreateJniProxyModuleBuilder(RuntimeContext context) { - jniProxyAssemblyBuilder = DefineDynamicAssembly(context, new AssemblyIdentity("jniproxy"), null); + jniProxyAssemblyBuilder = DefineDynamicAssembly(context, new AssemblyIdentity("jniproxy"), []); return jniProxyAssemblyBuilder.DefineModule("jniproxy.dll"); } @@ -545,9 +547,9 @@ public static IModuleSymbolBuilder CreateModuleBuilder(RuntimeContext context, A name.ContentType, name.ProcessorArchitecture); - var attribs = Array.Empty(); + var attribs = ImmutableArray.Empty; if (AppDomain.CurrentDomain.IsFullyTrusted == false) - attribs = [context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveCoreType(typeof(System.Security.SecurityTransparentAttribute).FullName).GetConstructor([]), [])]; + attribs = [CustomAttribute.Create(context.Resolver.ResolveCoreType(typeof(System.Security.SecurityTransparentAttribute).FullName).GetConstructor([]), [])]; var assemblyBuilder = DefineDynamicAssembly(context, name, attribs); context.AttributeHelper.SetRuntimeCompatibilityAttribute(assemblyBuilder); @@ -562,7 +564,7 @@ public static IModuleSymbolBuilder CreateModuleBuilder(RuntimeContext context, A // create new module var moduleBuilder = assemblyBuilder.DefineModule(name.Name, null, context.Options.EmitSymbols); - moduleBuilder.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveRuntimeType(typeof(IKVM.Attributes.JavaModuleAttribute).FullName).GetConstructor([]), [])); + moduleBuilder.SetCustomAttribute(CustomAttribute.Create(context.Resolver.ResolveRuntimeType(typeof(IKVM.Attributes.JavaModuleAttribute).FullName).GetConstructor([]), [])); return moduleBuilder; } @@ -573,7 +575,7 @@ public static IModuleSymbolBuilder CreateModuleBuilder(RuntimeContext context, A /// /// /// - static IAssemblySymbolBuilder DefineDynamicAssembly(RuntimeContext context, AssemblyIdentity name, ICustomAttributeBuilder[] assemblyAttributes) + static IAssemblySymbolBuilder DefineDynamicAssembly(RuntimeContext context, AssemblyIdentity name, ImmutableArray assemblyAttributes) { return context.Resolver.Symbols.DefineAssembly(name, assemblyAttributes, false, false); } diff --git a/src/IKVM.Runtime/JNI/JNIEnv.cs b/src/IKVM.Runtime/JNI/JNIEnv.cs index 6daad51be..789832c73 100644 --- a/src/IKVM.Runtime/JNI/JNIEnv.cs +++ b/src/IKVM.Runtime/JNI/JNIEnv.cs @@ -628,9 +628,9 @@ static nint AllocObjectImpl(JNIEnv* pEnv, RuntimeJavaType wrapper) wrapper.Finish(); #if NETFRAMEWORK - return pEnv->MakeLocalRef(FormatterServices.GetUninitializedObject(wrapper.TypeAsBaseType.AsReflection())); + return pEnv->MakeLocalRef(FormatterServices.GetUninitializedObject(wrapper.TypeAsBaseType.GetUnderlyingType())); #else - return pEnv->MakeLocalRef(RuntimeHelpers.GetUninitializedObject(wrapper.TypeAsBaseType.AsReflection())); + return pEnv->MakeLocalRef(RuntimeHelpers.GetUninitializedObject(wrapper.TypeAsBaseType.GetUnderlyingType())); #endif } catch (RetargetableJavaException e) @@ -709,7 +709,7 @@ static object InvokeHelper(JNIEnv* pEnv, nint objHandle, nint methodID, JValue* // possible with remapped types throw new NotSupportedException($"Remapped type {mw.DeclaringType.Name} doesn't support constructor invocation on an existing instance"); } - else if (!mb.DeclaringType.AsReflection().IsInstanceOfType(obj)) + else if (!mb.DeclaringType.GetUnderlyingType().IsInstanceOfType(obj)) { // we're trying to initialize an existing instance of a remapped type throw new NotSupportedException($"Unable to partially construct object of type {obj.GetType().FullName} to type {mb.DeclaringType.FullName}"); @@ -734,10 +734,10 @@ static object InvokeNonVirtual(JNIEnvContext env, RuntimeJavaMethod mw, object o if (mw.HasCallerID || mw.IsDynamicOnly) throw new NotSupportedException(); - if (mw.DeclaringType.IsRemapped && !mw.DeclaringType.TypeAsBaseType.AsReflection().IsInstanceOfType(obj)) + if (mw.DeclaringType.IsRemapped && !mw.DeclaringType.TypeAsBaseType.GetUnderlyingType().IsInstanceOfType(obj)) return mw.InvokeNonvirtualRemapped(obj, argarray); - var del = (Delegate)Activator.CreateInstance(mw.GetDelegateType().AsReflection(), [obj, mw.GetMethod().AsReflection().MethodHandle.GetFunctionPointer()]); + var del = (Delegate)Activator.CreateInstance(mw.GetDelegateType().GetUnderlyingType(), [obj, mw.GetMethod().GetUnderlyingMethodBase().MethodHandle.GetFunctionPointer()]); try { return del.DynamicInvoke(argarray); @@ -2157,7 +2157,7 @@ internal static nint NewObjectArray(JNIEnv* pEnv, jsize len, nint clazz, nint in try { // we want to support (non-primitive) value types so we can't cast to object[] - var a = Array.CreateInstance(RuntimeJavaType.FromClass((java.lang.Class)pEnv->UnwrapRef(clazz)).TypeAsArrayType.AsReflection(), len); + var a = Array.CreateInstance(RuntimeJavaType.FromClass((java.lang.Class)pEnv->UnwrapRef(clazz)).TypeAsArrayType.GetUnderlyingType(), len); var o = pEnv->UnwrapRef(init); if (o != null) for (int i = 0; i < a.Length; i++) @@ -2776,7 +2776,7 @@ internal static jint RegisterNatives(JNIEnv* pEnv, nint clazz, JNINativeMethod* // don't allow dotted names! if (methodSig.IndexOf('.') < 0) - fi = wrapper.TypeAsTBD.GetField(METHOD_PTR_FIELD_PREFIX + methodName + methodSig, BindingFlags.Static | BindingFlags.NonPublic).AsReflection(); + fi = wrapper.TypeAsTBD.GetField(METHOD_PTR_FIELD_PREFIX + methodName + methodSig, BindingFlags.Static | BindingFlags.NonPublic).GetUnderlyingField(); if (fi == null) { diff --git a/src/IKVM.Runtime/JVM.Internal.cs b/src/IKVM.Runtime/JVM.Internal.cs index c2c71d615..1ff5d56f9 100644 --- a/src/IKVM.Runtime/JVM.Internal.cs +++ b/src/IKVM.Runtime/JVM.Internal.cs @@ -39,7 +39,7 @@ internal static class Internal static ThreadGroupAccessor threadGroupAccessor; static SystemAccessor systemAccessor; - internal static AccessorCache BaseAccessors => AccessorCache.Get(ref baseAccessors, context.Resolver.GetBaseAssembly().AsReflection()); + internal static AccessorCache BaseAccessors => AccessorCache.Get(ref baseAccessors, context.Resolver.GetBaseAssembly().GetUnderlyingAssembly()); internal static ThreadGroupAccessor ThreadGroupAccessor => BaseAccessors.Get(ref threadGroupAccessor); diff --git a/src/IKVM.Runtime/JVM.Properties.cs b/src/IKVM.Runtime/JVM.Properties.cs index f97f9f49e..0d3af177d 100644 --- a/src/IKVM.Runtime/JVM.Properties.cs +++ b/src/IKVM.Runtime/JVM.Properties.cs @@ -272,7 +272,7 @@ static void InitSystemProperties(Dictionary p) p["java.ext.dirs"] = Path.Combine(HomePath, "lib", "ext"); p["java.endorsed.dirs"] = Path.Combine(HomePath, "lib", "endorsed"); p["sun.boot.library.path"] = GetBootLibraryPath(); - p["sun.boot.class.path"] = VfsTable.GetAssemblyClassesPath(Vfs.Context, Context.Resolver.GetBaseAssembly().AsReflection(), HomePath); + p["sun.boot.class.path"] = VfsTable.GetAssemblyClassesPath(Vfs.Context, Context.Resolver.GetBaseAssembly().GetUnderlyingAssembly(), HomePath); p["sun.cds.enableSharedLookupCache"] = "false"; // unlimited direct memory diff --git a/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Util.cs b/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Util.cs index 2da52208a..530a59697 100644 --- a/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Util.cs +++ b/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Util.cs @@ -24,7 +24,6 @@ Jeroen Frijters using System; using IKVM.Attributes; -using IKVM.CoreLib.Symbols; using IKVM.CoreLib.Symbols.Emit; using IKVM.Runtime; @@ -168,9 +167,9 @@ public static Type getInstanceTypeFromClass(global::java.lang.Class classObject) { var wrapper = RuntimeJavaType.FromClass(classObject); if (wrapper.IsRemapped && wrapper.IsFinal) - return wrapper.TypeAsTBD.AsReflection(); + return wrapper.TypeAsTBD.GetUnderlyingRuntimeType(); else - return wrapper.TypeAsBaseType.AsReflection(); + return wrapper.TypeAsBaseType.GetUnderlyingRuntimeType(); } /// @@ -184,9 +183,9 @@ public static Type getRuntimeTypeFromClass(global::java.lang.Class classObject) wrapper.Finish(); if (wrapper.IsRemapped && wrapper.IsFinal) - return wrapper.TypeAsTBD.AsReflection(); + return wrapper.TypeAsTBD.GetUnderlyingRuntimeType(); else - return wrapper.TypeAsBaseType.AsReflection(); + return wrapper.TypeAsBaseType.GetUnderlyingRuntimeType(); } [HideFromJava] diff --git a/src/IKVM.Runtime/Java/Externs/java/io/ObjectStreamClass.cs b/src/IKVM.Runtime/Java/Externs/java/io/ObjectStreamClass.cs index abe35f952..9208087fd 100644 --- a/src/IKVM.Runtime/Java/Externs/java/io/ObjectStreamClass.cs +++ b/src/IKVM.Runtime/Java/Externs/java/io/ObjectStreamClass.cs @@ -256,10 +256,10 @@ internal FastFieldReflector(global::java.io.ObjectStreamField[] fields) throw x.ToJava(); } - var dmObjGetter = DynamicMethodUtil.Create("__", tw.TypeAsBaseType.AsReflection(), true, null, [typeof(object), typeof(object[])]); - var dmPrimGetter = DynamicMethodUtil.Create("__", tw.TypeAsBaseType.AsReflection(), true, null, [typeof(object), typeof(byte[])]); - var dmObjSetter = DynamicMethodUtil.Create("__", tw.TypeAsBaseType.AsReflection(), true, null, [typeof(object), typeof(object[])]); - var dmPrimSetter = DynamicMethodUtil.Create("__", tw.TypeAsBaseType.AsReflection(), true, null, [typeof(object), typeof(byte[])]); + var dmObjGetter = DynamicMethodUtil.Create("__", tw.TypeAsBaseType.GetUnderlyingType(), true, null, [typeof(object), typeof(object[])]); + var dmPrimGetter = DynamicMethodUtil.Create("__", tw.TypeAsBaseType.GetUnderlyingType(), true, null, [typeof(object), typeof(byte[])]); + var dmObjSetter = DynamicMethodUtil.Create("__", tw.TypeAsBaseType.GetUnderlyingType(), true, null, [typeof(object), typeof(object[])]); + var dmPrimSetter = DynamicMethodUtil.Create("__", tw.TypeAsBaseType.GetUnderlyingType(), true, null, [typeof(object), typeof(byte[])]); var ilgenObjGetter = JVM.Context.CodeEmitterFactory.Create(dmObjGetter); var ilgenPrimGetter = JVM.Context.CodeEmitterFactory.Create(dmPrimGetter); var ilgenObjSetter = JVM.Context.CodeEmitterFactory.Create(dmObjSetter); diff --git a/src/IKVM.Runtime/Java/Externs/java/lang/Package.cs b/src/IKVM.Runtime/Java/Externs/java/lang/Package.cs index e98641d5f..051ccbe75 100644 --- a/src/IKVM.Runtime/Java/Externs/java/lang/Package.cs +++ b/src/IKVM.Runtime/Java/Externs/java/lang/Package.cs @@ -48,7 +48,7 @@ static void LazyInitSystemPackages() if (systemPackages == null) { var dict = new Dictionary(); - var path = Path.Combine(VfsTable.GetAssemblyResourcesPath(JVM.Vfs.Context, JVM.Context.Resolver.GetBaseAssembly().AsReflection(), JVM.Properties.HomePath), "resources.jar"); + var path = Path.Combine(VfsTable.GetAssemblyResourcesPath(JVM.Vfs.Context, JVM.Context.Resolver.GetBaseAssembly().GetUnderlyingAssembly(), JVM.Properties.HomePath), "resources.jar"); foreach (var pkgs in JVM.Context.ClassLoaderFactory.GetBootstrapClassLoader().GetPackageInfo()) foreach (var pkg in pkgs.Value) dict[pkg.Replace('.', '/') + "/"] = path; diff --git a/src/IKVM.Runtime/Java/Externs/java/lang/invoke/MethodHandleNatives.cs b/src/IKVM.Runtime/Java/Externs/java/lang/invoke/MethodHandleNatives.cs index db53ee23a..778db45f8 100644 --- a/src/IKVM.Runtime/Java/Externs/java/lang/invoke/MethodHandleNatives.cs +++ b/src/IKVM.Runtime/Java/Externs/java/lang/invoke/MethodHandleNatives.cs @@ -378,7 +378,7 @@ static Delegate CreateMemberNameDelegate(RuntimeJavaMethod mw, global::java.lang && tw.Context.MethodHandleUtil.HasOnlyBasicTypes(mw.GetParameters(), mw.ReturnType) && type.parameterCount() <= MethodHandleUtil.MaxArity) { - return Delegate.CreateDelegate(tw.Context.MethodHandleUtil.CreateMemberWrapperDelegateType(mw.GetParameters(), mw.ReturnType).AsReflection(), mi); + return Delegate.CreateDelegate(tw.Context.MethodHandleUtil.CreateMemberWrapperDelegateType(mw.GetParameters(), mw.ReturnType).GetUnderlyingType(), mi); } else { @@ -466,7 +466,7 @@ public static object staticFieldBase(global::java.lang.invoke.MemberName self) internal static void InitializeCallSite(global::java.lang.invoke.CallSite site) { - var type = typeof(IKVM.Runtime.IndyCallSite<>).MakeGenericType(JVM.Context.MethodHandleUtil.GetDelegateTypeForInvokeExact(site.type()).AsReflection()); + var type = typeof(IKVM.Runtime.IndyCallSite<>).MakeGenericType(JVM.Context.MethodHandleUtil.GetDelegateTypeForInvokeExact(site.type()).GetUnderlyingType()); var ics = (IKVM.Runtime.IIndyCallSite)Activator.CreateInstance(type, true); Interlocked.CompareExchange(ref site.ics, ics, null); } diff --git a/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Array.cs b/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Array.cs index f19c102fe..a42d11e82 100644 --- a/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Array.cs +++ b/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Array.cs @@ -609,7 +609,7 @@ public static object newArray(global::java.lang.Class componentType, int length) var wrapper = RuntimeJavaType.FromClass(componentType); wrapper.Finish(); - var obj = global::System.Array.CreateInstance(wrapper.TypeAsArrayType.AsReflection(), length); + var obj = global::System.Array.CreateInstance(wrapper.TypeAsArrayType.GetUnderlyingType(), length); if (wrapper.IsGhost || wrapper.IsGhostArray) IKVM.Runtime.GhostTag.SetTag(obj, wrapper.MakeArrayType(1)); @@ -646,7 +646,7 @@ public static object multiNewArray(global::java.lang.Class componentType, int[] var wrapper = RuntimeJavaType.FromClass(componentType).MakeArrayType(dimensions.Length); wrapper.Finish(); - var obj = IKVM.Runtime.ByteCodeHelper.multianewarray(wrapper.TypeAsArrayType.AsReflection().TypeHandle, dimensions); + var obj = IKVM.Runtime.ByteCodeHelper.multianewarray(wrapper.TypeAsArrayType.GetUnderlyingType().TypeHandle, dimensions); if (wrapper.IsGhostArray) IKVM.Runtime.GhostTag.SetTag(obj, wrapper); diff --git a/src/IKVM.Runtime/Java/Externs/sun/misc/Unsafe.cs b/src/IKVM.Runtime/Java/Externs/sun/misc/Unsafe.cs index d27e19065..f2faef90c 100644 --- a/src/IKVM.Runtime/Java/Externs/sun/misc/Unsafe.cs +++ b/src/IKVM.Runtime/Java/Externs/sun/misc/Unsafe.cs @@ -1734,9 +1734,9 @@ public static object allocateInstance(object self, global::java.lang.Class cls) } #if NETFRAMEWORK - return FormatterServices.GetUninitializedObject(wrapper.TypeAsBaseType.AsReflection()); + return FormatterServices.GetUninitializedObject(wrapper.TypeAsBaseType.GetUnderlyingType()); #else - return RuntimeHelpers.GetUninitializedObject(wrapper.TypeAsBaseType.AsReflection()); + return RuntimeHelpers.GetUninitializedObject(wrapper.TypeAsBaseType.GetUnderlyingType()); #endif } @@ -1854,8 +1854,8 @@ static void PutFieldVolatile(object o, long offset, T value) /// static Delegate CreateGetArrayVolatileDelegate(RuntimeJavaType tw) { - var et = tw.IsPrimitive ? tw.TypeAsTBD.AsReflection() : typeof(object); - var dm = DynamicMethodUtil.Create($"____{tw.Name.Replace(".", "_")}", tw.TypeAsTBD.AsReflection(), true, et, new[] { typeof(object[]), typeof(long) }); + var et = tw.IsPrimitive ? tw.TypeAsTBD.GetUnderlyingType() : typeof(object); + var dm = DynamicMethodUtil.Create($"____{tw.Name.Replace(".", "_")}", tw.TypeAsTBD.GetUnderlyingType(), true, et, new[] { typeof(object[]), typeof(long) }); var il = dm.GetILGenerator(); // load reference to element @@ -1865,17 +1865,17 @@ static Delegate CreateGetArrayVolatileDelegate(RuntimeJavaType tw) il.Emit(OpCodes.Ldc_I4, ArrayIndexScale(tw.MakeArrayType(1))); il.Emit(OpCodes.Div); il.Emit(OpCodes.Conv_Ovf_I); - il.Emit(OpCodes.Ldelema, tw.TypeAsLocalOrStackType.AsReflection()); + il.Emit(OpCodes.Ldelema, tw.TypeAsLocalOrStackType.GetUnderlyingType()); if (tw.IsWidePrimitive == false) { il.Emit(OpCodes.Volatile); - EmitLdind(il, tw.TypeAsLocalOrStackType.AsReflection()); + EmitLdind(il, tw.TypeAsLocalOrStackType.GetUnderlyingType()); } else { // Java volatile semantics require atomicity, CLR volatile semantics do not - var mi = typeof(Unsafe).GetMethod(nameof(InterlockedRead), BindingFlags.NonPublic | BindingFlags.Static, null, new[] { tw.TypeAsTBD.MakeByRefType().AsReflection() }, null); + var mi = typeof(Unsafe).GetMethod(nameof(InterlockedRead), BindingFlags.NonPublic | BindingFlags.Static, null, new[] { tw.TypeAsTBD.MakeByRefType().GetUnderlyingType() }, null); il.Emit(OpCodes.Call, mi); } @@ -1912,8 +1912,8 @@ static object GetArrayObjectVolatile(object[] array, long offset) /// static Delegate CreatePutArrayVolatileDelegate(RuntimeJavaType tw) { - var et = tw.IsPrimitive ? tw.TypeAsTBD.AsReflection() : typeof(object); - var dm = DynamicMethodUtil.Create($"____{tw.Name.Replace(".", "_")}", tw.TypeAsTBD.AsReflection(), true, typeof(void), new[] { typeof(object[]), typeof(long), et }); + var et = tw.IsPrimitive ? tw.TypeAsTBD.GetUnderlyingType() : typeof(object); + var dm = DynamicMethodUtil.Create($"____{tw.Name.Replace(".", "_")}", tw.TypeAsTBD.GetUnderlyingType(), true, typeof(void), new[] { typeof(object[]), typeof(long), et }); var il = dm.GetILGenerator(); // load reference to element @@ -1923,19 +1923,19 @@ static Delegate CreatePutArrayVolatileDelegate(RuntimeJavaType tw) il.Emit(OpCodes.Ldc_I4, ArrayIndexScale(tw.MakeArrayType(1))); il.Emit(OpCodes.Div); il.Emit(OpCodes.Conv_Ovf_I); - il.Emit(OpCodes.Ldelema, tw.TypeAsLocalOrStackType.AsReflection()); + il.Emit(OpCodes.Ldelema, tw.TypeAsLocalOrStackType.GetUnderlyingType()); il.Emit(OpCodes.Ldarg_2); if (tw.IsWidePrimitive == false) { il.Emit(OpCodes.Volatile); - EmitStind(il, tw.TypeAsLocalOrStackType.AsReflection()); + EmitStind(il, tw.TypeAsLocalOrStackType.GetUnderlyingType()); } else { // Java volatile semantics require atomicity, CLR volatile semantics do not - var mi = typeof(Interlocked).GetMethod(nameof(Interlocked.Exchange), new[] { tw.TypeAsTBD.MakeByRefType().AsReflection() }); + var mi = typeof(Interlocked).GetMethod(nameof(Interlocked.Exchange), new[] { tw.TypeAsTBD.MakeByRefType().GetUnderlyingType() }); il.Emit(OpCodes.Call, mi); } @@ -2475,11 +2475,11 @@ static Delegate CreateCompareExchangeArrayDelegate(RuntimeJavaType tw) var e = Expression.Parameter(typeof(object)); return Expression.Lambda>( Expression.Call( - compareAndSwapArrayMethodInfo.MakeGenericMethod(tw.TypeAsTBD.AsReflection()), - Expression.Convert(p, tw.MakeArrayType(1).TypeAsTBD.AsReflection()), + compareAndSwapArrayMethodInfo.MakeGenericMethod(tw.TypeAsTBD.GetUnderlyingType()), + Expression.Convert(p, tw.MakeArrayType(1).TypeAsTBD.GetUnderlyingType()), i, - Expression.Convert(v, tw.TypeAsTBD.AsReflection()), - Expression.Convert(e, tw.TypeAsTBD.AsReflection())), + Expression.Convert(v, tw.TypeAsTBD.GetUnderlyingType()), + Expression.Convert(e, tw.TypeAsTBD.GetUnderlyingType())), p, i, v, e) .Compile(); } diff --git a/src/IKVM.Runtime/Java/Externs/sun/misc/VM.cs b/src/IKVM.Runtime/Java/Externs/sun/misc/VM.cs index 02e611e84..4a99fea26 100644 --- a/src/IKVM.Runtime/Java/Externs/sun/misc/VM.cs +++ b/src/IKVM.Runtime/Java/Externs/sun/misc/VM.cs @@ -64,7 +64,7 @@ public static void initialize() // check that the assembly isn't the .NET corelib or the IKVM runtime var clw = tw.ClassLoader; if (clw is RuntimeAssemblyClassLoader acl) - if (acl.GetAssembly(tw) == JVM.Context.Types.Object.Assembly || acl.GetAssembly(tw).AsReflection() == typeof(VM).Assembly) + if (acl.GetAssembly(tw) == JVM.Context.Types.Object.Assembly || acl.GetAssembly(tw).GetUnderlyingAssembly() == typeof(VM).Assembly) continue; // associated Java class loader is our nearest diff --git a/src/IKVM.Runtime/Java/Externs/sun/reflect/ReflectionFactory.cs b/src/IKVM.Runtime/Java/Externs/sun/reflect/ReflectionFactory.cs index ab9c1a1b1..c898acb33 100644 --- a/src/IKVM.Runtime/Java/Externs/sun/reflect/ReflectionFactory.cs +++ b/src/IKVM.Runtime/Java/Externs/sun/reflect/ReflectionFactory.cs @@ -286,9 +286,9 @@ internal SerializationConstructorAccessorImpl(global::java.lang.reflect.Construc public object newInstance(object[] args) { #if NETFRAMEWORK - var obj = FormatterServices.GetUninitializedObject(type.AsReflection()); + var obj = FormatterServices.GetUninitializedObject(type.GetUnderlyingType()); #else - var obj = RuntimeHelpers.GetUninitializedObject(type.AsReflection()); + var obj = RuntimeHelpers.GetUninitializedObject(type.GetUnderlyingType()); #endif if (mw != null) mw.Invoke(obj, ConvertArgs(mw.DeclaringType.ClassLoader, mw.GetParameters(), args)); @@ -587,7 +587,7 @@ internal unsafe FastMethodAccessorImpl(RuntimeJavaMethod mw) // generate new dynamic method var np = !mw.IsPublic || !mw.DeclaringType.IsPublic; - var dm = DynamicMethodUtil.Create($"____{mw.DeclaringType.Name.Replace(".", "_")}__{mw.Name}", mw.DeclaringType.TypeAsBaseType.AsReflection(), np, typeof(object), new[] { typeof(object), typeof(object[]), typeof(global::ikvm.@internal.CallerID) }); + var dm = DynamicMethodUtil.Create($"____{mw.DeclaringType.Name.Replace(".", "_")}__{mw.Name}", mw.DeclaringType.TypeAsBaseType.GetUnderlyingType(), np, typeof(object), new[] { typeof(object), typeof(object[]), typeof(global::ikvm.@internal.CallerID) }); var il = JVM.Context.CodeEmitterFactory.Create(dm); // labels @@ -831,7 +831,7 @@ internal FastConstructorAccessorImpl(global::java.lang.reflect.Constructor const // resolve the runtime method info mw.ResolveMethod(); var np = !mw.IsPublic || !mw.DeclaringType.IsPublic; - var dm = DynamicMethodUtil.Create($"____{mw.DeclaringType.Name.Replace(".", "_")}__{mw.Name}", mw.DeclaringType.TypeAsTBD.AsReflection(), np, typeof(object), new[] { typeof(object[]) }); + var dm = DynamicMethodUtil.Create($"____{mw.DeclaringType.Name.Replace(".", "_")}__{mw.Name}", mw.DeclaringType.TypeAsTBD.GetUnderlyingType(), np, typeof(object), new[] { typeof(object[]) }); var il = JVM.Context.CodeEmitterFactory.Create(dm); // labels @@ -1007,7 +1007,7 @@ internal FastSerializationConstructorAccessorImpl(global::java.lang.reflect.Cons throw x.ToJava(); } - var dm = DynamicMethodUtil.Create("__", constructor.DeclaringType.TypeAsBaseType.AsReflection(), true, typeof(object), null); + var dm = DynamicMethodUtil.Create("__", constructor.DeclaringType.TypeAsBaseType.GetUnderlyingType(), true, typeof(object), null); var il = JVM.Context.CodeEmitterFactory.Create(dm); il.Emit(OpCodes.Ldtoken, type); il.Emit(OpCodes.Call, GetTypeFromHandleMethod); @@ -1052,7 +1052,7 @@ public object newInstance(object[] objarr) try { - return Activator.CreateInstance(type.AsReflection()); + return Activator.CreateInstance(type.GetUnderlyingType()); } catch (TargetInvocationException x) { @@ -1319,7 +1319,7 @@ private T lazyGet(object obj) { throw GetIllegalArgumentException(obj); } - else if (fw.DeclaringType.IsRemapped && !fw.DeclaringType.TypeAsBaseType.AsReflection().IsInstanceOfType(obj)) + else if (fw.DeclaringType.IsRemapped && !fw.DeclaringType.TypeAsBaseType.GetUnderlyingType().IsInstanceOfType(obj)) { throw GetUnsupportedRemappedFieldException(obj); } @@ -1364,7 +1364,7 @@ private void lazySet(object obj, T value) { throw SetIllegalArgumentException(obj); } - else if (fw.DeclaringType.IsRemapped && !fw.DeclaringType.TypeAsBaseType.AsReflection().IsInstanceOfType(obj)) + else if (fw.DeclaringType.IsRemapped && !fw.DeclaringType.TypeAsBaseType.GetUnderlyingType().IsInstanceOfType(obj)) { throw GetUnsupportedRemappedFieldException(obj); } @@ -2070,7 +2070,7 @@ private Delegate GenerateFastGetter(Type delegateType, Type fieldType, RuntimeJa fw.ResolveField(); - var dm = DynamicMethodUtil.Create("__", fw.DeclaringType.TypeAsBaseType.AsReflection(), !fw.IsPublic || !fw.DeclaringType.IsPublic, fieldType, [typeof(IReflectionException), typeof(object), typeof(object)]); + var dm = DynamicMethodUtil.Create("__", fw.DeclaringType.TypeAsBaseType.GetUnderlyingType(), !fw.IsPublic || !fw.DeclaringType.IsPublic, fieldType, [typeof(IReflectionException), typeof(object), typeof(object)]); var il = JVM.Context.CodeEmitterFactory.Create(dm); if (fw.IsStatic) { @@ -2118,7 +2118,7 @@ private Delegate GenerateFastSetter(Type delegateType, Type fieldType, RuntimeJa fw.ResolveField(); - var dm = DynamicMethodUtil.Create("__", fw.DeclaringType.TypeAsBaseType.AsReflection(), !fw.IsPublic || !fw.DeclaringType.IsPublic, null, [typeof(IReflectionException), typeof(object), fieldType, typeof(object)]); + var dm = DynamicMethodUtil.Create("__", fw.DeclaringType.TypeAsBaseType.GetUnderlyingType(), !fw.IsPublic || !fw.DeclaringType.IsPublic, null, [typeof(IReflectionException), typeof(object), fieldType, typeof(object)]); var il = JVM.Context.CodeEmitterFactory.Create(dm); if (fw.IsStatic) { diff --git a/src/IKVM.Runtime/MethodHandleUtil.jniexport.cs b/src/IKVM.Runtime/MethodHandleUtil.jniexport.cs index 9a6044702..b44ab8b5b 100644 --- a/src/IKVM.Runtime/MethodHandleUtil.jniexport.cs +++ b/src/IKVM.Runtime/MethodHandleUtil.jniexport.cs @@ -59,7 +59,7 @@ Type CreateMethodHandleDelegateType(java.lang.invoke.MethodType type) var ret = RuntimeJavaType.FromClass(type.returnType()); ret.Finish(); - return CreateMethodHandleDelegateType(args, ret).AsReflection(); + return CreateMethodHandleDelegateType(args, ret).GetUnderlyingType(); } static ITypeSymbol[] GetParameterTypes(IMethodBaseSymbol mb) @@ -194,7 +194,7 @@ public Container(T1 target, T2 value) if (!ReflectUtil.CanOwnDynamicMethod(owner)) owner = typeof(DynamicMethodBuilder); - dm = new DynamicMethod(name, mi.ReturnType.AsReflection(), paramTypes.AsReflection(), owner, true); + dm = new DynamicMethod(name, mi.ReturnType.GetUnderlyingType(), paramTypes.GetUnderlyingTypes(), owner, true); ilgen = context.CodeEmitterFactory.Create(dm); if (type.parameterCount() > MaxArity) @@ -348,7 +348,7 @@ internal static Delegate CreateMemberName(RuntimeContext context, RuntimeJavaMet FinishTypes(type); var tw = mw.DeclaringType; - var owner = tw.TypeAsBaseType.AsReflection(); + var owner = tw.TypeAsBaseType.GetUnderlyingType(); var dm = new DynamicMethodBuilder(context, "MemberName:" + mw.DeclaringType.Name + "::" + mw.Name + mw.Signature, type, null, mw.HasCallerID ? DynamicCallerIDProvider.Instance : null, null, owner, true); for (int i = 0, count = type.parameterCount(); i < count; i++) { @@ -516,8 +516,8 @@ internal Delegate CreateDelegate() //ilgen.DumpMethod(); ilgen.DoEmit(); return ValidateDelegate(firstArg == 0 - ? dm.CreateDelegate(delegateType.AsReflection()) - : dm.CreateDelegate(delegateType.AsReflection(), container == null ? firstBoundValue : Activator.CreateInstance(container.AsReflection(), firstBoundValue, secondBoundValue))); + ? dm.CreateDelegate(delegateType.GetUnderlyingType()) + : dm.CreateDelegate(delegateType.GetUnderlyingType(), container == null ? firstBoundValue : Activator.CreateInstance(container.GetUnderlyingType(), firstBoundValue, secondBoundValue))); } internal void BoxArgs(int start) @@ -644,7 +644,7 @@ internal T GetDelegateForInvokeExact(global::java.lang.invoke.MethodHandle mh if (mh._invokeExactDelegate == null) { type._invokeExactDynamicMethod ??= DynamicMethodBuilder.CreateInvokeExact(context, type); - mh._invokeExactDelegate = type._invokeExactDynamicMethod.CreateDelegate(GetDelegateTypeForInvokeExact(type).AsReflection(), mh); + mh._invokeExactDelegate = type._invokeExactDynamicMethod.CreateDelegate(GetDelegateTypeForInvokeExact(type).GetUnderlyingType(), mh); var del = mh._invokeExactDelegate as T; if (del != null) return del; diff --git a/src/IKVM.Runtime/ReflectUtil.cs b/src/IKVM.Runtime/ReflectUtil.cs index 69c23a0a9..7c88196d2 100644 --- a/src/IKVM.Runtime/ReflectUtil.cs +++ b/src/IKVM.Runtime/ReflectUtil.cs @@ -67,7 +67,7 @@ internal static bool IsDynamicAssembly(IAssemblySymbol asm) #if IMPORTER || EXPORTER return false; #else - return asm.AsReflection().IsDynamic; + return asm.GetUnderlyingAssembly().IsDynamic; #endif } @@ -77,7 +77,7 @@ internal static bool IsReflectionOnly(ITypeSymbol type) type = type.GetElementType(); var asm = type.Assembly; - if (asm != null && asm.AsReflection().ReflectionOnly) + if (asm != null && asm.GetUnderlyingAssembly().ReflectionOnly) return true; if (!type.IsGenericType || type.IsGenericTypeDefinition) diff --git a/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs b/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs index e8c275675..9b2f65e22 100644 --- a/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs +++ b/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs @@ -487,11 +487,11 @@ void DoInitializeExports() { if (delegates == null) { - if (ReflectUtil.IsDynamicAssembly(assemblyLoader.Assembly) == false && assemblyLoader.Assembly.AsReflection().GetManifestResourceInfo("ikvm.exports") != null) + if (ReflectUtil.IsDynamicAssembly(assemblyLoader.Assembly) == false && assemblyLoader.Assembly.GetUnderlyingAssembly().GetManifestResourceInfo("ikvm.exports") != null) { var wildcardExports = new List(); - using (var stream = assemblyLoader.Assembly.AsReflection().GetManifestResourceStream("ikvm.exports")) + using (var stream = assemblyLoader.Assembly.GetUnderlyingAssembly().GetManifestResourceStream("ikvm.exports")) { var rdr = new BinaryReader(stream); var assemblyCount = rdr.ReadInt32(); @@ -847,7 +847,7 @@ static java.net.URL MakeResourceURL(IAssemblySymbol asm, string name) #if FIRST_PASS throw new NotImplementedException(); #else - return new java.io.File(Path.Combine(VfsTable.GetAssemblyResourcesPath(JVM.Vfs.Context, asm.AsReflection(), JVM.Properties.HomePath), name)).toURI().toURL(); + return new java.io.File(Path.Combine(VfsTable.GetAssemblyResourcesPath(JVM.Vfs.Context, asm.GetUnderlyingAssembly(), JVM.Properties.HomePath), name)).toURI().toURL(); #endif } @@ -857,7 +857,7 @@ static java.net.URL MakeResourceURL(IAssemblySymbol asm, string name) throw new NotImplementedException(); #else // cannot find resources in dynamic assembly - if (assemblyLoader.Assembly.AsReflection().IsDynamic) + if (assemblyLoader.Assembly.GetUnderlyingAssembly().IsDynamic) yield break; var found = false; @@ -873,14 +873,14 @@ static java.net.URL MakeResourceURL(IAssemblySymbol asm, string name) if (assemblyLoader.HasJavaModule == false) { // attempt to find an assembly resource with the exact name - if (unmangledName != "" && assemblyLoader.Assembly.AsReflection().GetManifestResourceInfo(unmangledName) != null) + if (unmangledName != "" && assemblyLoader.Assembly.GetUnderlyingAssembly().GetManifestResourceInfo(unmangledName) != null) { found = true; yield return MakeResourceURL(assemblyLoader.Assembly, unmangledName); } // the JavaResourceAttribute can be used to manufacture a named Java resource - foreach (var res in assemblyLoader.Assembly.AsReflection().GetCustomAttributes()) + foreach (var res in assemblyLoader.Assembly.GetUnderlyingAssembly().GetCustomAttributes()) { if (res.JavaName == unmangledName) { @@ -892,7 +892,7 @@ static java.net.URL MakeResourceURL(IAssemblySymbol asm, string name) // find an assembly resource with the managed resource name var name = JVM.MangleResourceName(unmangledName); - if (assemblyLoader.Assembly.AsReflection().GetManifestResourceInfo(name) != null) + if (assemblyLoader.Assembly.GetUnderlyingAssembly().GetManifestResourceInfo(name) != null) { found = true; yield return MakeResourceURL(assemblyLoader.Assembly, name); @@ -921,7 +921,7 @@ static java.net.URL MakeResourceURL(IAssemblySymbol asm, string name) yield return (java.net.URL)urls.nextElement(); } - if (loader.Assembly.AsReflection().GetManifestResourceInfo(name) != null) + if (loader.Assembly.GetUnderlyingAssembly().GetManifestResourceInfo(name) != null) { found = true; yield return MakeResourceURL(loader.Assembly, name); @@ -934,7 +934,7 @@ static java.net.URL MakeResourceURL(IAssemblySymbol asm, string name) { var tw = FindLoadedClass(unmangledName.Substring(0, unmangledName.Length - 6).Replace('/', '.')); if (tw != null && tw.ClassLoader == this && !tw.IsArray && !tw.IsDynamic) - yield return new java.io.File(Path.Combine(VfsTable.GetAssemblyClassesPath(JVM.Vfs.Context, assemblyLoader.Assembly.AsReflection(), JVM.Properties.HomePath), unmangledName)).toURI().toURL(); + yield return new java.io.File(Path.Combine(VfsTable.GetAssemblyClassesPath(JVM.Vfs.Context, assemblyLoader.Assembly.GetUnderlyingAssembly(), JVM.Properties.HomePath), unmangledName)).toURI().toURL(); } #endif } @@ -1070,7 +1070,7 @@ internal override java.lang.ClassLoader GetJavaClassLoader() internal virtual java.security.ProtectionDomain GetProtectionDomain() { if (protectionDomain == null) - Interlocked.CompareExchange(ref protectionDomain, new java.security.ProtectionDomain(assemblyLoader.Assembly.AsReflection()), null); + Interlocked.CompareExchange(ref protectionDomain, new java.security.ProtectionDomain(assemblyLoader.Assembly.GetUnderlyingAssembly()), null); return protectionDomain; } @@ -1129,7 +1129,7 @@ internal List> GetPackageInfo() var list = new List>(); foreach (var m in assemblyLoader.Assembly.GetModules(false)) { - var attr = m.AsReflection().GetCustomAttributes(); + var attr = m.GetUnderlyingModule().GetCustomAttributes(); foreach (var p in attr) list.Add(new KeyValuePair(p.jar, p.packages)); } @@ -1174,7 +1174,7 @@ Type GetCustomClassLoaderType() var attribs = assembly.GetCustomAttribute(Context.Resolver.ResolveRuntimeType(typeof(CustomAssemblyClassLoaderAttribute).FullName), false); if (attribs.HasValue) - return ((ITypeSymbol)attribs.Value.ConstructorArguments[0].Value).AsReflection(); + return ((ITypeSymbol)attribs.Value.ConstructorArguments[0].Value).GetUnderlyingType(); return null; } @@ -1301,7 +1301,7 @@ internal CustomClassLoaderCtorCaller(ConstructorInfo ctor, object classLoader, I public object run() { - ctor.Invoke(classLoader, [assembly.AsReflection()]); + ctor.Invoke(classLoader, [assembly.GetUnderlyingAssembly()]); return null; } } diff --git a/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishContext.cs b/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishContext.cs index 1cbe1c18f..f94982e0f 100644 --- a/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishContext.cs +++ b/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishContext.cs @@ -737,7 +737,7 @@ internal ITypeSymbol FinishImpl() } #if !IMPORTER if (liveObjects != null) - context.Resolver.ResolveRuntimeType("IKVM.Runtime.LiveObjectHolder`1").GetField("values", BindingFlags.Static | BindingFlags.Public).AsReflection().SetValue(null, liveObjects.ToArray()); + context.Resolver.ResolveRuntimeType("IKVM.Runtime.LiveObjectHolder`1").GetField("values", BindingFlags.Static | BindingFlags.Public).GetUnderlyingField().SetValue(null, liveObjects.ToArray()); #endif } finally @@ -1593,7 +1593,7 @@ internal static class JniProxyBuilder static JniProxyBuilder() { mod = DynamicClassLoader.CreateJniProxyModuleBuilder(JVM.Context); - var cab = JVM.Context.Resolver.Symbols.CreateCustomAttribute(JVM.Context.Resolver.ResolveRuntimeType(typeof(JavaModuleAttribute).FullName).GetConstructor([]), []); + var cab = CustomAttribute.Create(JVM.Context.Resolver.ResolveRuntimeType(typeof(JavaModuleAttribute).FullName).GetConstructor([]), []); mod.SetCustomAttribute(cab); } @@ -2181,7 +2181,7 @@ internal IConstructorSymbolBuilder DefineThreadLocalType() int id = nestedTypeBuilders == null ? 0 : nestedTypeBuilders.Count; var tb = typeBuilder.DefineNestedType(NestedTypeName.ThreadLocal + id, TypeAttributes.NestedPrivate | TypeAttributes.Sealed, threadLocal.TypeAsBaseType); var fb = tb.DefineField("field", context.Types.Object, FieldAttributes.Private | FieldAttributes.Static); - fb.SetCustomAttribute(context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveCoreType(typeof(ThreadStaticAttribute).FullName).GetConstructor([]), [])); + fb.SetCustomAttribute(CustomAttribute.Create(context.Resolver.ResolveCoreType(typeof(ThreadStaticAttribute).FullName).GetConstructor([]), [])); var mbGet = tb.DefineMethod("get", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final, context.Types.Object, []); var ilgen = mbGet.GetILGenerator(); diff --git a/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.cs b/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.cs index 21106db45..0d4ee8d9a 100644 --- a/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.cs +++ b/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.cs @@ -1104,10 +1104,7 @@ internal override IFieldSymbol LinkField(RuntimeJavaField fw) } if (fld.IsTransient) - { - var transientAttrib = wrapper.Context.Resolver.Symbols.CreateCustomAttribute(wrapper.Context.Resolver.ResolveCoreType(typeof(NonSerializedAttribute).FullName).GetConstructor([]), []); - field.SetCustomAttribute(transientAttrib); - } + field.SetCustomAttribute(CustomAttribute.Create(wrapper.Context.Resolver.ResolveCoreType(typeof(NonSerializedAttribute).FullName).GetConstructor([]), [])); #if IMPORTER { @@ -1264,10 +1261,7 @@ FinishedTypeImpl FinishCore() #if IMPORTER if (annotationBuilder != null) - { - var cab = wrapper.Context.Resolver.Symbols.CreateCustomAttribute(wrapper.Context.Resolver.ResolveRuntimeType(typeof(AnnotationAttributeAttribute).FullName).GetConstructor([wrapper.Context.Types.String]), [UnicodeUtil.EscapeInvalidSurrogates(annotationBuilder.AttributeTypeName)]); - typeBuilder.SetCustomAttribute(cab); - } + typeBuilder.SetCustomAttribute(CustomAttribute.Create(wrapper.Context.Resolver.ResolveRuntimeType(typeof(AnnotationAttributeAttribute).FullName).GetConstructor([wrapper.Context.Types.String]), [UnicodeUtil.EscapeInvalidSurrogates(annotationBuilder.AttributeTypeName)])); if (!wrapper.IsInterface && wrapper.IsMapUnsafeException) { @@ -1470,7 +1464,7 @@ internal void Link() if (o.classFile.Annotations != null) { - ICustomAttributeBuilder attributeUsageAttribute = null; + CustomAttribute? attributeUsageAttribute = null; bool hasAttributeUsageAttribute = false; foreach (object[] def in o.classFile.Annotations) { @@ -1523,7 +1517,9 @@ internal void Link() } } - attributeUsageAttribute = context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveCoreType(typeof(AttributeUsageAttribute).FullName).GetConstructor([context.Resolver.ResolveCoreType(typeof(AttributeTargets).FullName)]), [targets]); + attributeUsageAttribute = CustomAttribute.Create( + context.Resolver.ResolveCoreType(typeof(AttributeUsageAttribute).FullName).GetConstructor([context.Resolver.ResolveCoreType(typeof(AttributeTargets).FullName)]), + [targets]); } } } @@ -1542,7 +1538,7 @@ internal void Link() if (attributeUsageAttribute != null && !hasAttributeUsageAttribute) { - attributeTypeBuilder.SetCustomAttribute(attributeUsageAttribute); + attributeTypeBuilder.SetCustomAttribute(attributeUsageAttribute.Value); } } @@ -1839,12 +1835,12 @@ internal void Finish(JavaTypeImpl o) attributeTypeBuilder.Complete(); } - ICustomAttributeBuilder MakeCustomAttributeBuilder(RuntimeClassLoader loader, object annotation) + CustomAttribute MakeCustomAttributeBuilder(RuntimeClassLoader loader, object annotation) { Link(); var ctor = defineConstructor != null ? defineConstructor : context.Resolver.ResolveRuntimeType("IKVM.Attributes.DynamicAnnotationAttribute").GetConstructor([context.Types.Object.MakeArrayType()]); - return context.Resolver.Symbols.CreateCustomAttribute(ctor, new object[] { AnnotationDefaultAttribute.Escape(QualifyClassNames(loader, annotation)) }); + return CustomAttribute.Create(ctor, [AnnotationDefaultAttribute.Escape(QualifyClassNames(loader, annotation))]); } internal override void Apply(RuntimeClassLoader loader, ITypeSymbolBuilder tb, object annotation) @@ -2851,12 +2847,10 @@ IMethodSymbolBuilder GenerateMethod(int index, ClassFile.Method m, ref bool setM ilgen.Emit(System.Reflection.Emit.OpCodes.Ret); ilgen.DoEmit(); } + #if IMPORTER if (classFile.Methods[index].AnnotationDefault != null) - { - var cab = wrapper.Context.Resolver.Symbols.CreateCustomAttribute(wrapper.Context.Resolver.ResolveRuntimeType("IKVM.Attributes.AnnotationDefaultAttribute").GetConstructor([wrapper.Context.Types.Object]), [AnnotationDefaultAttribute.Escape(classFile.Methods[index].AnnotationDefault)]); - mb.SetCustomAttribute(cab); - } + mb.SetCustomAttribute(CustomAttribute.Create(wrapper.Context.Resolver.ResolveRuntimeType("IKVM.Attributes.AnnotationDefaultAttribute").GetConstructor([wrapper.Context.Types.Object]), [AnnotationDefaultAttribute.Escape(classFile.Methods[index].AnnotationDefault)])); #endif } diff --git a/src/IKVM.Runtime/RuntimeConstantJavaField.cs b/src/IKVM.Runtime/RuntimeConstantJavaField.cs index 8403202e4..bec2dd0fa 100644 --- a/src/IKVM.Runtime/RuntimeConstantJavaField.cs +++ b/src/IKVM.Runtime/RuntimeConstantJavaField.cs @@ -141,7 +141,7 @@ protected override void EmitSetImpl(CodeEmitter ilgen) internal override object GetValue(object obj) { var field = GetField(); - return FieldTypeWrapper.IsPrimitive || field == null ? GetConstantValue() : field.AsReflection().GetValue(null); + return FieldTypeWrapper.IsPrimitive || field == null ? GetConstantValue() : field.GetUnderlyingField().GetValue(null); } internal override void SetValue(object obj, object value) diff --git a/src/IKVM.Runtime/RuntimeJavaField.cs b/src/IKVM.Runtime/RuntimeJavaField.cs index f36a6325c..9b3398eef 100644 --- a/src/IKVM.Runtime/RuntimeJavaField.cs +++ b/src/IKVM.Runtime/RuntimeJavaField.cs @@ -500,8 +500,8 @@ Delegate CreateUnsafeGetDelegate() FieldTypeWrapper.Finish(); ResolveField(); - var ft = FieldTypeWrapper.IsPrimitive ? FieldTypeWrapper.TypeAsSignatureType.AsReflection() : typeof(object); - var dm = DynamicMethodUtil.Create($"____{DeclaringType.Name.Replace(".", "_")}__{Name}", DeclaringType.TypeAsTBD.AsReflection(), true, ft, [typeof(object)]); + var ft = FieldTypeWrapper.IsPrimitive ? FieldTypeWrapper.TypeAsSignatureType.GetUnderlyingType() : typeof(object); + var dm = DynamicMethodUtil.Create($"____{DeclaringType.Name.Replace(".", "_")}__{Name}", DeclaringType.TypeAsTBD.GetUnderlyingType(), true, ft, [typeof(object)]); var il = JVM.Context.CodeEmitterFactory.Create(dm); if (IsStatic == false) @@ -547,8 +547,8 @@ Delegate CreateUnsafeSetDelegate() FieldTypeWrapper.Finish(); ResolveField(); - var ft = FieldTypeWrapper.IsPrimitive ? FieldTypeWrapper.TypeAsSignatureType.AsReflection() : typeof(object); - var dm = DynamicMethodUtil.Create($"____{DeclaringType.Name.Replace(".", "_")}__{Name}", DeclaringType.TypeAsTBD.AsReflection(), true, typeof(void), [typeof(object), ft]); + var ft = FieldTypeWrapper.IsPrimitive ? FieldTypeWrapper.TypeAsSignatureType.GetUnderlyingType() : typeof(object); + var dm = DynamicMethodUtil.Create($"____{DeclaringType.Name.Replace(".", "_")}__{Name}", DeclaringType.TypeAsTBD.GetUnderlyingType(), true, typeof(void), [typeof(object), ft]); var il = JVM.Context.CodeEmitterFactory.Create(dm); if (IsStatic == false) @@ -592,8 +592,8 @@ Delegate GetUnsafeVolatileGetDelegate() Delegate CreateUnsafeVolatileGetDelegate() { ResolveField(); - var ft = FieldTypeWrapper.IsPrimitive ? FieldTypeWrapper.TypeAsSignatureType.AsReflection() : typeof(object); - var dm = new DynamicMethod($"____{DeclaringType.Name.Replace(".", "_")}__{Name}", ft, [typeof(object)], DeclaringType.TypeAsTBD.Module.AsReflection(), true); + var ft = FieldTypeWrapper.IsPrimitive ? FieldTypeWrapper.TypeAsSignatureType.GetUnderlyingType() : typeof(object); + var dm = new DynamicMethod($"____{DeclaringType.Name.Replace(".", "_")}__{Name}", ft, [typeof(object)], DeclaringType.TypeAsTBD.Module.GetUnderlyingModule(), true); var il = JVM.Context.CodeEmitterFactory.Create(dm); if (IsStatic == false) @@ -637,8 +637,8 @@ Delegate GetUnsafeVolatileSetDelegate() Delegate CreateUnsafeVolatileSetDelegate() { ResolveField(); - var ft = FieldTypeWrapper.IsPrimitive ? FieldTypeWrapper.TypeAsSignatureType.AsReflection() : typeof(object); - var dm = DynamicMethodUtil.Create($"____{DeclaringType.Name.Replace(".", "_")}__{Name}", DeclaringType.TypeAsTBD.AsReflection(), true, typeof(void), [typeof(object), ft]); + var ft = FieldTypeWrapper.IsPrimitive ? FieldTypeWrapper.TypeAsSignatureType.GetUnderlyingType() : typeof(object); + var dm = DynamicMethodUtil.Create($"____{DeclaringType.Name.Replace(".", "_")}__{Name}", DeclaringType.TypeAsTBD.GetUnderlyingType(), true, typeof(void), [typeof(object), ft]); var il = JVM.Context.CodeEmitterFactory.Create(dm); if (IsStatic == false) @@ -685,8 +685,8 @@ Delegate GetUnsafeCompareAndSwapDelegate() Delegate CreateUnsafeCompareAndSwapDelegate() { ResolveField(); - var ft = FieldTypeWrapper.IsPrimitive ? FieldTypeWrapper.TypeAsSignatureType.AsReflection() : typeof(object); - var dm = DynamicMethodUtil.Create($"____{DeclaringType.Name.Replace(".", "_")}__{Name}", DeclaringType.TypeAsTBD.AsReflection(), true, typeof(bool), [typeof(object), ft, ft]); + var ft = FieldTypeWrapper.IsPrimitive ? FieldTypeWrapper.TypeAsSignatureType.GetUnderlyingType() : typeof(object); + var dm = DynamicMethodUtil.Create($"____{DeclaringType.Name.Replace(".", "_")}__{Name}", DeclaringType.TypeAsTBD.GetUnderlyingType(), true, typeof(bool), [typeof(object), ft, ft]); var il = JVM.Context.CodeEmitterFactory.Create(dm); if (IsStatic == false) diff --git a/src/IKVM.Runtime/RuntimeJavaMethod.cs b/src/IKVM.Runtime/RuntimeJavaMethod.cs index d416dc451..066546208 100644 --- a/src/IKVM.Runtime/RuntimeJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimeJavaMethod.cs @@ -491,7 +491,7 @@ protected static object InvokeAndUnwrapException(IMethodBaseSymbol mb, object ob #else try { - return mb.AsReflection().Invoke(obj, args); + return mb.GetUnderlyingMethodBase().Invoke(obj, args); } catch (TargetInvocationException e) { diff --git a/src/IKVM.Runtime/RuntimeJavaType.cs b/src/IKVM.Runtime/RuntimeJavaType.cs index 7a5e44cf1..908f89d9f 100644 --- a/src/IKVM.Runtime/RuntimeJavaType.cs +++ b/src/IKVM.Runtime/RuntimeJavaType.cs @@ -254,9 +254,9 @@ private void LazyInitClass() { var type = GetClassLiteralType(); if (IsForbiddenTypeParameterType(type)) - clazz = new java.lang.Class(type.AsReflection()); + clazz = new java.lang.Class(type.GetUnderlyingRuntimeType()); else - clazz = (java.lang.Class)typeof(ClassLiteral<>).MakeGenericType(type.AsReflection()).GetProperty("Value").GetGetMethod().Invoke(null, []); + clazz = (java.lang.Class)typeof(ClassLiteral<>).MakeGenericType(type.GetUnderlyingRuntimeType()).GetProperty("Value").GetGetMethod().Invoke(null, []); } clazz.typeWrapper = this; @@ -1205,7 +1205,7 @@ internal void RunClassInit() { var t = IsRemapped ? TypeAsBaseType : TypeAsTBD; if (t != null) - System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(t.AsReflection().TypeHandle); + System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(t.GetUnderlyingRuntimeType().TypeHandle); } #endif @@ -1503,7 +1503,7 @@ internal virtual object GetAnnotationDefault(RuntimeJavaMethod mw) var mb = mw.GetMethod(); if (mb != null) { - var attr = mb.AsReflection().GetCustomAttribute(); + var attr = mb.GetUnderlyingMethodBase().GetCustomAttribute(); if (attr != null) return JVM.NewAnnotationElementValue(mw.DeclaringType.ClassLoader.GetJavaClassLoader(), mw.ReturnType.ClassObject, attr.Value); } diff --git a/src/IKVM.Runtime/RuntimeManagedByteCodeAccessStubJavaField.cs b/src/IKVM.Runtime/RuntimeManagedByteCodeAccessStubJavaField.cs index 3b965b99a..b8bbd3e1e 100644 --- a/src/IKVM.Runtime/RuntimeManagedByteCodeAccessStubJavaField.cs +++ b/src/IKVM.Runtime/RuntimeManagedByteCodeAccessStubJavaField.cs @@ -108,13 +108,13 @@ protected override void EmitSetImpl(CodeEmitter ilgen) internal override object GetValue(object obj) { // we can only be invoked on type 2 access stubs (because type 1 access stubs are HideFromReflection), so we know we have a field - return GetField().AsReflection().GetValue(obj); + return GetField().GetUnderlyingField().GetValue(obj); } internal override void SetValue(object obj, object value) { // we can only be invoked on type 2 access stubs (because type 1 access stubs are HideFromReflection), so we know we have a field - GetField().AsReflection().SetValue(obj, value); + GetField().GetUnderlyingField().SetValue(obj, value); } #endif diff --git a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.GhostJavaType.cs b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.GhostJavaType.cs index db1e75101..cd880c261 100644 --- a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.GhostJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.GhostJavaType.cs @@ -57,12 +57,12 @@ internal GhostJavaType(RuntimeContext context, string name, ITypeSymbol type) : internal override object GhostWrap(object obj) { - return type.GetMethod("Cast").AsReflection().Invoke(null, [obj]); + return type.GetMethod("Cast").GetUnderlyingMethod().Invoke(null, [obj]); } internal override object GhostUnwrap(object obj) { - return type.GetMethod("ToObject").AsReflection().Invoke(obj, []); + return type.GetMethod("ToObject").GetUnderlyingMethod().Invoke(obj, []); } #endif diff --git a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.RemappedJavaMethod.cs b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.RemappedJavaMethod.cs index dc6311ad0..87eff2372 100644 --- a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.RemappedJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.RemappedJavaMethod.cs @@ -149,7 +149,7 @@ internal override object CreateInstance(object[] args) internal override object InvokeNonvirtualRemapped(object obj, object[] args) { var mi = mbNonvirtualHelper ?? mbHelper; - return mi.AsReflection().Invoke(null, ArrayUtil.Concat(obj, args)); + return mi.GetUnderlyingMethod().Invoke(null, ArrayUtil.Concat(obj, args)); } #endif // !IMPORTER && !FIRST_PASS && !EXPORTER diff --git a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs index 73fa25273..94939dec1 100644 --- a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs @@ -1115,7 +1115,7 @@ object[] CastArray(object[] l) internal override object[] GetDeclaredAnnotations() { - return CastArray(type.AsReflection().GetCustomAttributes(false)); + return CastArray(type.GetUnderlyingType().GetCustomAttributes(false)); } internal override object[] GetMethodAnnotations(RuntimeJavaMethod mw) @@ -1127,7 +1127,7 @@ internal override object[] GetMethodAnnotations(RuntimeJavaMethod mw) return null; } - return CastArray(mb.AsReflection().GetCustomAttributes(false)); + return CastArray(mb.GetUnderlyingMethodBase().GetCustomAttributes(false)); } internal override object[][] GetParameterAnnotations(RuntimeJavaMethod mw) @@ -1150,7 +1150,7 @@ internal override object[][] GetParameterAnnotations(RuntimeJavaMethod mw) var attribs = new object[parameters.Length - skip - skipEnd][]; for (int i = skip; i < parameters.Length - skipEnd; i++) - attribs[i - skip] = CastArray(parameters[i].AsReflection().GetCustomAttributes(false)); + attribs[i - skip] = CastArray(parameters[i].GetUnderlyingParameter().GetCustomAttributes(false)); return attribs; } @@ -1159,10 +1159,10 @@ internal override object[] GetFieldAnnotations(RuntimeJavaField fw) { var field = fw.GetField(); if (field != null) - return CastArray(field.AsReflection().GetCustomAttributes(false)); + return CastArray(field.GetUnderlyingField().GetCustomAttributes(false)); if (fw is RuntimeManagedByteCodePropertyJavaField prop) - return CastArray(prop.GetProperty().AsReflection().GetCustomAttributes(false)); + return CastArray(prop.GetProperty().GetUnderlyingProperty().GetCustomAttributes(false)); return Array.Empty(); } @@ -1186,9 +1186,9 @@ internal CompiledAnnotation(RuntimeContext context, ITypeSymbol type) constructor = type.GetConstructor([context.Types.Object.MakeArrayType()]); } - private ICustomAttributeBuilder MakeCustomAttributeBuilder(RuntimeClassLoader loader, object annotation) + private CustomAttribute MakeCustomAttributeBuilder(RuntimeClassLoader loader, object annotation) { - return context.Resolver.Symbols.CreateCustomAttribute(constructor, [AnnotationDefaultAttribute.Escape(QualifyClassNames(loader, annotation))]); + return CustomAttribute.Create(constructor, [AnnotationDefaultAttribute.Escape(QualifyClassNames(loader, annotation))]); } internal override void Apply(RuntimeClassLoader loader, ITypeSymbolBuilder tb, object annotation) @@ -1274,7 +1274,7 @@ internal override int GetSourceLineNumber(IMethodBaseSymbol mb, int ilOffset) { var attr = type.GetCustomAttribute(Context.Resolver.GetSymbol(typeof(LineNumberTableAttribute))); if (attr.HasValue && attr.Value.Constructor != null) - return ((LineNumberTableAttribute)attr.Value.Constructor.AsReflection().Invoke(attr.Value.ConstructorArguments.Cast().ToArray())).GetLineNumber(ilOffset); + return ((LineNumberTableAttribute)attr.Value.Constructor.GetUnderlyingConstructor().Invoke(attr.Value.ConstructorArguments.Cast().ToArray())).GetLineNumber(ilOffset); return -1; } diff --git a/src/IKVM.Runtime/RuntimeManagedByteCodePropertyJavaField.cs b/src/IKVM.Runtime/RuntimeManagedByteCodePropertyJavaField.cs index 0f1222e26..09f5dba60 100644 --- a/src/IKVM.Runtime/RuntimeManagedByteCodePropertyJavaField.cs +++ b/src/IKVM.Runtime/RuntimeManagedByteCodePropertyJavaField.cs @@ -104,7 +104,7 @@ internal override object GetValue(object obj) if (getter == null) throw new java.lang.NoSuchMethodError(); - return getter.AsReflection().Invoke(obj, []); + return getter.GetUnderlyingMethod().Invoke(obj, []); } internal override void SetValue(object obj, object value) @@ -113,7 +113,7 @@ internal override void SetValue(object obj, object value) if (setter == null) throw new java.lang.NoSuchMethodError(); - setter.AsReflection().Invoke(obj, new object[] { value }); + setter.GetUnderlyingMethod().Invoke(obj, new object[] { value }); } #endif diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.cs index b762ef101..d17358d07 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.cs @@ -376,7 +376,7 @@ internal override object GetAnnotationDefault(RuntimeJavaMethod mw) } else if (mw.ReturnType.IsArray) { - return Array.CreateInstance(mw.ReturnType.TypeAsArrayType.AsReflection(), 0); + return Array.CreateInstance(mw.ReturnType.TypeAsArrayType.GetUnderlyingType(), 0); } } @@ -491,7 +491,7 @@ internal AttributeAnnotation(ITypeSymbol type) this.type = type; } - ICustomAttributeBuilder MakeCustomAttributeBuilder(RuntimeClassLoader loader, object annotation) + CustomAttribute MakeCustomAttributeBuilder(RuntimeClassLoader loader, object annotation) { object[] arr = (object[])annotation; object ctorArg = null; @@ -534,7 +534,7 @@ ICustomAttributeBuilder MakeCustomAttributeBuilder(RuntimeClassLoader loader, ob // TODO required argument is missing } - return loader.Context.Resolver.Symbols.CreateCustomAttribute( + return CustomAttribute.Create( ctorArg == null ? defCtor : singleOneArgCtor, ctorArg == null ? [] : new object[] { ctorArg }, properties.ToArray(), @@ -583,11 +583,11 @@ internal override void Apply(RuntimeClassLoader loader, IParameterSymbolBuilder internal override void Apply(RuntimeClassLoader loader, IAssemblySymbolBuilder assemblyBuilder, object annotation) { #if IMPORTER - var ab = assemblyBuilder.AsReflection(); + var ab = assemblyBuilder.GetUnderlyingAssemblyBuilder(); if (type == loader.Context.Resolver.ResolveCoreType(typeof(System.Runtime.CompilerServices.TypeForwardedToAttribute).FullName)) { - ab.__AddTypeForwarder((Type)ConvertValue(loader, loader.Context.Types.Type, ((object[])annotation)[3])); + assemblyBuilder.AddTypeForwarder((ITypeSymbol)ConvertValue(loader, loader.Context.Types.Type, ((object[])annotation)[3])); } else if (type == loader.Context.Resolver.ResolveCoreType(typeof(System.Reflection.AssemblyVersionAttribute).FullName)) { diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.EnumEnumJavaType.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.EnumEnumJavaType.cs index 709b00704..35eba0393 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.EnumEnumJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.EnumEnumJavaType.cs @@ -98,7 +98,7 @@ internal EnumJavaField(RuntimeJavaType tw, string name, int ordinal) : internal override object GetValue(object obj) { if (val == null) - System.Threading.Interlocked.CompareExchange(ref val, Activator.CreateInstance(this.DeclaringType.TypeAsTBD.AsReflection(), BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, new object[] { this.Name, ordinal }, null), null); + System.Threading.Interlocked.CompareExchange(ref val, Activator.CreateInstance(this.DeclaringType.TypeAsTBD.GetUnderlyingType(), BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, new object[] { this.Name, ordinal }, null), null); return val; } @@ -147,7 +147,7 @@ internal EnumValuesJavaMethod(RuntimeJavaType declaringType) : internal override object Invoke(object obj, object[] args) { var values = DeclaringType.GetFields(); - var array = (object[])Array.CreateInstance(DeclaringType.TypeAsArrayType.AsReflection(), values.Length); + var array = (object[])Array.CreateInstance(DeclaringType.TypeAsArrayType.GetUnderlyingType(), values.Length); for (int i = 0; i < values.Length; i++) array[i] = values[i].GetValue(null); diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.EnumWrapJavaMethod.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.EnumWrapJavaMethod.cs index b412e502e..d706a9031 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.EnumWrapJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.EnumWrapJavaMethod.cs @@ -67,7 +67,7 @@ internal override void EmitCall(CodeEmitter ilgen) internal override object Invoke(object obj, object[] args) { - return Enum.ToObject(DeclaringType.TypeAsTBD.AsReflection(), args[0]); + return Enum.ToObject(DeclaringType.TypeAsTBD.GetUnderlyingType(), args[0]); } #endif diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.ValueTypeDefaultCtorJavaMethod.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.ValueTypeDefaultCtorJavaMethod.cs index 730a30941..6de44f611 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.ValueTypeDefaultCtorJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.ValueTypeDefaultCtorJavaMethod.cs @@ -65,7 +65,7 @@ internal override void EmitCall(CodeEmitter ilgen) internal override object CreateInstance(object[] args) { - return Activator.CreateInstance(DeclaringType.TypeAsTBD.AsReflection()); + return Activator.CreateInstance(DeclaringType.TypeAsTBD.GetUnderlyingType()); } #endif diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.cs index 7b20b06a8..a26fefa20 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.cs @@ -270,7 +270,7 @@ internal static bool IsAllowedOutside(ITypeSymbol type) // since the reflection implementation lives inside this assembly, all internal members would // be accessible through Java reflection. #if !FIRST_PASS && !IMPORTER && !EXPORTER - if (type.Assembly.AsReflection() == typeof(RuntimeManagedJavaType).Assembly) + if (type.Assembly.GetUnderlyingAssembly() == typeof(RuntimeManagedJavaType).Assembly) return false; #endif diff --git a/src/IKVM.Runtime/RuntimeSimpleJavaField.cs b/src/IKVM.Runtime/RuntimeSimpleJavaField.cs index 4045ad61d..72d41974f 100644 --- a/src/IKVM.Runtime/RuntimeSimpleJavaField.cs +++ b/src/IKVM.Runtime/RuntimeSimpleJavaField.cs @@ -55,12 +55,12 @@ internal RuntimeSimpleJavaField(RuntimeJavaType declaringType, RuntimeJavaType f internal override object GetValue(object obj) { - return GetField().AsReflection().GetValue(obj); + return GetField().GetUnderlyingRuntimeField().GetValue(obj); } internal override void SetValue(object obj, object value) { - GetField().AsReflection().SetValue(obj, value); + GetField().GetUnderlyingRuntimeField().SetValue(obj, value); } #endif diff --git a/src/IKVM.Runtime/Serialization.cs b/src/IKVM.Runtime/Serialization.cs index a2dfffbfb..22c90df64 100644 --- a/src/IKVM.Runtime/Serialization.cs +++ b/src/IKVM.Runtime/Serialization.cs @@ -43,8 +43,8 @@ class Serialization readonly RuntimeContext context; - ICustomAttributeBuilder serializableAttribute; - ICustomAttributeBuilder securityCriticalAttribute; + CustomAttribute? serializableAttribute; + CustomAttribute? securityCriticalAttribute; RuntimeJavaType typeOfISerializable; RuntimeJavaType typeofIObjectreference; RuntimeJavaType typeOfExternalizable; @@ -58,9 +58,9 @@ public Serialization(RuntimeContext context) this.context = context ?? throw new ArgumentNullException(nameof(context)); } - ICustomAttributeBuilder SerializableAttribute => serializableAttribute ??= context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveCoreType(typeof(SerializableAttribute).FullName).GetConstructor([]), []); + CustomAttribute SerializableAttribute => serializableAttribute ??= CustomAttribute.Create(context.Resolver.ResolveCoreType(typeof(SerializableAttribute).FullName).GetConstructor([]), []); - ICustomAttributeBuilder SecurityCriticalAttribute => securityCriticalAttribute ??= context.Resolver.Symbols.CreateCustomAttribute(context.Resolver.ResolveCoreType(typeof(SecurityCriticalAttribute).FullName).GetConstructor([]), []); + CustomAttribute SecurityCriticalAttribute => securityCriticalAttribute ??= CustomAttribute.Create(context.Resolver.ResolveCoreType(typeof(SecurityCriticalAttribute).FullName).GetConstructor([]), []); RuntimeJavaType TypeOfISerializable => typeOfISerializable ??= context.ClassLoaderFactory.GetJavaTypeFromType(context.Resolver.ResolveCoreType(typeof(ISerializable).FullName)); diff --git a/src/IKVM.Runtime/SymbolExtensions.cs b/src/IKVM.Runtime/SymbolExtensions.cs index e98aa7697..08cf48b7d 100644 --- a/src/IKVM.Runtime/SymbolExtensions.cs +++ b/src/IKVM.Runtime/SymbolExtensions.cs @@ -23,7 +23,7 @@ namespace IKVM.Runtime static class SymbolExtensions { - public static Assembly AsReflection(this IAssemblySymbol symbol) + public static Assembly GetUnderlyingAssembly(this IAssemblySymbol symbol) { if (symbol == null) return null; @@ -35,7 +35,7 @@ public static Assembly AsReflection(this IAssemblySymbol symbol) #endif } - public static Module AsReflection(this IModuleSymbol symbol) + public static Module GetUnderlyingModule(this IModuleSymbol symbol) { if (symbol == null) return null; @@ -47,7 +47,7 @@ public static Module AsReflection(this IModuleSymbol symbol) #endif } - public static Type AsReflection(this ITypeSymbol symbol) + public static Type GetUnderlyingType(this ITypeSymbol symbol) { if (symbol == null) return null; @@ -59,19 +59,31 @@ public static Type AsReflection(this ITypeSymbol symbol) #endif } - public static Type[] AsReflection(this ITypeSymbol[] symbols) + public static Type GetUnderlyingRuntimeType(this ITypeSymbol symbol) + { + if (symbol == null) + return null; + +#if IMPORTER || EXPORTER + throw new NotSupportedException(); +#else + return ((IReflectionTypeSymbol)symbol).UnderlyingRuntimeType; +#endif + } + + public static Type[] GetUnderlyingTypes(this ITypeSymbol[] symbols) { if (symbols == null) return null; var a = new Type[symbols.Length]; for (int i = 0; i < symbols.Length; i++) - a[i] = AsReflection(symbols[i]); + a[i] = GetUnderlyingType(symbols[i]); return a; } - public static MethodBase AsReflection(this IMethodBaseSymbol symbol) + public static MethodBase GetUnderlyingMethodBase(this IMethodBaseSymbol symbol) { if (symbol == null) return null; @@ -83,7 +95,7 @@ public static MethodBase AsReflection(this IMethodBaseSymbol symbol) #endif } - public static ConstructorInfo AsReflection(this IConstructorSymbol symbol) + public static ConstructorInfo GetUnderlyingConstructor(this IConstructorSymbol symbol) { if (symbol == null) return null; @@ -95,7 +107,7 @@ public static ConstructorInfo AsReflection(this IConstructorSymbol symbol) #endif } - public static MethodInfo AsReflection(this IMethodSymbol symbol) + public static MethodInfo GetUnderlyingMethod(this IMethodSymbol symbol) { if (symbol == null) return null; @@ -107,7 +119,7 @@ public static MethodInfo AsReflection(this IMethodSymbol symbol) #endif } - public static ParameterInfo AsReflection(this IParameterSymbol symbol) + public static ParameterInfo GetUnderlyingParameter(this IParameterSymbol symbol) { if (symbol == null) return null; @@ -119,7 +131,7 @@ public static ParameterInfo AsReflection(this IParameterSymbol symbol) #endif } - public static FieldInfo AsReflection(this IFieldSymbol symbol) + public static FieldInfo GetUnderlyingField(this IFieldSymbol symbol) { if (symbol == null) return null; @@ -131,19 +143,31 @@ public static FieldInfo AsReflection(this IFieldSymbol symbol) #endif } - public static FieldInfo[] AsReflection(this IFieldSymbol[] symbols) + public static FieldInfo GetUnderlyingRuntimeField(this IFieldSymbol symbol) + { + if (symbol == null) + return null; + +#if IMPORTER || EXPORTER + throw new NotSupportedException(); +#else + return ((IReflectionFieldSymbol)symbol).UnderlyingRuntimeField; +#endif + } + + public static FieldInfo[] GetUnderlyingFields(this IFieldSymbol[] symbols) { if (symbols == null) return null; var a = new FieldInfo[symbols.Length]; for (int i = 0; i < symbols.Length; i++) - a[i] = AsReflection(symbols[i]); + a[i] = GetUnderlyingField(symbols[i]); return a; } - public static PropertyInfo AsReflection(this IPropertySymbol symbol) + public static PropertyInfo GetUnderlyingProperty(this IPropertySymbol symbol) { if (symbol == null) return null; @@ -155,19 +179,19 @@ public static PropertyInfo AsReflection(this IPropertySymbol symbol) #endif } - public static PropertyInfo[] AsReflection(this IPropertySymbol[] symbols) + public static PropertyInfo[] GetUnderlyingProperties(this IPropertySymbol[] symbols) { if (symbols == null) return null; var a = new PropertyInfo[symbols.Length]; for (int i = 0; i < symbols.Length; i++) - a[i] = AsReflection(symbols[i]); + a[i] = GetUnderlyingProperty(symbols[i]); return a; } - public static AssemblyBuilder AsReflection(this IAssemblySymbolBuilder builder) + public static AssemblyBuilder GetUnderlyingAssemblyBuilder(this IAssemblySymbolBuilder builder) { if (builder == null) return null; @@ -179,7 +203,7 @@ public static AssemblyBuilder AsReflection(this IAssemblySymbolBuilder builder) #endif } - public static ModuleBuilder AsReflection(this IModuleSymbolBuilder builder) + public static ModuleBuilder GetUnderlyingModuleBuilder(this IModuleSymbolBuilder builder) { if (builder == null) return null; @@ -191,7 +215,7 @@ public static ModuleBuilder AsReflection(this IModuleSymbolBuilder builder) #endif } - public static TypeBuilder AsReflection(this ITypeSymbolBuilder builder) + public static TypeBuilder GetUnderlyingTypeBuilder(this ITypeSymbolBuilder builder) { if (builder == null) return null; @@ -203,7 +227,7 @@ public static TypeBuilder AsReflection(this ITypeSymbolBuilder builder) #endif } - public static ConstructorBuilder AsReflection(this IConstructorSymbolBuilder builder) + public static ConstructorBuilder GetUnderlyingConstructorBuilder(this IConstructorSymbolBuilder builder) { if (builder == null) return null; @@ -215,7 +239,7 @@ public static ConstructorBuilder AsReflection(this IConstructorSymbolBuilder bui #endif } - public static MethodBuilder AsReflection(this IMethodSymbolBuilder builder) + public static MethodBuilder GetUnderlyingMethodBuilder(this IMethodSymbolBuilder builder) { if (builder == null) return null; @@ -227,7 +251,7 @@ public static MethodBuilder AsReflection(this IMethodSymbolBuilder builder) #endif } - public static FieldBuilder AsReflection(this IFieldSymbolBuilder builder) + public static FieldBuilder GetUnderlyingFieldBuilder(this IFieldSymbolBuilder builder) { if (builder == null) return null; diff --git a/src/IKVM.Runtime/Util/Java/Lang/Invoke/NativeInvokerBytecodeGenerator.cs b/src/IKVM.Runtime/Util/Java/Lang/Invoke/NativeInvokerBytecodeGenerator.cs index 355ca0447..bfee5d139 100644 --- a/src/IKVM.Runtime/Util/Java/Lang/Invoke/NativeInvokerBytecodeGenerator.cs +++ b/src/IKVM.Runtime/Util/Java/Lang/Invoke/NativeInvokerBytecodeGenerator.cs @@ -115,7 +115,7 @@ internal BailoutException(Bailout reason, object data) var paramTypes = MethodHandleUtil.GetParameterTypes(context.Types.Object.MakeArrayType(), mi); // HACK the code we generate is not verifiable (known issue: locals aren't typed correctly), so we stick the DynamicMethod into mscorlib (a security critical assembly) - this.dm = new DynamicMethod(lambdaForm.debugName, mi.ReturnType.AsReflection(), paramTypes.AsReflection(), typeof(object).Module, true); + this.dm = new DynamicMethod(lambdaForm.debugName, mi.ReturnType.GetUnderlyingType(), paramTypes.GetUnderlyingTypes(), typeof(object).Module, true); this.ilgen = context.CodeEmitterFactory.Create(this.dm); if (invokerType.parameterCount() > MethodHandleUtil.MaxArity) { @@ -439,7 +439,7 @@ private Delegate generateCustomizedCodeBytes() emitReturn(onStack); ilgen.DoEmit(); - return dm.CreateDelegate(delegateType.AsReflection(), constants.ToArray()); + return dm.CreateDelegate(delegateType.GetUnderlyingType(), constants.ToArray()); } void emitArrayLoad(Name name) diff --git a/src/IKVM.Tools.Importer/ImportClassLoader.cs b/src/IKVM.Tools.Importer/ImportClassLoader.cs index 7e321787b..81e9b716b 100644 --- a/src/IKVM.Tools.Importer/ImportClassLoader.cs +++ b/src/IKVM.Tools.Importer/ImportClassLoader.cs @@ -516,7 +516,7 @@ void SetMain(RuntimeJavaType type, IKVM.CoreLib.Symbols.Emit.PEFileKinds target, // global main method decorated with appropriate apartment type var mainMethodProxy = GetTypeWrapperFactory().ModuleBuilder.DefineGlobalMethod("Main", System.Reflection.MethodAttributes.Public | System.Reflection.MethodAttributes.Static, Context.Types.Int32, [Context.Types.String.MakeArrayType()]); if (apartmentAttributeType != null) - mainMethodProxy.SetCustomAttribute(Context.Resolver.Symbols.CreateCustomAttribute(apartmentAttributeType.GetConstructor([]), [])); + mainMethodProxy.SetCustomAttribute(CustomAttribute.Create(apartmentAttributeType.GetConstructor([]), [])); var ilgen = Context.CodeEmitterFactory.Create(mainMethodProxy); @@ -605,7 +605,7 @@ void Save() foreach (object[] args in packages.ToArray()) { args[1] = UnicodeUtil.EscapeInvalidSurrogates((string[])args[1]); - mb.SetCustomAttribute(Context.Resolver.Symbols.CreateCustomAttribute(packageListAttributeCtor, args)); + mb.SetCustomAttribute(CustomAttribute.Create(packageListAttributeCtor, args)); } // We can't add the resource when we're a module, because a multi-module assembly has a single resource namespace // and since you cannot combine -target:module with -sharedclassloader we don't need an export map @@ -672,13 +672,11 @@ void AddJavaModuleAttribute(IModuleSymbolBuilder mb) } list = UnicodeUtil.EscapeInvalidSurrogates(list); - var cab = Context.Resolver.Symbols.CreateCustomAttribute(typeofJavaModuleAttribute.GetConstructor([Context.Types.String.MakeArrayType()]), [list], propInfos, propValues); - mb.SetCustomAttribute(cab); + mb.SetCustomAttribute(CustomAttribute.Create(typeofJavaModuleAttribute.GetConstructor([Context.Types.String.MakeArrayType()]), [list], propInfos, propValues)); } else { - var cab = Context.Resolver.Symbols.CreateCustomAttribute(typeofJavaModuleAttribute.GetConstructor([]), [], propInfos, propValues); - mb.SetCustomAttribute(cab); + mb.SetCustomAttribute(CustomAttribute.Create(typeofJavaModuleAttribute.GetConstructor([]), [], propInfos, propValues)); } } @@ -1490,7 +1488,7 @@ internal override IMethodBaseSymbol DoLink() DeclaringType.Context.AttributeHelper.SetModifiers(mbHelper, (Modifiers)m.Modifiers, false); DeclaringType.Context.AttributeHelper.SetNameSig(mbHelper, m.Name, m.Sig); AddDeclaredExceptions(DeclaringType.Context, mbHelper, m.Throws); - mbHelper.SetCustomAttribute(DeclaringType.Context.Resolver.Symbols.CreateCustomAttribute(DeclaringType.Context.Resolver.ResolveCoreType(typeof(ObsoleteAttribute).FullName).GetConstructor([DeclaringType.Context.Types.String]), ["This function will be removed from future versions. Please use extension methods from ikvm.extensions namespace instead."])); + mbHelper.SetCustomAttribute(CustomAttribute.Create(DeclaringType.Context.Resolver.ResolveCoreType(typeof(ObsoleteAttribute).FullName).GetConstructor([DeclaringType.Context.Types.String]), ["This function will be removed from future versions. Please use extension methods from ikvm.extensions namespace instead."])); } return mbCore; } @@ -3011,10 +3009,7 @@ int CompilePass3() // configure Win32 file version if (state.fileversion != null) - { - var filever = Context.Resolver.Symbols.CreateCustomAttribute(Context.Resolver.ResolveCoreType(typeof(System.Reflection.AssemblyFileVersionAttribute).FullName).GetConstructor([Context.Types.String]), [state.fileversion]); - assemblyBuilder.SetCustomAttribute(filever); - } + assemblyBuilder.SetCustomAttribute(CustomAttribute.Create(Context.Resolver.ResolveCoreType(typeof(System.Reflection.AssemblyFileVersionAttribute).FullName).GetConstructor([Context.Types.String]), [state.fileversion])); // apply assembly annotations if (state.assemblyAttributeAnnotations != null) From b74376789c3961f06cd353684f66e3227d767eab Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Fri, 18 Oct 2024 15:56:37 -0500 Subject: [PATCH 45/51] Fix. --- .../Reflection/ReflectionSymbolTests.cs | 19 ++ .../Reflection/ReflectionExtensions.cs | 118 +++++++- .../Emit/ReflectionMethodSymbolBuilder.cs | 2 +- .../ReflectionGenericSpecTypeSymbol.cs | 280 +++++++++++++++++- .../Reflection/ReflectionMethodBaseSymbol.cs | 44 +-- .../Reflection/ReflectionMethodSymbol.cs | 88 +++++- .../Reflection/ReflectionMethodTable.cs | 4 +- .../Reflection/ReflectionParameterSpecInfo.cs | 51 ++++ .../Reflection/ReflectionTypeSpecSymbol.cs | 3 + .../Symbols/Reflection/ReflectionUtil.cs | 35 +++ .../java/lang/invoke/MethodHandleNatives.cs | 2 +- src/IKVM.Runtime/MethodHandleUtil.compiler.cs | 3 +- .../MethodHandleUtil.jniexport.cs | 2 +- 13 files changed, 613 insertions(+), 38 deletions(-) create mode 100644 src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterSpecInfo.cs diff --git a/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs b/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs index 31e4ecaea..f12186725 100644 --- a/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs +++ b/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs @@ -490,6 +490,25 @@ public void CanGetMethodsFromTypeBuilder() incompleteMethod.Should().BeSameAs(method); } + /// + /// Generics closed over a type builder need to be handled specially. + /// + [TestMethod] + public void CanCreateRuntimeGenericTypeOfTypeBuilder() + { + var c = new ReflectionSymbolContext(); + var a = c.DefineAssembly(new AssemblyIdentity("DynamicAssembly"), false, false); + var m = a.DefineModule("DynamicModule"); + var type = m.DefineType("DynamicType"); + var funcType = c.GetOrCreateTypeSymbol(typeof(Func<,>)); + var realFuncType = funcType.MakeGenericType(type, type); + var invokeMethod = realFuncType.GetMethod("Invoke"); + invokeMethod.Should().NotBeNull(); + invokeMethod.GetParameters().Should().HaveCount(1); + invokeMethod.GetParameters()[0].ParameterType.Should().BeSameAs(type); + invokeMethod.ReturnType.Should().BeSameAs(type); + } + } } diff --git a/src/IKVM.CoreLib/Reflection/ReflectionExtensions.cs b/src/IKVM.CoreLib/Reflection/ReflectionExtensions.cs index ee2c0b7b9..b7966e9d0 100644 --- a/src/IKVM.CoreLib/Reflection/ReflectionExtensions.cs +++ b/src/IKVM.CoreLib/Reflection/ReflectionExtensions.cs @@ -11,11 +11,19 @@ namespace IKVM.CoreLib.Reflection static class ReflectionExtensions { + static readonly ParameterExpression _constructorInfoParameter = Expression.Parameter(typeof(ConstructorInfo), "p"); + static readonly ParameterExpression _methodInfoParameter = Expression.Parameter(typeof(MethodInfo), "p"); + static readonly ParameterExpression _fieldInfoParameter = Expression.Parameter(typeof(FieldInfo), "p"); + static readonly ParameterExpression _assemblyBuilderRuntimeAssemblyParameter = Expression.Parameter(typeof(AssemblyBuilder), "p"); static readonly ParameterExpression _propertyBuilderParameter = Expression.Parameter(typeof(PropertyBuilder), "p"); static readonly ParameterExpression _eventBuilderParameter = Expression.Parameter(typeof(EventBuilder), "p"); static readonly ParameterExpression _parameterBuilderParameter = Expression.Parameter(typeof(ParameterBuilder), "p"); + static readonly Type _constructorOnTypeBuilderInstantiationType = typeof(TypeBuilder).Assembly.GetType("System.Reflection.Emit.ConstructorOnTypeBuilderInstantiation", true)!; + static readonly Type _methodOnTypeBuilderInstantiationType = typeof(TypeBuilder).Assembly.GetType("System.Reflection.Emit.MethodOnTypeBuilderInstantiation", true)!; + static readonly Type _fieldOnTypeBuilderInstantiationType = typeof(TypeBuilder).Assembly.GetType("System.Reflection.Emit.FieldOnTypeBuilderInstantiation", true)!; + #if NET #if NET8_0_OR_GREATER @@ -25,6 +33,27 @@ static class ReflectionExtensions static readonly Type _eventBuilderType = typeof(EventBuilder).Assembly.GetType("System.Reflection.Emit.RuntimeEventBuilder", true)!; static readonly Type _parameterBuilderType = typeof(ParameterBuilder).Assembly.GetType("System.Reflection.Emit.RuntimeParameterBuilder", true)!; + static readonly Func _getConstructorOnTypeBuilderInstantiationConstructorFunc = Expression.Lambda>( + Expression.Field( + Expression.ConvertChecked(_constructorInfoParameter, _constructorOnTypeBuilderInstantiationType), + _constructorOnTypeBuilderInstantiationType.GetField("_ctor", BindingFlags.NonPublic | BindingFlags.Instance) ?? throw new InvalidOperationException()), + _constructorInfoParameter) + .Compile(); + + static readonly Func _getMethodOnTypeBuilderInstantiationMethodFunc = Expression.Lambda>( + Expression.Field( + Expression.ConvertChecked(_methodInfoParameter, _methodOnTypeBuilderInstantiationType), + _methodOnTypeBuilderInstantiationType.GetField("_method", BindingFlags.NonPublic | BindingFlags.Instance) ?? throw new InvalidOperationException()), + _methodInfoParameter) + .Compile(); + + static readonly Func _getFieldOnTypeBuilderInstantiationFieldFunc = Expression.Lambda>( + Expression.Field( + Expression.ConvertChecked(_fieldInfoParameter, _fieldOnTypeBuilderInstantiationType), + _fieldOnTypeBuilderInstantiationType.GetField("_field", BindingFlags.NonPublic | BindingFlags.Instance) ?? throw new InvalidOperationException()), + _fieldInfoParameter) + .Compile(); + #else static readonly Type _assemblyBuilderType = typeof(AssemblyBuilder).Assembly.GetType("System.Reflection.Emit.AssemblyBuilder", true)!; @@ -32,6 +61,27 @@ static class ReflectionExtensions static readonly Type _eventBuilderType = typeof(EventBuilder).Assembly.GetType("System.Reflection.Emit.EventBuilder", true)!; static readonly Type _parameterBuilderType = typeof(ParameterBuilder).Assembly.GetType("System.Reflection.Emit.ParameterBuilder", true)!; + static readonly Func _getConstructorOnTypeBuilderInstantiationConstructorFunc = Expression.Lambda>( + Expression.Field( + Expression.ConvertChecked(_constructorInfoParameter, _constructorOnTypeBuilderInstantiationType), + _constructorOnTypeBuilderInstantiationType.GetField("m_ctor", BindingFlags.NonPublic | BindingFlags.Instance) ?? throw new InvalidOperationException()), + _constructorInfoParameter) + .Compile(); + + static readonly Func _getMethodOnTypeBuilderInstantiationMethodFunc = Expression.Lambda>( + Expression.Field( + Expression.ConvertChecked(_methodInfoParameter, _methodOnTypeBuilderInstantiationType), + _methodOnTypeBuilderInstantiationType.GetField("m_method", BindingFlags.NonPublic | BindingFlags.Instance) ?? throw new InvalidOperationException()), + _methodInfoParameter) + .Compile(); + + static readonly Func _getFieldOnTypeBuilderInstantiationFieldFunc = Expression.Lambda>( + Expression.Field( + Expression.ConvertChecked(_fieldInfoParameter, _fieldOnTypeBuilderInstantiationType), + _fieldOnTypeBuilderInstantiationType.GetField("m_field", BindingFlags.NonPublic | BindingFlags.Instance) ?? throw new InvalidOperationException()), + _fieldInfoParameter) + .Compile(); + #endif static readonly Func _getAssemblyBuilderRuntimeAssemblyFunc = Expression.Lambda>( @@ -75,6 +125,27 @@ static class ReflectionExtensions static readonly Type _eventBuilderType = typeof(EventBuilder).Assembly.GetType("System.Reflection.Emit.EventBuilder", true)!; static readonly Type _parameterBuilderType = typeof(ParameterBuilder).Assembly.GetType("System.Reflection.Emit.ParameterBuilder", true)!; + static readonly Func _getConstructorOnTypeBuilderInstantiationConstructorFunc = Expression.Lambda>( + Expression.Field( + Expression.ConvertChecked(_constructorInfoParameter, _constructorOnTypeBuilderInstantiationType), + _constructorOnTypeBuilderInstantiationType.GetField("m_ctor", BindingFlags.NonPublic | BindingFlags.Instance) ?? throw new InvalidOperationException()), + _constructorInfoParameter) + .Compile(); + + static readonly Func _getMethodOnTypeBuilderInstantiationMethodFunc = Expression.Lambda>( + Expression.Field( + Expression.ConvertChecked(_methodInfoParameter, _methodOnTypeBuilderInstantiationType), + _methodOnTypeBuilderInstantiationType.GetField("m_method", BindingFlags.NonPublic | BindingFlags.Instance) ?? throw new InvalidOperationException()), + _methodInfoParameter) + .Compile(); + + static readonly Func _getFieldOnTypeBuilderInstantiationFieldFunc = Expression.Lambda>( + Expression.Field( + Expression.ConvertChecked(_fieldInfoParameter, _fieldOnTypeBuilderInstantiationType), + _fieldOnTypeBuilderInstantiationType.GetField("m_field", BindingFlags.NonPublic | BindingFlags.Instance) ?? throw new InvalidOperationException()), + _fieldInfoParameter) + .Compile(); + static readonly Func _getAssemblyBuilderRuntimeAssemblyFunc = Expression.Lambda>( Expression.Call( Expression.ConvertChecked(_assemblyBuilderRuntimeAssemblyParameter, _assemblyBuilderType), @@ -121,6 +192,11 @@ static class ReflectionExtensions _eventBuilderParameter) .Compile(); + /// + /// Gets the type. + /// + public static Type MethodOnTypeBuilderInstantiationType => _methodOnTypeBuilderInstantiationType; + /// /// Gets the metadata token for the specified . /// @@ -212,6 +288,15 @@ public static int GetMetadataTokenSafe(this FieldInfo field) } #endif +#if NET8_0_OR_GREATER || NETFRAMEWORK + // field is instance of FieldOnTypeBuilderInstantiation + if (_fieldOnTypeBuilderInstantiationType.IsInstanceOfType(field)) + { + var f = _getFieldOnTypeBuilderInstantiationFieldFunc(field); + return f.GetMetadataTokenSafe(); + } +#endif + return field.GetMetadataToken(); } @@ -275,6 +360,15 @@ public static int GetMetadataTokenSafe(this ConstructorInfo ctor) } #endif +#if NET8_0_OR_GREATER || NETFRAMEWORK + // ctor is instance of ConstructorOnTypeBuilderInstantiation + if (_constructorOnTypeBuilderInstantiationType.IsInstanceOfType(ctor)) + { + var c = _getConstructorOnTypeBuilderInstantiationConstructorFunc(ctor); + return c.GetMetadataTokenSafe(); + } +#endif + return ctor.GetMetadataToken(); } @@ -306,17 +400,35 @@ public static int GetMetadataTokenSafe(this MethodInfo method) } #endif +#if NET8_0_OR_GREATER || NETFRAMEWORK + // method is instance of MethodOnTypeBuilderInstantiation + if (_methodOnTypeBuilderInstantiationType.IsInstanceOfType(method)) + { + var m = _getMethodOnTypeBuilderInstantiationMethodFunc(method); + return m.GetMetadataTokenSafe(); + } +#endif + +#if NET6_0 + // method is instance of MethodOnTypeBuilderInstantiation + if (_methodOnTypeBuilderInstantiationType.IsInstanceOfType(method)) + { + var m = _getMethodOnTypeBuilderInstantiationMethodFunc(method); + return m.GetMetadataTokenSafe(); + } +#endif + return method.GetMetadataToken(); } /// /// Gets the metadata row number for the specified . /// - /// + /// /// - public static int GetMetadataTokenRowNumberSafe(this MethodInfo ctor) + public static int GetMetadataTokenRowNumberSafe(this MethodInfo method) { - return MetadataTokens.GetRowNumber(MetadataTokens.MethodDefinitionHandle(ctor.GetMetadataTokenSafe())); + return MetadataTokens.GetRowNumber(MetadataTokens.MethodDefinitionHandle(method.GetMetadataTokenSafe())); } /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs index 2dc1d53f1..58fdd779b 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs @@ -30,7 +30,7 @@ class ReflectionMethodSymbolBuilder : ReflectionMethodSymbol, IReflectionMethodS public ReflectionMethodSymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbolBuilder resolvingModule, IReflectionTypeSymbolBuilder? resolvingType, MethodBuilder builder) : base(context, resolvingModule, resolvingType, builder) { - _builder = builder; + _builder = builder ?? throw new ArgumentNullException(nameof(builder)); } /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericSpecTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericSpecTypeSymbol.cs index 3470c6b2f..e369f1e10 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericSpecTypeSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericSpecTypeSymbol.cs @@ -1,5 +1,7 @@ using System; using System.Linq; +using System.Reflection; +using System.Reflection.Emit; namespace IKVM.CoreLib.Symbols.Reflection { @@ -7,7 +9,33 @@ namespace IKVM.CoreLib.Symbols.Reflection class ReflectionGenericSpecTypeSymbol : ReflectionTypeSpecSymbol { - readonly IReflectionTypeSymbol[] genericTypeArguments; + /// + /// Returns true if the type or any generic type definition or generic arguments are type builders. That is, is this a TypeBuilderInstantiation instance. + /// + /// + /// + static bool ContainsTypeBuilder(Type type) + { + // find deepest element type + while (type.HasElementType) + type = type.GetElementType() ?? throw new InvalidOperationException(); + + // type definition, or generic type definition, result is whether it is itself a type builder + if (type.IsGenericType == false || type.IsGenericTypeDefinition) + return type is TypeBuilder; + + // are arguments of closed generic themselves type builder instantiations? + foreach (var arg in type.GetGenericArguments()) + if (ContainsTypeBuilder(arg)) + return true; + + // are we a type builder? + return type.GetGenericTypeDefinition() is TypeBuilder; + } + + readonly IReflectionTypeSymbol[] _genericTypeArguments; + Type? _underlyingType; + bool? _underlyingTypeContainsTypeBuilder; /// /// Initializes a new instance. @@ -19,14 +47,258 @@ class ReflectionGenericSpecTypeSymbol : ReflectionTypeSpecSymbol public ReflectionGenericSpecTypeSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol elementType, IReflectionTypeSymbol[] genericTypeArguments) : base(context, resolvingModule, elementType) { - this.genericTypeArguments = genericTypeArguments ?? throw new ArgumentNullException(nameof(genericTypeArguments)); + _genericTypeArguments = genericTypeArguments ?? throw new ArgumentNullException(nameof(genericTypeArguments)); + } + + /// + public override Type UnderlyingType => _underlyingType ??= ElementType.UnderlyingType.MakeGenericType(_genericTypeArguments.Select(i => i.UnderlyingType).ToArray()); + + /// + public override Type UnderlyingRuntimeType => ElementType.UnderlyingRuntimeType.MakeGenericType(_genericTypeArguments.Select(i => i.UnderlyingRuntimeType).ToArray()); + + /// + /// Returns true if the underlying type contains a type builder. + /// + /// + bool UnderlyingTypeContainsTypeBuilder => _underlyingTypeContainsTypeBuilder ??= ContainsTypeBuilder(UnderlyingType); + + /// + public override IFieldSymbol[] GetFields() + { + if (UnderlyingTypeContainsTypeBuilder) + { + var l = ElementType.UnderlyingType.GetFields(); + var a = new IFieldSymbol[l.Length]; + for (int i = 0; i < l.Length; i++) + a[i] = ResolveFieldSymbol(TypeBuilder.GetField(UnderlyingType, l[i])); + + return a; + } + + return base.GetFields(); + } + + /// + public override IFieldSymbol[] GetFields(BindingFlags bindingAttr) + { + if (UnderlyingTypeContainsTypeBuilder) + { + var l = ElementType.UnderlyingType.GetFields(bindingAttr); + var a = new IFieldSymbol[l.Length]; + for (int i = 0; i < l.Length; i++) + a[i] = ResolveFieldSymbol(TypeBuilder.GetField(UnderlyingType, l[i])); + + return a; + } + + return base.GetFields(bindingAttr); + } + + /// + public override IFieldSymbol? GetField(string name) + { + if (UnderlyingTypeContainsTypeBuilder) + if (ElementType.UnderlyingType.GetField(name) is { } f) + return ResolveFieldSymbol(TypeBuilder.GetField(UnderlyingType, f)); + + return base.GetField(name); + } + + /// + public override IFieldSymbol? GetField(string name, BindingFlags bindingAttr) + { + if (UnderlyingTypeContainsTypeBuilder) + if (ElementType.UnderlyingType.GetField(name, bindingAttr) is { } f) + return ResolveFieldSymbol(TypeBuilder.GetField(UnderlyingType, f)); + + return base.GetField(name, bindingAttr); + } + + /// + public override IConstructorSymbol[] GetConstructors() + { + if (UnderlyingTypeContainsTypeBuilder) + { + var l = ElementType.UnderlyingType.GetConstructors(); + var a = new IConstructorSymbol[l.Length]; + for (int i = 0; i < l.Length; i++) + a[i] = ResolveConstructorSymbol(TypeBuilder.GetConstructor(UnderlyingType, l[i])); + + return a; + } + + return base.GetConstructors(); + } + + /// + public override IConstructorSymbol[] GetConstructors(BindingFlags bindingAttr) + { + if (UnderlyingTypeContainsTypeBuilder) + { + var l = ElementType.UnderlyingType.GetConstructors(bindingAttr); + var a = new IConstructorSymbol[l.Length]; + for (int i = 0; i < l.Length; i++) + a[i] = ResolveConstructorSymbol(TypeBuilder.GetConstructor(UnderlyingType, l[i])); + + return a; + } + + return base.GetConstructors(bindingAttr); + } + + /// + public override IConstructorSymbol? GetConstructor(ITypeSymbol[] types) + { + if (UnderlyingTypeContainsTypeBuilder) + if (ElementType.UnderlyingType.GetConstructor(types.Unpack()) is { } m) + return ResolveConstructorSymbol(TypeBuilder.GetConstructor(UnderlyingType, m)); + + return base.GetConstructor(types); + } + + /// + public override IConstructorSymbol? GetConstructor(BindingFlags bindingAttr, ITypeSymbol[] types) + { + if (UnderlyingTypeContainsTypeBuilder) + if (ElementType.UnderlyingType.GetConstructor(bindingAttr, null, types.Unpack(), null) is { } m) + return ResolveConstructorSymbol(TypeBuilder.GetConstructor(UnderlyingType, m)); + + return base.GetConstructor(bindingAttr, types); + } + + /// + public override IMethodSymbol[] GetMethods() + { + if (UnderlyingTypeContainsTypeBuilder) + { + var l = ElementType.UnderlyingType.GetMethods(); + var a = new IMethodSymbol[l.Length]; + for (int i = 0; i < l.Length; i++) + a[i] = ResolveMethodSymbol(TypeBuilder.GetMethod(UnderlyingType, l[i])); + + return a; + } + + return base.GetMethods(); + } + + /// + public override IMethodSymbol[] GetMethods(BindingFlags bindingAttr) + { + if (UnderlyingTypeContainsTypeBuilder) + { + var l = ElementType.UnderlyingType.GetMethods(bindingAttr); + var a = new IMethodSymbol[l.Length]; + for (int i = 0; i < l.Length; i++) + a[i] = ResolveMethodSymbol(TypeBuilder.GetMethod(UnderlyingType, l[i])); + + return a; + } + + return base.GetMethods(bindingAttr); + } + + /// + public override IMethodSymbol? GetMethod(string name) + { + if (UnderlyingTypeContainsTypeBuilder) + if (ElementType.UnderlyingType.GetMethod(name) is { } m) + return ResolveMethodSymbol(TypeBuilder.GetMethod(UnderlyingType, m)); + + return base.GetMethod(name); + } + + /// + public override IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr) + { + if (UnderlyingTypeContainsTypeBuilder) + if (ElementType.UnderlyingType.GetMethod(name, bindingAttr) is { } m) + return ResolveMethodSymbol(TypeBuilder.GetMethod(UnderlyingType, m)); + + return base.GetMethod(name, bindingAttr); + } + + /// + public override IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) + { + if (UnderlyingTypeContainsTypeBuilder) + if (ElementType.UnderlyingType.GetMethod(name, types.Unpack()) is { } m) + return ResolveMethodSymbol(TypeBuilder.GetMethod(UnderlyingType, m)); + + return base.GetMethod(name, types); + } + + /// + public override IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types) + { + if (UnderlyingTypeContainsTypeBuilder) + if (ElementType.UnderlyingType.GetMethod(name, bindingAttr, null, types.Unpack(), null) is { } m) + return ResolveMethodSymbol(TypeBuilder.GetMethod(UnderlyingType, m)); + + return base.GetMethod(name, bindingAttr, types); + } + + /// + public override IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types, ParameterModifier[]? modifiers) + { + if (UnderlyingTypeContainsTypeBuilder) + if (ElementType.UnderlyingType.GetMethod(name, bindingAttr, null, types.Unpack(), modifiers) is { } m) + return ResolveMethodSymbol(TypeBuilder.GetMethod(UnderlyingType, m)); + + return base.GetMethod(name, bindingAttr, types, modifiers); + } + + /// + public override IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers) + { + if (UnderlyingTypeContainsTypeBuilder) + if (ElementType.UnderlyingType.GetMethod(name, bindingAttr, null, callConvention, types.Unpack(), modifiers) is { } m) + return ResolveMethodSymbol(TypeBuilder.GetMethod(UnderlyingType, m)); + + return base.GetMethod(name, bindingAttr, callConvention, types, modifiers); + } + + /// + public override IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, ParameterModifier[]? modifiers) + { + if (UnderlyingTypeContainsTypeBuilder) +#if NETFRAMEWORK + throw new NotSupportedException(); +#else + if (ElementType.UnderlyingType.GetMethod(name, genericParameterCount, types.Unpack(), modifiers) is { } m) + return ResolveMethodSymbol(TypeBuilder.GetMethod(UnderlyingType, m)); +#endif + + return base.GetMethod(name, genericParameterCount, types, modifiers); } /// - public override Type UnderlyingType => ElementType.UnderlyingType.MakeGenericType(genericTypeArguments.Select(i => i.UnderlyingType).ToArray()); + public override IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, ITypeSymbol[] types, ParameterModifier[]? modifiers) + { + if (UnderlyingTypeContainsTypeBuilder) +#if NETFRAMEWORK + throw new NotSupportedException(); +#else + if (ElementType.UnderlyingType.GetMethod(name, genericParameterCount, bindingAttr, null, types.Unpack(), modifiers) is { } m) + return ResolveMethodSymbol(TypeBuilder.GetMethod(UnderlyingType, m)); +#endif + + return base.GetMethod(name, genericParameterCount, bindingAttr, types, modifiers); + } /// - public override Type UnderlyingRuntimeType => ElementType.UnderlyingRuntimeType.MakeGenericType(genericTypeArguments.Select(i => i.UnderlyingRuntimeType).ToArray()); + public override IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers) + { + if (UnderlyingTypeContainsTypeBuilder) +#if NETFRAMEWORK + throw new NotSupportedException(); +#else + if (ElementType.UnderlyingType.GetMethod(name, genericParameterCount, bindingAttr, null, callConvention, types.Unpack(), modifiers) is { } m) + return ResolveMethodSymbol(TypeBuilder.GetMethod(UnderlyingType, m)); +#endif + + return base.GetMethod(name, genericParameterCount, bindingAttr, callConvention, types, modifiers); + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodBaseSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodBaseSymbol.cs index 8e7fdc126..d30f9d8a4 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodBaseSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodBaseSymbol.cs @@ -54,76 +54,76 @@ public IReflectionParameterSymbolBuilder GetOrCreateParameterSymbol(ParameterBui public override sealed MemberInfo UnderlyingRuntimeMember => UnderlyingRuntimeMethodBase; /// - public System.Reflection.MethodAttributes Attributes => (System.Reflection.MethodAttributes)UnderlyingMethodBase.Attributes; + public virtual System.Reflection.MethodAttributes Attributes => (System.Reflection.MethodAttributes)UnderlyingMethodBase.Attributes; /// - public System.Reflection.CallingConventions CallingConvention => (System.Reflection.CallingConventions)UnderlyingMethodBase.CallingConvention; + public virtual System.Reflection.CallingConventions CallingConvention => (System.Reflection.CallingConventions)UnderlyingMethodBase.CallingConvention; /// - public bool ContainsGenericParameters => UnderlyingMethodBase.ContainsGenericParameters; + public virtual bool ContainsGenericParameters => UnderlyingMethodBase.ContainsGenericParameters; /// - public bool IsAbstract => UnderlyingMethodBase.IsAbstract; + public virtual bool IsAbstract => UnderlyingMethodBase.IsAbstract; /// - public bool IsAssembly => UnderlyingMethodBase.IsAssembly; + public virtual bool IsAssembly => UnderlyingMethodBase.IsAssembly; /// - public bool IsConstructor => UnderlyingMethodBase.IsConstructor; + public virtual bool IsConstructor => UnderlyingMethodBase.IsConstructor; /// - public bool IsFamily => UnderlyingMethodBase.IsFamily; + public virtual bool IsFamily => UnderlyingMethodBase.IsFamily; /// - public bool IsFamilyAndAssembly => UnderlyingMethodBase.IsFamilyAndAssembly; + public virtual bool IsFamilyAndAssembly => UnderlyingMethodBase.IsFamilyAndAssembly; /// - public bool IsFamilyOrAssembly => UnderlyingMethodBase.IsFamilyOrAssembly; + public virtual bool IsFamilyOrAssembly => UnderlyingMethodBase.IsFamilyOrAssembly; /// - public bool IsFinal => UnderlyingMethodBase.IsFinal; + public virtual bool IsFinal => UnderlyingMethodBase.IsFinal; /// - public bool IsGenericMethod => UnderlyingMethodBase.IsGenericMethod; + public virtual bool IsGenericMethod => UnderlyingMethodBase.IsGenericMethod; /// - public bool IsGenericMethodDefinition => UnderlyingMethodBase.IsGenericMethodDefinition; + public virtual bool IsGenericMethodDefinition => UnderlyingMethodBase.IsGenericMethodDefinition; /// - public bool IsHideBySig => UnderlyingMethodBase.IsHideBySig; + public virtual bool IsHideBySig => UnderlyingMethodBase.IsHideBySig; /// - public bool IsPrivate => UnderlyingMethodBase.IsPrivate; + public virtual bool IsPrivate => UnderlyingMethodBase.IsPrivate; /// - public bool IsPublic => UnderlyingMethodBase.IsPublic; + public virtual bool IsPublic => UnderlyingMethodBase.IsPublic; /// - public bool IsStatic => UnderlyingMethodBase.IsStatic; + public virtual bool IsStatic => UnderlyingMethodBase.IsStatic; /// - public bool IsVirtual => UnderlyingMethodBase.IsVirtual; + public virtual bool IsVirtual => UnderlyingMethodBase.IsVirtual; /// - public bool IsSpecialName => UnderlyingMethodBase.IsSpecialName; + public virtual bool IsSpecialName => UnderlyingMethodBase.IsSpecialName; /// - public System.Reflection.MethodImplAttributes MethodImplementationFlags => (System.Reflection.MethodImplAttributes)UnderlyingMethodBase.MethodImplementationFlags; + public virtual System.Reflection.MethodImplAttributes MethodImplementationFlags => (System.Reflection.MethodImplAttributes)UnderlyingMethodBase.MethodImplementationFlags; /// - public ITypeSymbol[] GetGenericArguments() + public virtual ITypeSymbol[] GetGenericArguments() { return ResolveTypeSymbols(UnderlyingMethodBase.GetGenericArguments()); } /// - public System.Reflection.MethodImplAttributes GetMethodImplementationFlags() + public virtual System.Reflection.MethodImplAttributes GetMethodImplementationFlags() { return (System.Reflection.MethodImplAttributes)UnderlyingMethodBase.GetMethodImplementationFlags(); } /// - public IParameterSymbol[] GetParameters() + public virtual IParameterSymbol[] GetParameters() { return ResolveParameterSymbols(UnderlyingMethodBase.GetParameters()); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs index 358d8b886..33ff9fa02 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs @@ -1,7 +1,11 @@ using System; using System.Reflection; using System.Reflection.Emit; +using System.Threading; +using IKVM.CoreLib.Threading; +using IKVM.CoreLib.Collections; +using IKVM.CoreLib.Reflection; using IKVM.CoreLib.Symbols.Reflection.Emit; namespace IKVM.CoreLib.Symbols.Reflection @@ -15,6 +19,9 @@ class ReflectionMethodSymbol : ReflectionMethodBaseSymbol, IReflectionMethodSymb ReflectionGenericTypeParameterTable _genericTypeParameterTable; ReflectionMethodSpecTable _specTable; + ReflectionParameterSpecInfo[]? _specParameters; + ReflectionParameterSpecInfo? _specReturnParameter; + /// /// Initializes a new instance. /// @@ -69,8 +76,53 @@ public IReflectionMethodSymbol GetOrCreateGenericMethodSymbol(MethodInfo method) /// public IParameterSymbol ReturnParameter => ResolveParameterSymbol(UnderlyingMethod.ReturnParameter); + /// + /// Gets the return type of the method. + /// + /// + IParameterSymbol GetReturnParameter() + { + if (ReflectionExtensions.MethodOnTypeBuilderInstantiationType.IsInstanceOfType(_method)) + return GetReturnParameterForMethodOnTypeBuilderInstantiation(); + else + return ResolveParameterSymbol(UnderlyingMethod.ReturnParameter); + } + + /// + /// Gets the return parameter in the case that this method is a . + /// + /// + IParameterSymbol GetReturnParameterForMethodOnTypeBuilderInstantiation() + { + if (_specReturnParameter == null) + Interlocked.CompareExchange(ref _specReturnParameter, new ReflectionParameterSpecInfo(_method, _method.ReturnParameter, _method.DeclaringType!.GetGenericArguments()), null); + + return ResolveParameterSymbol(_specReturnParameter); + } + /// - public ITypeSymbol ReturnType => ResolveTypeSymbol(UnderlyingMethod.ReturnType); + public ITypeSymbol ReturnType => GetReturnType(); + + /// + /// Gets the return type of the method. + /// + /// + ITypeSymbol GetReturnType() + { + if (ReflectionExtensions.MethodOnTypeBuilderInstantiationType.IsInstanceOfType(_method)) + return GetReturnTypeForMethodOnTypeBuilderInstantiation(); + else + return ResolveTypeSymbol(UnderlyingMethod.ReturnType); + } + + /// + /// Gets the return type in the case that this method is a . + /// + /// + ITypeSymbol GetReturnTypeForMethodOnTypeBuilderInstantiation() + { + return ResolveTypeSymbol(_method.ReturnType.SubstituteGenericTypes(_method.DeclaringType!.GetGenericArguments())); + } /// public ICustomAttributeProvider ReturnTypeCustomAttributes => throw new NotImplementedException(); @@ -87,6 +139,40 @@ public IMethodSymbol GetGenericMethodDefinition() return ResolveMethodSymbol(UnderlyingMethod.GetGenericMethodDefinition()); } + /// + public override IParameterSymbol[] GetParameters() + { + if (ReflectionExtensions.MethodOnTypeBuilderInstantiationType.IsInstanceOfType(_method)) + return GetParametersForMethodOnTypeBuilderInstantiation(); + else + return base.GetParameters(); + } + + /// + /// Gets the parameters in the case that this method is a . + /// + /// + IParameterSymbol[] GetParametersForMethodOnTypeBuilderInstantiation() + { + // we cache the spec parameters to avoid creating them repeatidly + if (_specParameters == null) + { + var l = _method.GetParameters(); + var a = new ReflectionParameterSpecInfo[l.Length]; + for (int i = 0; i < l.Length; i++) + a[i] = new ReflectionParameterSpecInfo(_method, l[i], _method.DeclaringType!.GetGenericArguments()); + + Interlocked.CompareExchange(ref _specParameters, a, null); + } + + // resolve into symbols + var symbols = new IParameterSymbol[_specParameters.Length]; + for (int i = 0; i < _specParameters.Length; i++) + symbols[i] = ResolveParameterSymbol(_specParameters[i]); + + return symbols; + } + /// public IMethodSymbol MakeGenericMethod(params ITypeSymbol[] typeArguments) { diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodTable.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodTable.cs index 6e58bb23b..47fde2273 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodTable.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodTable.cs @@ -1,9 +1,7 @@ using System; -using System.Collections.Concurrent; -using System.Collections.Generic; +using System.Diagnostics.Eventing.Reader; using System.Reflection; using System.Reflection.Emit; -using System.Reflection.Metadata.Ecma335; using System.Threading; using IKVM.CoreLib.Collections; diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterSpecInfo.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterSpecInfo.cs new file mode 100644 index 000000000..42bc91d6b --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterSpecInfo.cs @@ -0,0 +1,51 @@ +using System; +using System.Reflection; + +namespace IKVM.CoreLib.Symbols.Reflection +{ + + /// + /// Fake implementation that is used for instantiated method parameters. + /// + class ReflectionParameterSpecInfo : ParameterInfo + { + + readonly MemberInfo _member; + readonly ParameterInfo _parameter; + readonly Type[] _genericTypeArguments; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + public ReflectionParameterSpecInfo(MemberInfo member, ParameterInfo parameter, Type[] genericTypeArguments) + { + _member = member ?? throw new ArgumentNullException(nameof(member)); + _parameter = parameter ?? throw new ArgumentNullException(nameof(parameter)); + _genericTypeArguments = genericTypeArguments ?? throw new ArgumentNullException(nameof(genericTypeArguments)); + } + + /// + public override ParameterAttributes Attributes => (ParameterAttributes)_parameter.Attributes; + + /// + public override MemberInfo Member => _member; + + /// + public override string? Name => _parameter.Name; + + /// + public override int Position => _parameter.Position; + + /// + public override int MetadataToken => throw new InvalidOperationException(); + + /// + public override Type ParameterType => _parameter.ParameterType.SubstituteGenericTypes(_genericTypeArguments); + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSpecSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSpecSymbol.cs index 121f36a58..abea83797 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSpecSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSpecSymbol.cs @@ -25,6 +25,9 @@ public ReflectionTypeSpecSymbol(ReflectionSymbolContext context, IReflectionModu /// protected IReflectionTypeSymbol ElementType => _elementType; + /// + public override bool IsComplete => ElementType.IsComplete; + } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionUtil.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionUtil.cs index d8991850d..c42fa284a 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionUtil.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionUtil.cs @@ -524,6 +524,41 @@ public static bool IsMethodDefinition(this MethodBase method) return method.IsGenericMethod == false || method.IsGenericMethodDefinition; } + /// + /// Substitutes generic type parameters into the specified type. + /// + /// + /// + /// + public static Type SubstituteGenericTypes(this Type type, Type[] genericTypeArguments) + { + if (type.IsGenericParameter) + return genericTypeArguments[type.GenericParameterPosition]; + + if (type.IsGenericType) + { + var anySubstituted = false; + var typeDef = type.GetGenericTypeDefinition(); + var genericTypeParameters = typeDef.GetGenericArguments(); + + for (int i = 0; i < genericTypeParameters.Length; i++) + { + var typeParameter = SubstituteGenericTypes(genericTypeParameters[i], genericTypeArguments); + if (genericTypeParameters[i] != typeParameter) + { + genericTypeParameters[i] = typeParameter; + anySubstituted = true; + } + } + + // if any parameters were substituted + if (anySubstituted) + return typeDef.MakeGenericType(genericTypeParameters); + } + + return type; + } + } } diff --git a/src/IKVM.Runtime/Java/Externs/java/lang/invoke/MethodHandleNatives.cs b/src/IKVM.Runtime/Java/Externs/java/lang/invoke/MethodHandleNatives.cs index 778db45f8..8bd4b0a3b 100644 --- a/src/IKVM.Runtime/Java/Externs/java/lang/invoke/MethodHandleNatives.cs +++ b/src/IKVM.Runtime/Java/Externs/java/lang/invoke/MethodHandleNatives.cs @@ -466,7 +466,7 @@ public static object staticFieldBase(global::java.lang.invoke.MemberName self) internal static void InitializeCallSite(global::java.lang.invoke.CallSite site) { - var type = typeof(IKVM.Runtime.IndyCallSite<>).MakeGenericType(JVM.Context.MethodHandleUtil.GetDelegateTypeForInvokeExact(site.type()).GetUnderlyingType()); + var type = typeof(IKVM.Runtime.IndyCallSite<>).MakeGenericType(JVM.Context.MethodHandleUtil.GetDelegateTypeForInvokeExact(site.type()).GetUnderlyingRuntimeType()); var ics = (IKVM.Runtime.IIndyCallSite)Activator.CreateInstance(type, true); Interlocked.CompareExchange(ref site.ics, ics, null); } diff --git a/src/IKVM.Runtime/MethodHandleUtil.compiler.cs b/src/IKVM.Runtime/MethodHandleUtil.compiler.cs index 041845bb1..f55b3879e 100644 --- a/src/IKVM.Runtime/MethodHandleUtil.compiler.cs +++ b/src/IKVM.Runtime/MethodHandleUtil.compiler.cs @@ -1,5 +1,4 @@ -using System.Reflection; -using System.Reflection.Emit; +using System.Reflection.Emit; using IKVM.CoreLib.Symbols; diff --git a/src/IKVM.Runtime/MethodHandleUtil.jniexport.cs b/src/IKVM.Runtime/MethodHandleUtil.jniexport.cs index b44ab8b5b..7c050b865 100644 --- a/src/IKVM.Runtime/MethodHandleUtil.jniexport.cs +++ b/src/IKVM.Runtime/MethodHandleUtil.jniexport.cs @@ -644,7 +644,7 @@ internal T GetDelegateForInvokeExact(global::java.lang.invoke.MethodHandle mh if (mh._invokeExactDelegate == null) { type._invokeExactDynamicMethod ??= DynamicMethodBuilder.CreateInvokeExact(context, type); - mh._invokeExactDelegate = type._invokeExactDynamicMethod.CreateDelegate(GetDelegateTypeForInvokeExact(type).GetUnderlyingType(), mh); + mh._invokeExactDelegate = type._invokeExactDynamicMethod.CreateDelegate(GetDelegateTypeForInvokeExact(type).GetUnderlyingRuntimeType(), mh); var del = mh._invokeExactDelegate as T; if (del != null) return del; From dbf2cd8977b005f6a9071ff1f691130e134d6935 Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Fri, 18 Oct 2024 23:22:21 -0500 Subject: [PATCH 46/51] use runtime types --- src/IKVM.Runtime/ByteCodeHelper.cs | 4 +-- src/IKVM.Runtime/JNI/JNIEnv.cs | 12 +++---- .../Java/Externs/java/io/ObjectStreamClass.cs | 8 ++--- .../Java/Externs/sun/misc/Unsafe.cs | 32 +++++++++---------- .../Externs/sun/reflect/ReflectionFactory.cs | 20 ++++++------ .../MethodHandleUtil.jniexport.cs | 6 ++-- .../RuntimeAssemblyClassLoader.cs | 2 +- src/IKVM.Runtime/RuntimeJavaField.cs | 18 +++++------ ...gedJavaType.AttributeAnnotationJavaType.cs | 2 +- ...RuntimeManagedJavaType.EnumEnumJavaType.cs | 4 +-- ...ntimeManagedJavaType.EnumWrapJavaMethod.cs | 2 +- ...JavaType.ValueTypeDefaultCtorJavaMethod.cs | 2 +- src/IKVM.Runtime/SymbolExtensions.cs | 16 ++++++++-- .../Invoke/NativeInvokerBytecodeGenerator.cs | 4 +-- 14 files changed, 72 insertions(+), 60 deletions(-) diff --git a/src/IKVM.Runtime/ByteCodeHelper.cs b/src/IKVM.Runtime/ByteCodeHelper.cs index a4b6db89a..34a288e87 100644 --- a/src/IKVM.Runtime/ByteCodeHelper.cs +++ b/src/IKVM.Runtime/ByteCodeHelper.cs @@ -128,7 +128,7 @@ public static object DynamicMultianewarray(int[] lengths, global::java.lang.Clas Profiler.Count("DynamicMultianewarray"); var wrapper = RuntimeJavaType.FromClass(clazz); - var obj = multianewarray(wrapper.TypeAsArrayType.GetUnderlyingType().TypeHandle, lengths); + var obj = multianewarray(wrapper.TypeAsArrayType.GetUnderlyingRuntimeType().TypeHandle, lengths); if (wrapper.IsGhostArray) GhostTag.SetTag(obj, wrapper); @@ -147,7 +147,7 @@ public static object DynamicNewarray(int length, global::java.lang.Class clazz) throw new global::java.lang.NegativeArraySizeException(); var wrapper = RuntimeJavaType.FromClass(clazz); - var obj = Array.CreateInstance(wrapper.TypeAsArrayType.GetUnderlyingType(), length); + var obj = Array.CreateInstance(wrapper.TypeAsArrayType.GetUnderlyingRuntimeType(), length); if (wrapper.IsGhost || wrapper.IsGhostArray) GhostTag.SetTag(obj, wrapper.MakeArrayType(1)); diff --git a/src/IKVM.Runtime/JNI/JNIEnv.cs b/src/IKVM.Runtime/JNI/JNIEnv.cs index 789832c73..03b3c897a 100644 --- a/src/IKVM.Runtime/JNI/JNIEnv.cs +++ b/src/IKVM.Runtime/JNI/JNIEnv.cs @@ -628,9 +628,9 @@ static nint AllocObjectImpl(JNIEnv* pEnv, RuntimeJavaType wrapper) wrapper.Finish(); #if NETFRAMEWORK - return pEnv->MakeLocalRef(FormatterServices.GetUninitializedObject(wrapper.TypeAsBaseType.GetUnderlyingType())); + return pEnv->MakeLocalRef(FormatterServices.GetUninitializedObject(wrapper.TypeAsBaseType.GetUnderlyingRuntimeType())); #else - return pEnv->MakeLocalRef(RuntimeHelpers.GetUninitializedObject(wrapper.TypeAsBaseType.GetUnderlyingType())); + return pEnv->MakeLocalRef(RuntimeHelpers.GetUninitializedObject(wrapper.TypeAsBaseType.GetUnderlyingRuntimeType())); #endif } catch (RetargetableJavaException e) @@ -709,7 +709,7 @@ static object InvokeHelper(JNIEnv* pEnv, nint objHandle, nint methodID, JValue* // possible with remapped types throw new NotSupportedException($"Remapped type {mw.DeclaringType.Name} doesn't support constructor invocation on an existing instance"); } - else if (!mb.DeclaringType.GetUnderlyingType().IsInstanceOfType(obj)) + else if (!mb.DeclaringType.GetUnderlyingRuntimeType().IsInstanceOfType(obj)) { // we're trying to initialize an existing instance of a remapped type throw new NotSupportedException($"Unable to partially construct object of type {obj.GetType().FullName} to type {mb.DeclaringType.FullName}"); @@ -734,10 +734,10 @@ static object InvokeNonVirtual(JNIEnvContext env, RuntimeJavaMethod mw, object o if (mw.HasCallerID || mw.IsDynamicOnly) throw new NotSupportedException(); - if (mw.DeclaringType.IsRemapped && !mw.DeclaringType.TypeAsBaseType.GetUnderlyingType().IsInstanceOfType(obj)) + if (mw.DeclaringType.IsRemapped && !mw.DeclaringType.TypeAsBaseType.GetUnderlyingRuntimeType().IsInstanceOfType(obj)) return mw.InvokeNonvirtualRemapped(obj, argarray); - var del = (Delegate)Activator.CreateInstance(mw.GetDelegateType().GetUnderlyingType(), [obj, mw.GetMethod().GetUnderlyingMethodBase().MethodHandle.GetFunctionPointer()]); + var del = (Delegate)Activator.CreateInstance(mw.GetDelegateType().GetUnderlyingRuntimeType(), [obj, mw.GetMethod().GetUnderlyingMethodBase().MethodHandle.GetFunctionPointer()]); try { return del.DynamicInvoke(argarray); @@ -2157,7 +2157,7 @@ internal static nint NewObjectArray(JNIEnv* pEnv, jsize len, nint clazz, nint in try { // we want to support (non-primitive) value types so we can't cast to object[] - var a = Array.CreateInstance(RuntimeJavaType.FromClass((java.lang.Class)pEnv->UnwrapRef(clazz)).TypeAsArrayType.GetUnderlyingType(), len); + var a = Array.CreateInstance(RuntimeJavaType.FromClass((java.lang.Class)pEnv->UnwrapRef(clazz)).TypeAsArrayType.GetUnderlyingRuntimeType(), len); var o = pEnv->UnwrapRef(init); if (o != null) for (int i = 0; i < a.Length; i++) diff --git a/src/IKVM.Runtime/Java/Externs/java/io/ObjectStreamClass.cs b/src/IKVM.Runtime/Java/Externs/java/io/ObjectStreamClass.cs index 9208087fd..7d61dff83 100644 --- a/src/IKVM.Runtime/Java/Externs/java/io/ObjectStreamClass.cs +++ b/src/IKVM.Runtime/Java/Externs/java/io/ObjectStreamClass.cs @@ -256,10 +256,10 @@ internal FastFieldReflector(global::java.io.ObjectStreamField[] fields) throw x.ToJava(); } - var dmObjGetter = DynamicMethodUtil.Create("__", tw.TypeAsBaseType.GetUnderlyingType(), true, null, [typeof(object), typeof(object[])]); - var dmPrimGetter = DynamicMethodUtil.Create("__", tw.TypeAsBaseType.GetUnderlyingType(), true, null, [typeof(object), typeof(byte[])]); - var dmObjSetter = DynamicMethodUtil.Create("__", tw.TypeAsBaseType.GetUnderlyingType(), true, null, [typeof(object), typeof(object[])]); - var dmPrimSetter = DynamicMethodUtil.Create("__", tw.TypeAsBaseType.GetUnderlyingType(), true, null, [typeof(object), typeof(byte[])]); + var dmObjGetter = DynamicMethodUtil.Create("__", tw.TypeAsBaseType.GetUnderlyingRuntimeType(), true, null, [typeof(object), typeof(object[])]); + var dmPrimGetter = DynamicMethodUtil.Create("__", tw.TypeAsBaseType.GetUnderlyingRuntimeType(), true, null, [typeof(object), typeof(byte[])]); + var dmObjSetter = DynamicMethodUtil.Create("__", tw.TypeAsBaseType.GetUnderlyingRuntimeType(), true, null, [typeof(object), typeof(object[])]); + var dmPrimSetter = DynamicMethodUtil.Create("__", tw.TypeAsBaseType.GetUnderlyingRuntimeType(), true, null, [typeof(object), typeof(byte[])]); var ilgenObjGetter = JVM.Context.CodeEmitterFactory.Create(dmObjGetter); var ilgenPrimGetter = JVM.Context.CodeEmitterFactory.Create(dmPrimGetter); var ilgenObjSetter = JVM.Context.CodeEmitterFactory.Create(dmObjSetter); diff --git a/src/IKVM.Runtime/Java/Externs/sun/misc/Unsafe.cs b/src/IKVM.Runtime/Java/Externs/sun/misc/Unsafe.cs index f2faef90c..0d06aca91 100644 --- a/src/IKVM.Runtime/Java/Externs/sun/misc/Unsafe.cs +++ b/src/IKVM.Runtime/Java/Externs/sun/misc/Unsafe.cs @@ -1734,9 +1734,9 @@ public static object allocateInstance(object self, global::java.lang.Class cls) } #if NETFRAMEWORK - return FormatterServices.GetUninitializedObject(wrapper.TypeAsBaseType.GetUnderlyingType()); + return FormatterServices.GetUninitializedObject(wrapper.TypeAsBaseType.GetUnderlyingRuntimeType()); #else - return RuntimeHelpers.GetUninitializedObject(wrapper.TypeAsBaseType.GetUnderlyingType()); + return RuntimeHelpers.GetUninitializedObject(wrapper.TypeAsBaseType.GetUnderlyingRuntimeType()); #endif } @@ -1854,8 +1854,8 @@ static void PutFieldVolatile(object o, long offset, T value) /// static Delegate CreateGetArrayVolatileDelegate(RuntimeJavaType tw) { - var et = tw.IsPrimitive ? tw.TypeAsTBD.GetUnderlyingType() : typeof(object); - var dm = DynamicMethodUtil.Create($"____{tw.Name.Replace(".", "_")}", tw.TypeAsTBD.GetUnderlyingType(), true, et, new[] { typeof(object[]), typeof(long) }); + var et = tw.IsPrimitive ? tw.TypeAsTBD.GetUnderlyingRuntimeType() : typeof(object); + var dm = DynamicMethodUtil.Create($"____{tw.Name.Replace(".", "_")}", tw.TypeAsTBD.GetUnderlyingRuntimeType(), true, et, [typeof(object[]), typeof(long)]); var il = dm.GetILGenerator(); // load reference to element @@ -1865,17 +1865,17 @@ static Delegate CreateGetArrayVolatileDelegate(RuntimeJavaType tw) il.Emit(OpCodes.Ldc_I4, ArrayIndexScale(tw.MakeArrayType(1))); il.Emit(OpCodes.Div); il.Emit(OpCodes.Conv_Ovf_I); - il.Emit(OpCodes.Ldelema, tw.TypeAsLocalOrStackType.GetUnderlyingType()); + il.Emit(OpCodes.Ldelema, tw.TypeAsLocalOrStackType.GetUnderlyingRuntimeType()); if (tw.IsWidePrimitive == false) { il.Emit(OpCodes.Volatile); - EmitLdind(il, tw.TypeAsLocalOrStackType.GetUnderlyingType()); + EmitLdind(il, tw.TypeAsLocalOrStackType.GetUnderlyingRuntimeType()); } else { // Java volatile semantics require atomicity, CLR volatile semantics do not - var mi = typeof(Unsafe).GetMethod(nameof(InterlockedRead), BindingFlags.NonPublic | BindingFlags.Static, null, new[] { tw.TypeAsTBD.MakeByRefType().GetUnderlyingType() }, null); + var mi = typeof(Unsafe).GetMethod(nameof(InterlockedRead), BindingFlags.NonPublic | BindingFlags.Static, null, [tw.TypeAsTBD.MakeByRefType().GetUnderlyingRuntimeType()], null); il.Emit(OpCodes.Call, mi); } @@ -1912,8 +1912,8 @@ static object GetArrayObjectVolatile(object[] array, long offset) /// static Delegate CreatePutArrayVolatileDelegate(RuntimeJavaType tw) { - var et = tw.IsPrimitive ? tw.TypeAsTBD.GetUnderlyingType() : typeof(object); - var dm = DynamicMethodUtil.Create($"____{tw.Name.Replace(".", "_")}", tw.TypeAsTBD.GetUnderlyingType(), true, typeof(void), new[] { typeof(object[]), typeof(long), et }); + var et = tw.IsPrimitive ? tw.TypeAsTBD.GetUnderlyingRuntimeType() : typeof(object); + var dm = DynamicMethodUtil.Create($"____{tw.Name.Replace(".", "_")}", tw.TypeAsTBD.GetUnderlyingRuntimeType(), true, typeof(void), new[] { typeof(object[]), typeof(long), et }); var il = dm.GetILGenerator(); // load reference to element @@ -1923,19 +1923,19 @@ static Delegate CreatePutArrayVolatileDelegate(RuntimeJavaType tw) il.Emit(OpCodes.Ldc_I4, ArrayIndexScale(tw.MakeArrayType(1))); il.Emit(OpCodes.Div); il.Emit(OpCodes.Conv_Ovf_I); - il.Emit(OpCodes.Ldelema, tw.TypeAsLocalOrStackType.GetUnderlyingType()); + il.Emit(OpCodes.Ldelema, tw.TypeAsLocalOrStackType.GetUnderlyingRuntimeType()); il.Emit(OpCodes.Ldarg_2); if (tw.IsWidePrimitive == false) { il.Emit(OpCodes.Volatile); - EmitStind(il, tw.TypeAsLocalOrStackType.GetUnderlyingType()); + EmitStind(il, tw.TypeAsLocalOrStackType.GetUnderlyingRuntimeType()); } else { // Java volatile semantics require atomicity, CLR volatile semantics do not - var mi = typeof(Interlocked).GetMethod(nameof(Interlocked.Exchange), new[] { tw.TypeAsTBD.MakeByRefType().GetUnderlyingType() }); + var mi = typeof(Interlocked).GetMethod(nameof(Interlocked.Exchange), new[] { tw.TypeAsTBD.MakeByRefType().GetUnderlyingRuntimeType() }); il.Emit(OpCodes.Call, mi); } @@ -2475,11 +2475,11 @@ static Delegate CreateCompareExchangeArrayDelegate(RuntimeJavaType tw) var e = Expression.Parameter(typeof(object)); return Expression.Lambda>( Expression.Call( - compareAndSwapArrayMethodInfo.MakeGenericMethod(tw.TypeAsTBD.GetUnderlyingType()), - Expression.Convert(p, tw.MakeArrayType(1).TypeAsTBD.GetUnderlyingType()), + compareAndSwapArrayMethodInfo.MakeGenericMethod(tw.TypeAsTBD.GetUnderlyingRuntimeType()), + Expression.Convert(p, tw.MakeArrayType(1).TypeAsTBD.GetUnderlyingRuntimeType()), i, - Expression.Convert(v, tw.TypeAsTBD.GetUnderlyingType()), - Expression.Convert(e, tw.TypeAsTBD.GetUnderlyingType())), + Expression.Convert(v, tw.TypeAsTBD.GetUnderlyingRuntimeType()), + Expression.Convert(e, tw.TypeAsTBD.GetUnderlyingRuntimeType())), p, i, v, e) .Compile(); } diff --git a/src/IKVM.Runtime/Java/Externs/sun/reflect/ReflectionFactory.cs b/src/IKVM.Runtime/Java/Externs/sun/reflect/ReflectionFactory.cs index c898acb33..12684b2d1 100644 --- a/src/IKVM.Runtime/Java/Externs/sun/reflect/ReflectionFactory.cs +++ b/src/IKVM.Runtime/Java/Externs/sun/reflect/ReflectionFactory.cs @@ -286,9 +286,9 @@ internal SerializationConstructorAccessorImpl(global::java.lang.reflect.Construc public object newInstance(object[] args) { #if NETFRAMEWORK - var obj = FormatterServices.GetUninitializedObject(type.GetUnderlyingType()); + var obj = FormatterServices.GetUninitializedObject(type.GetUnderlyingRuntimeType()); #else - var obj = RuntimeHelpers.GetUninitializedObject(type.GetUnderlyingType()); + var obj = RuntimeHelpers.GetUninitializedObject(type.GetUnderlyingRuntimeType()); #endif if (mw != null) mw.Invoke(obj, ConvertArgs(mw.DeclaringType.ClassLoader, mw.GetParameters(), args)); @@ -587,7 +587,7 @@ internal unsafe FastMethodAccessorImpl(RuntimeJavaMethod mw) // generate new dynamic method var np = !mw.IsPublic || !mw.DeclaringType.IsPublic; - var dm = DynamicMethodUtil.Create($"____{mw.DeclaringType.Name.Replace(".", "_")}__{mw.Name}", mw.DeclaringType.TypeAsBaseType.GetUnderlyingType(), np, typeof(object), new[] { typeof(object), typeof(object[]), typeof(global::ikvm.@internal.CallerID) }); + var dm = DynamicMethodUtil.Create($"____{mw.DeclaringType.Name.Replace(".", "_")}__{mw.Name}", mw.DeclaringType.TypeAsBaseType.GetUnderlyingRuntimeType(), np, typeof(object), new[] { typeof(object), typeof(object[]), typeof(global::ikvm.@internal.CallerID) }); var il = JVM.Context.CodeEmitterFactory.Create(dm); // labels @@ -831,7 +831,7 @@ internal FastConstructorAccessorImpl(global::java.lang.reflect.Constructor const // resolve the runtime method info mw.ResolveMethod(); var np = !mw.IsPublic || !mw.DeclaringType.IsPublic; - var dm = DynamicMethodUtil.Create($"____{mw.DeclaringType.Name.Replace(".", "_")}__{mw.Name}", mw.DeclaringType.TypeAsTBD.GetUnderlyingType(), np, typeof(object), new[] { typeof(object[]) }); + var dm = DynamicMethodUtil.Create($"____{mw.DeclaringType.Name.Replace(".", "_")}__{mw.Name}", mw.DeclaringType.TypeAsTBD.GetUnderlyingRuntimeType(), np, typeof(object), new[] { typeof(object[]) }); var il = JVM.Context.CodeEmitterFactory.Create(dm); // labels @@ -1007,7 +1007,7 @@ internal FastSerializationConstructorAccessorImpl(global::java.lang.reflect.Cons throw x.ToJava(); } - var dm = DynamicMethodUtil.Create("__", constructor.DeclaringType.TypeAsBaseType.GetUnderlyingType(), true, typeof(object), null); + var dm = DynamicMethodUtil.Create("__", constructor.DeclaringType.TypeAsBaseType.GetUnderlyingRuntimeType(), true, typeof(object), null); var il = JVM.Context.CodeEmitterFactory.Create(dm); il.Emit(OpCodes.Ldtoken, type); il.Emit(OpCodes.Call, GetTypeFromHandleMethod); @@ -1052,7 +1052,7 @@ public object newInstance(object[] objarr) try { - return Activator.CreateInstance(type.GetUnderlyingType()); + return Activator.CreateInstance(type.GetUnderlyingRuntimeType()); } catch (TargetInvocationException x) { @@ -1319,7 +1319,7 @@ private T lazyGet(object obj) { throw GetIllegalArgumentException(obj); } - else if (fw.DeclaringType.IsRemapped && !fw.DeclaringType.TypeAsBaseType.GetUnderlyingType().IsInstanceOfType(obj)) + else if (fw.DeclaringType.IsRemapped && !fw.DeclaringType.TypeAsBaseType.GetUnderlyingRuntimeType().IsInstanceOfType(obj)) { throw GetUnsupportedRemappedFieldException(obj); } @@ -1364,7 +1364,7 @@ private void lazySet(object obj, T value) { throw SetIllegalArgumentException(obj); } - else if (fw.DeclaringType.IsRemapped && !fw.DeclaringType.TypeAsBaseType.GetUnderlyingType().IsInstanceOfType(obj)) + else if (fw.DeclaringType.IsRemapped && !fw.DeclaringType.TypeAsBaseType.GetUnderlyingRuntimeType().IsInstanceOfType(obj)) { throw GetUnsupportedRemappedFieldException(obj); } @@ -2070,7 +2070,7 @@ private Delegate GenerateFastGetter(Type delegateType, Type fieldType, RuntimeJa fw.ResolveField(); - var dm = DynamicMethodUtil.Create("__", fw.DeclaringType.TypeAsBaseType.GetUnderlyingType(), !fw.IsPublic || !fw.DeclaringType.IsPublic, fieldType, [typeof(IReflectionException), typeof(object), typeof(object)]); + var dm = DynamicMethodUtil.Create("__", fw.DeclaringType.TypeAsBaseType.GetUnderlyingRuntimeType(), !fw.IsPublic || !fw.DeclaringType.IsPublic, fieldType, [typeof(IReflectionException), typeof(object), typeof(object)]); var il = JVM.Context.CodeEmitterFactory.Create(dm); if (fw.IsStatic) { @@ -2118,7 +2118,7 @@ private Delegate GenerateFastSetter(Type delegateType, Type fieldType, RuntimeJa fw.ResolveField(); - var dm = DynamicMethodUtil.Create("__", fw.DeclaringType.TypeAsBaseType.GetUnderlyingType(), !fw.IsPublic || !fw.DeclaringType.IsPublic, null, [typeof(IReflectionException), typeof(object), fieldType, typeof(object)]); + var dm = DynamicMethodUtil.Create("__", fw.DeclaringType.TypeAsBaseType.GetUnderlyingRuntimeType(), !fw.IsPublic || !fw.DeclaringType.IsPublic, null, [typeof(IReflectionException), typeof(object), fieldType, typeof(object)]); var il = JVM.Context.CodeEmitterFactory.Create(dm); if (fw.IsStatic) { diff --git a/src/IKVM.Runtime/MethodHandleUtil.jniexport.cs b/src/IKVM.Runtime/MethodHandleUtil.jniexport.cs index 7c050b865..f29b4493c 100644 --- a/src/IKVM.Runtime/MethodHandleUtil.jniexport.cs +++ b/src/IKVM.Runtime/MethodHandleUtil.jniexport.cs @@ -194,7 +194,7 @@ public Container(T1 target, T2 value) if (!ReflectUtil.CanOwnDynamicMethod(owner)) owner = typeof(DynamicMethodBuilder); - dm = new DynamicMethod(name, mi.ReturnType.GetUnderlyingType(), paramTypes.GetUnderlyingTypes(), owner, true); + dm = new DynamicMethod(name, mi.ReturnType.GetUnderlyingRuntimeType(), paramTypes.GetUnderlyingRuntimeTypes(), owner, true); ilgen = context.CodeEmitterFactory.Create(dm); if (type.parameterCount() > MaxArity) @@ -516,8 +516,8 @@ internal Delegate CreateDelegate() //ilgen.DumpMethod(); ilgen.DoEmit(); return ValidateDelegate(firstArg == 0 - ? dm.CreateDelegate(delegateType.GetUnderlyingType()) - : dm.CreateDelegate(delegateType.GetUnderlyingType(), container == null ? firstBoundValue : Activator.CreateInstance(container.GetUnderlyingType(), firstBoundValue, secondBoundValue))); + ? dm.CreateDelegate(delegateType.GetUnderlyingRuntimeType()) + : dm.CreateDelegate(delegateType.GetUnderlyingRuntimeType(), container == null ? firstBoundValue : Activator.CreateInstance(container.GetUnderlyingRuntimeType(), firstBoundValue, secondBoundValue))); } internal void BoxArgs(int start) diff --git a/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs b/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs index 9b2f65e22..591f9f636 100644 --- a/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs +++ b/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs @@ -1174,7 +1174,7 @@ Type GetCustomClassLoaderType() var attribs = assembly.GetCustomAttribute(Context.Resolver.ResolveRuntimeType(typeof(CustomAssemblyClassLoaderAttribute).FullName), false); if (attribs.HasValue) - return ((ITypeSymbol)attribs.Value.ConstructorArguments[0].Value).GetUnderlyingType(); + return ((ITypeSymbol)attribs.Value.ConstructorArguments[0].Value).GetUnderlyingRuntimeType(); return null; } diff --git a/src/IKVM.Runtime/RuntimeJavaField.cs b/src/IKVM.Runtime/RuntimeJavaField.cs index 9b3398eef..293132710 100644 --- a/src/IKVM.Runtime/RuntimeJavaField.cs +++ b/src/IKVM.Runtime/RuntimeJavaField.cs @@ -500,8 +500,8 @@ Delegate CreateUnsafeGetDelegate() FieldTypeWrapper.Finish(); ResolveField(); - var ft = FieldTypeWrapper.IsPrimitive ? FieldTypeWrapper.TypeAsSignatureType.GetUnderlyingType() : typeof(object); - var dm = DynamicMethodUtil.Create($"____{DeclaringType.Name.Replace(".", "_")}__{Name}", DeclaringType.TypeAsTBD.GetUnderlyingType(), true, ft, [typeof(object)]); + var ft = FieldTypeWrapper.IsPrimitive ? FieldTypeWrapper.TypeAsSignatureType.GetUnderlyingRuntimeType() : typeof(object); + var dm = DynamicMethodUtil.Create($"____{DeclaringType.Name.Replace(".", "_")}__{Name}", DeclaringType.TypeAsTBD.GetUnderlyingRuntimeType(), true, ft, [typeof(object)]); var il = JVM.Context.CodeEmitterFactory.Create(dm); if (IsStatic == false) @@ -547,8 +547,8 @@ Delegate CreateUnsafeSetDelegate() FieldTypeWrapper.Finish(); ResolveField(); - var ft = FieldTypeWrapper.IsPrimitive ? FieldTypeWrapper.TypeAsSignatureType.GetUnderlyingType() : typeof(object); - var dm = DynamicMethodUtil.Create($"____{DeclaringType.Name.Replace(".", "_")}__{Name}", DeclaringType.TypeAsTBD.GetUnderlyingType(), true, typeof(void), [typeof(object), ft]); + var ft = FieldTypeWrapper.IsPrimitive ? FieldTypeWrapper.TypeAsSignatureType.GetUnderlyingRuntimeType() : typeof(object); + var dm = DynamicMethodUtil.Create($"____{DeclaringType.Name.Replace(".", "_")}__{Name}", DeclaringType.TypeAsTBD.GetUnderlyingRuntimeType(), true, typeof(void), [typeof(object), ft]); var il = JVM.Context.CodeEmitterFactory.Create(dm); if (IsStatic == false) @@ -592,7 +592,7 @@ Delegate GetUnsafeVolatileGetDelegate() Delegate CreateUnsafeVolatileGetDelegate() { ResolveField(); - var ft = FieldTypeWrapper.IsPrimitive ? FieldTypeWrapper.TypeAsSignatureType.GetUnderlyingType() : typeof(object); + var ft = FieldTypeWrapper.IsPrimitive ? FieldTypeWrapper.TypeAsSignatureType.GetUnderlyingRuntimeType() : typeof(object); var dm = new DynamicMethod($"____{DeclaringType.Name.Replace(".", "_")}__{Name}", ft, [typeof(object)], DeclaringType.TypeAsTBD.Module.GetUnderlyingModule(), true); var il = JVM.Context.CodeEmitterFactory.Create(dm); @@ -637,8 +637,8 @@ Delegate GetUnsafeVolatileSetDelegate() Delegate CreateUnsafeVolatileSetDelegate() { ResolveField(); - var ft = FieldTypeWrapper.IsPrimitive ? FieldTypeWrapper.TypeAsSignatureType.GetUnderlyingType() : typeof(object); - var dm = DynamicMethodUtil.Create($"____{DeclaringType.Name.Replace(".", "_")}__{Name}", DeclaringType.TypeAsTBD.GetUnderlyingType(), true, typeof(void), [typeof(object), ft]); + var ft = FieldTypeWrapper.IsPrimitive ? FieldTypeWrapper.TypeAsSignatureType.GetUnderlyingRuntimeType() : typeof(object); + var dm = DynamicMethodUtil.Create($"____{DeclaringType.Name.Replace(".", "_")}__{Name}", DeclaringType.TypeAsTBD.GetUnderlyingRuntimeType(), true, typeof(void), [typeof(object), ft]); var il = JVM.Context.CodeEmitterFactory.Create(dm); if (IsStatic == false) @@ -685,8 +685,8 @@ Delegate GetUnsafeCompareAndSwapDelegate() Delegate CreateUnsafeCompareAndSwapDelegate() { ResolveField(); - var ft = FieldTypeWrapper.IsPrimitive ? FieldTypeWrapper.TypeAsSignatureType.GetUnderlyingType() : typeof(object); - var dm = DynamicMethodUtil.Create($"____{DeclaringType.Name.Replace(".", "_")}__{Name}", DeclaringType.TypeAsTBD.GetUnderlyingType(), true, typeof(bool), [typeof(object), ft, ft]); + var ft = FieldTypeWrapper.IsPrimitive ? FieldTypeWrapper.TypeAsSignatureType.GetUnderlyingRuntimeType() : typeof(object); + var dm = DynamicMethodUtil.Create($"____{DeclaringType.Name.Replace(".", "_")}__{Name}", DeclaringType.TypeAsTBD.GetUnderlyingRuntimeType(), true, typeof(bool), [typeof(object), ft, ft]); var il = JVM.Context.CodeEmitterFactory.Create(dm); if (IsStatic == false) diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.cs index d17358d07..c76a9a594 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.cs @@ -376,7 +376,7 @@ internal override object GetAnnotationDefault(RuntimeJavaMethod mw) } else if (mw.ReturnType.IsArray) { - return Array.CreateInstance(mw.ReturnType.TypeAsArrayType.GetUnderlyingType(), 0); + return Array.CreateInstance(mw.ReturnType.TypeAsArrayType.GetUnderlyingRuntimeType(), 0); } } diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.EnumEnumJavaType.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.EnumEnumJavaType.cs index 35eba0393..61be98369 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.EnumEnumJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.EnumEnumJavaType.cs @@ -98,7 +98,7 @@ internal EnumJavaField(RuntimeJavaType tw, string name, int ordinal) : internal override object GetValue(object obj) { if (val == null) - System.Threading.Interlocked.CompareExchange(ref val, Activator.CreateInstance(this.DeclaringType.TypeAsTBD.GetUnderlyingType(), BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, new object[] { this.Name, ordinal }, null), null); + System.Threading.Interlocked.CompareExchange(ref val, Activator.CreateInstance(this.DeclaringType.TypeAsTBD.GetUnderlyingRuntimeType(), BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, new object[] { this.Name, ordinal }, null), null); return val; } @@ -147,7 +147,7 @@ internal EnumValuesJavaMethod(RuntimeJavaType declaringType) : internal override object Invoke(object obj, object[] args) { var values = DeclaringType.GetFields(); - var array = (object[])Array.CreateInstance(DeclaringType.TypeAsArrayType.GetUnderlyingType(), values.Length); + var array = (object[])Array.CreateInstance(DeclaringType.TypeAsArrayType.GetUnderlyingRuntimeType(), values.Length); for (int i = 0; i < values.Length; i++) array[i] = values[i].GetValue(null); diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.EnumWrapJavaMethod.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.EnumWrapJavaMethod.cs index d706a9031..a02a29ed3 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.EnumWrapJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.EnumWrapJavaMethod.cs @@ -67,7 +67,7 @@ internal override void EmitCall(CodeEmitter ilgen) internal override object Invoke(object obj, object[] args) { - return Enum.ToObject(DeclaringType.TypeAsTBD.GetUnderlyingType(), args[0]); + return Enum.ToObject(DeclaringType.TypeAsTBD.GetUnderlyingRuntimeType(), args[0]); } #endif diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.ValueTypeDefaultCtorJavaMethod.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.ValueTypeDefaultCtorJavaMethod.cs index 6de44f611..7ca600db3 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.ValueTypeDefaultCtorJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.ValueTypeDefaultCtorJavaMethod.cs @@ -65,7 +65,7 @@ internal override void EmitCall(CodeEmitter ilgen) internal override object CreateInstance(object[] args) { - return Activator.CreateInstance(DeclaringType.TypeAsTBD.GetUnderlyingType()); + return Activator.CreateInstance(DeclaringType.TypeAsTBD.GetUnderlyingRuntimeType()); } #endif diff --git a/src/IKVM.Runtime/SymbolExtensions.cs b/src/IKVM.Runtime/SymbolExtensions.cs index 08cf48b7d..40244b115 100644 --- a/src/IKVM.Runtime/SymbolExtensions.cs +++ b/src/IKVM.Runtime/SymbolExtensions.cs @@ -59,6 +59,18 @@ public static Type GetUnderlyingType(this ITypeSymbol symbol) #endif } + public static Type[] GetUnderlyingTypes(this ITypeSymbol[] symbols) + { + if (symbols == null) + return null; + + var a = new Type[symbols.Length]; + for (int i = 0; i < symbols.Length; i++) + a[i] = GetUnderlyingType(symbols[i]); + + return a; + } + public static Type GetUnderlyingRuntimeType(this ITypeSymbol symbol) { if (symbol == null) @@ -71,14 +83,14 @@ public static Type GetUnderlyingRuntimeType(this ITypeSymbol symbol) #endif } - public static Type[] GetUnderlyingTypes(this ITypeSymbol[] symbols) + public static Type[] GetUnderlyingRuntimeTypes(this ITypeSymbol[] symbols) { if (symbols == null) return null; var a = new Type[symbols.Length]; for (int i = 0; i < symbols.Length; i++) - a[i] = GetUnderlyingType(symbols[i]); + a[i] = GetUnderlyingRuntimeType(symbols[i]); return a; } diff --git a/src/IKVM.Runtime/Util/Java/Lang/Invoke/NativeInvokerBytecodeGenerator.cs b/src/IKVM.Runtime/Util/Java/Lang/Invoke/NativeInvokerBytecodeGenerator.cs index bfee5d139..57ecfebea 100644 --- a/src/IKVM.Runtime/Util/Java/Lang/Invoke/NativeInvokerBytecodeGenerator.cs +++ b/src/IKVM.Runtime/Util/Java/Lang/Invoke/NativeInvokerBytecodeGenerator.cs @@ -115,7 +115,7 @@ internal BailoutException(Bailout reason, object data) var paramTypes = MethodHandleUtil.GetParameterTypes(context.Types.Object.MakeArrayType(), mi); // HACK the code we generate is not verifiable (known issue: locals aren't typed correctly), so we stick the DynamicMethod into mscorlib (a security critical assembly) - this.dm = new DynamicMethod(lambdaForm.debugName, mi.ReturnType.GetUnderlyingType(), paramTypes.GetUnderlyingTypes(), typeof(object).Module, true); + this.dm = new DynamicMethod(lambdaForm.debugName, mi.ReturnType.GetUnderlyingRuntimeType(), paramTypes.GetUnderlyingRuntimeTypes(), typeof(object).Module, true); this.ilgen = context.CodeEmitterFactory.Create(this.dm); if (invokerType.parameterCount() > MethodHandleUtil.MaxArity) { @@ -439,7 +439,7 @@ private Delegate generateCustomizedCodeBytes() emitReturn(onStack); ilgen.DoEmit(); - return dm.CreateDelegate(delegateType.GetUnderlyingType(), constants.ToArray()); + return dm.CreateDelegate(delegateType.GetUnderlyingRuntimeType(), constants.ToArray()); } void emitArrayLoad(Name name) From 5eda2a69091df9d0e396e90d68eab70dbf33e051 Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Sun, 20 Oct 2024 13:32:23 -0500 Subject: [PATCH 47/51] Implement GetParameters and ReturnType. --- .../Emit/IkvmReflectionFieldSymbolBuilder.cs | 11 ++++++---- .../IkvmReflectionFieldTable.cs | 2 +- .../Emit/ReflectionFieldSymbolBuilder.cs | 21 ++++++++++++++++--- .../Emit/ReflectionMethodSymbolBuilder.cs | 17 +++++++++++---- .../Emit/ReflectionTypeSymbolBuilder.cs | 8 +++---- .../Reflection/IReflectionModuleSymbol.cs | 4 +++- .../Symbols/Reflection/IReflectionSymbol.cs | 4 +++- .../Reflection/IReflectionTypeSymbol.cs | 6 ++++-- .../Reflection/ReflectionFieldSymbol.cs | 4 ++-- .../Reflection/ReflectionFieldTable.cs | 15 +++++++------ .../ReflectionGenericTypeParameterSymbol.cs | 2 +- .../Reflection/ReflectionMemberSymbol.cs | 18 ++++++++++++++++ .../Reflection/ReflectionMethodSymbol.cs | 4 +++- .../Reflection/ReflectionModuleSymbol.cs | 8 +++---- .../Symbols/Reflection/ReflectionSymbol.cs | 4 ++-- .../Reflection/ReflectionSymbolContext.cs | 4 ++-- .../Reflection/ReflectionTypeSymbolBase.cs | 10 ++++----- src/IKVM.Runtime/StubGen/StubGenerator.cs | 2 +- 18 files changed, 100 insertions(+), 44 deletions(-) diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionFieldSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionFieldSymbolBuilder.cs index cb4971589..d1014b34b 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionFieldSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionFieldSymbolBuilder.cs @@ -1,6 +1,5 @@ using System; -using IKVM.CoreLib.Symbols.Emit; using IKVM.Reflection; using IKVM.Reflection.Emit; @@ -12,6 +11,8 @@ class IkvmReflectionFieldSymbolBuilder : IkvmReflectionMemberSymbolBuilder, IIkv FieldBuilder? _builder; FieldInfo _field; + readonly ITypeSymbol[] _optionalCustomModifiers; + readonly ITypeSymbol[] _requiredCustomModifiers; /// /// Initializes a new instance. @@ -21,11 +22,13 @@ class IkvmReflectionFieldSymbolBuilder : IkvmReflectionMemberSymbolBuilder, IIkv /// /// /// - public IkvmReflectionFieldSymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbolBuilder resolvingModule, IIkvmReflectionTypeSymbolBuilder? resolvingType, FieldBuilder builder) : + public IkvmReflectionFieldSymbolBuilder(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbolBuilder resolvingModule, IIkvmReflectionTypeSymbolBuilder? resolvingType, FieldBuilder builder, ITypeSymbol[] optionalCustomModifiers, ITypeSymbol[] requiredCustomModifiers) : base(context, resolvingModule, resolvingType) { _builder = builder ?? throw new ArgumentNullException(nameof(builder)); _field = _builder; + _optionalCustomModifiers = optionalCustomModifiers; + _requiredCustomModifiers = requiredCustomModifiers; } /// @@ -103,13 +106,13 @@ public void SetOffset(int iOffset) /// public ITypeSymbol[] GetOptionalCustomModifiers() { - return ResolveTypeSymbols(UnderlyingField.GetOptionalCustomModifiers()); + return _optionalCustomModifiers; } /// public ITypeSymbol[] GetRequiredCustomModifiers() { - return ResolveTypeSymbols(UnderlyingField.GetRequiredCustomModifiers()); + return _requiredCustomModifiers; } /// diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionFieldTable.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionFieldTable.cs index d493f35fa..624572ed0 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionFieldTable.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionFieldTable.cs @@ -90,7 +90,7 @@ public IIkvmReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) static IIkvmReflectionFieldSymbol CreateFieldSymbol(IkvmReflectionSymbolContext context, IIkvmReflectionModuleSymbol module, IIkvmReflectionTypeSymbol? type, FieldInfo field) { if (field is FieldBuilder builder) - return new IkvmReflectionFieldSymbolBuilder(context, (IIkvmReflectionModuleSymbolBuilder)module, (IIkvmReflectionTypeSymbolBuilder?)type, builder); + return new IkvmReflectionFieldSymbolBuilder(context, (IIkvmReflectionModuleSymbolBuilder)module, (IIkvmReflectionTypeSymbolBuilder?)type, builder, [], []); else return new IkvmReflectionFieldSymbol(context, module, type, field); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionFieldSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionFieldSymbolBuilder.cs index 6e99440cf..08311c1c6 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionFieldSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionFieldSymbolBuilder.cs @@ -2,8 +2,6 @@ using System.Reflection; using System.Reflection.Emit; -using IKVM.CoreLib.Symbols.Emit; - namespace IKVM.CoreLib.Symbols.Reflection.Emit { @@ -13,6 +11,9 @@ class ReflectionFieldSymbolBuilder : ReflectionFieldSymbol, IReflectionFieldSymb readonly FieldBuilder _builder; FieldInfo? _field; + readonly ITypeSymbol[]? _requiredCustomModifiers; + readonly ITypeSymbol[]? _optionalCustomModifiers; + /// /// Initializes a new instance. /// @@ -21,10 +22,12 @@ class ReflectionFieldSymbolBuilder : ReflectionFieldSymbol, IReflectionFieldSymb /// /// /// - public ReflectionFieldSymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbolBuilder resolvingModule, IReflectionTypeSymbolBuilder? resolvingType, FieldBuilder builder) : + public ReflectionFieldSymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbolBuilder resolvingModule, IReflectionTypeSymbolBuilder? resolvingType, FieldBuilder builder, ITypeSymbol[]? requiredCustomModifiers, ITypeSymbol[]? optionalCustomModifiers) : base(context, resolvingModule, resolvingType, builder) { _builder = builder ?? throw new ArgumentNullException(nameof(builder)); + _requiredCustomModifiers = requiredCustomModifiers ?? throw new ArgumentNullException(nameof(requiredCustomModifiers)); + _optionalCustomModifiers = optionalCustomModifiers ?? throw new ArgumentNullException(nameof(optionalCustomModifiers)); } /// @@ -41,6 +44,18 @@ public ReflectionFieldSymbolBuilder(ReflectionSymbolContext context, IReflection /// public override bool IsComplete => _field != null; + /// + public override ITypeSymbol[] GetRequiredCustomModifiers() + { + return _requiredCustomModifiers ?? []; + } + + /// + public override ITypeSymbol[] GetOptionalCustomModifiers() + { + return _optionalCustomModifiers ?? []; + } + #endregion #region IFieldSymbolBuilder diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs index 58fdd779b..9a30c7a88 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs @@ -42,15 +42,24 @@ public ReflectionMethodSymbolBuilder(ReflectionSymbolContext context, IReflectio #region IMethodBaseSymbolBuilder /// - public void SetImplementationFlags(System.Reflection.MethodImplAttributes attributes) + public void SetImplementationFlags(MethodImplAttributes attributes) { - UnderlyingMethodBuilder.SetImplementationFlags((MethodImplAttributes)attributes); + UnderlyingMethodBuilder.SetImplementationFlags(attributes); } /// - public IParameterSymbolBuilder DefineParameter(int position, System.Reflection.ParameterAttributes attributes, string? strParamName) + public IParameterSymbolBuilder DefineParameter(int position, ParameterAttributes attributes, string? strParamName) { - return ResolveParameterSymbol(this, UnderlyingMethodBuilder.DefineParameter(position, (ParameterAttributes)attributes, strParamName)); + return ResolveParameterSymbol(this, UnderlyingMethodBuilder.DefineParameter(position, attributes, strParamName)); + } + + /// + public override IParameterSymbol[] GetParameters() + { + if (IsComplete) + return ResolveParameterSymbols(UnderlyingRuntimeMethod.GetParameters()); + else + return base.GetParameters(); } /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs index 9130e6a35..ac8e95076 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs @@ -103,17 +103,17 @@ public IEventSymbolBuilder DefineEvent(string name, System.Reflection.EventAttri /// public IFieldSymbolBuilder DefineField(string fieldName, ITypeSymbol type, System.Reflection.FieldAttributes attributes) { - return ResolveFieldSymbol(UnderlyingTypeBuilder.DefineField(fieldName, type.Unpack(), (FieldAttributes)attributes)); + return ResolveFieldSymbol(UnderlyingTypeBuilder.DefineField(fieldName, type.Unpack(), attributes), [], []); } /// - public IFieldSymbolBuilder DefineField(string fieldName, ITypeSymbol type, ITypeSymbol[]? requiredCustomModifiers, ITypeSymbol[]? optionalCustomModifiers, System.Reflection.FieldAttributes attributes) + public IFieldSymbolBuilder DefineField(string fieldName, ITypeSymbol type, ITypeSymbol[]? requiredCustomModifiers, ITypeSymbol[]? optionalCustomModifiers, FieldAttributes attributes) { - return ResolveFieldSymbol(UnderlyingTypeBuilder.DefineField(fieldName, type.Unpack(), requiredCustomModifiers?.Unpack(), optionalCustomModifiers?.Unpack(), (FieldAttributes)attributes)); + return ResolveFieldSymbol(UnderlyingTypeBuilder.DefineField(fieldName, type.Unpack(), requiredCustomModifiers?.Unpack(), optionalCustomModifiers?.Unpack(), attributes), requiredCustomModifiers, optionalCustomModifiers); } /// - public IMethodSymbolBuilder DefineMethod(string name, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers) + public IMethodSymbolBuilder DefineMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers) { var m = ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, (MethodAttributes)attributes, (CallingConventions)callingConvention, returnType?.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack())); _incompleteMethods ??= []; diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionModuleSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionModuleSymbol.cs index 9b559b577..7d679be5c 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionModuleSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionModuleSymbol.cs @@ -85,8 +85,10 @@ interface IReflectionModuleSymbol : IReflectionSymbol, IModuleSymbol /// Gets or creates a for the specified . /// /// + /// + /// /// - IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field); + IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field, ITypeSymbol[]? optionalCustomModifiers, ITypeSymbol[]? requiredCustomModifiers); /// /// Gets or creates a for the specified . diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionSymbol.cs index 3928a4815..490fe4da8 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionSymbol.cs @@ -196,9 +196,11 @@ interface IReflectionSymbol : ISymbol /// Resolves the symbol for the specified field. /// /// + /// + /// /// [return: NotNullIfNotNull(nameof(field))] - IReflectionFieldSymbolBuilder ResolveFieldSymbol(FieldBuilder field); + IReflectionFieldSymbolBuilder ResolveFieldSymbol(FieldBuilder field, ITypeSymbol[] requiredCustomModifiers, ITypeSymbol[] optionalCustomModifiers); /// /// Resolves the symbol for the specified property. diff --git a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionTypeSymbol.cs index 47da7f1b4..f8daebceb 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/IReflectionTypeSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/IReflectionTypeSymbol.cs @@ -72,9 +72,11 @@ interface IReflectionTypeSymbol : IReflectionMemberSymbol, ITypeSymbol /// /// Gets or creates a for the given . /// - /// + /// + /// + /// /// - IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field); + IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field, ITypeSymbol[]? requiredCustomModifiers, ITypeSymbol[]? optionalCustomModifiers); /// /// Gets or creates a for the given . diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionFieldSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionFieldSymbol.cs index f6095d471..a9d760e50 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionFieldSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionFieldSymbol.cs @@ -79,13 +79,13 @@ public ReflectionFieldSymbol(ReflectionSymbolContext context, IReflectionModuleS public bool IsStatic => UnderlyingField.IsStatic; /// - public ITypeSymbol[] GetOptionalCustomModifiers() + public virtual ITypeSymbol[] GetOptionalCustomModifiers() { return ResolveTypeSymbols(UnderlyingField.GetOptionalCustomModifiers()); } /// - public ITypeSymbol[] GetRequiredCustomModifiers() + public virtual ITypeSymbol[] GetRequiredCustomModifiers() { return ResolveTypeSymbols(UnderlyingField.GetRequiredCustomModifiers()); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionFieldTable.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionFieldTable.cs index c2e1b3afd..984f167a8 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionFieldTable.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionFieldTable.cs @@ -1,7 +1,6 @@ using System; using System.Reflection; using System.Reflection.Emit; -using System.Reflection.Metadata.Ecma335; using System.Threading; using IKVM.CoreLib.Collections; @@ -40,8 +39,10 @@ public ReflectionFieldTable(ReflectionSymbolContext context, IReflectionModuleSy /// Gets or creates the cached for the type by field. /// /// + /// + /// /// - public IReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) + public IReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field, ITypeSymbol[]? requiredCustomModifiers, ITypeSymbol[]? optionalCustomModifiers) { if (field is null) throw new ArgumentNullException(nameof(field)); @@ -58,10 +59,10 @@ public IReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) if (_table[row] == null) using (_lock.CreateWriteLock()) if (field is FieldBuilder builder) - return _table[row] ??= new ReflectionFieldSymbolBuilder(_context, (IReflectionModuleSymbolBuilder)_module, (IReflectionTypeSymbolBuilder?)_type, builder); + return _table[row] ??= new ReflectionFieldSymbolBuilder(_context, (IReflectionModuleSymbolBuilder)_module, (IReflectionTypeSymbolBuilder?)_type, builder, requiredCustomModifiers, optionalCustomModifiers); else return _table[row] ??= new ReflectionFieldSymbol(_context, _module, _type, field); - + return _table[row] ?? throw new InvalidOperationException(); } } @@ -70,10 +71,12 @@ public IReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) /// Gets or creates the cached for the type by field. /// /// + /// + /// /// - public IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field) + public IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field, ITypeSymbol[]? requiredCustomModifiers, ITypeSymbol[]? optionalCustomModifiers) { - return (IReflectionFieldSymbolBuilder)GetOrCreateFieldSymbol((FieldInfo)field); + return (IReflectionFieldSymbolBuilder)GetOrCreateFieldSymbol((FieldInfo)field, requiredCustomModifiers, optionalCustomModifiers); } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericTypeParameterSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericTypeParameterSymbol.cs index 5aa9ccfad..b33ae45c3 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericTypeParameterSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericTypeParameterSymbol.cs @@ -106,7 +106,7 @@ public IReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) throw new NotSupportedException(); } - public IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field) + public IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field, ITypeSymbol[]? requiredCustomModifiers, ITypeSymbol[]? optionalCustomModifiers) { throw new NotImplementedException(); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs index 783d68a8d..c57bc860b 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs @@ -2,8 +2,10 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reflection; +using System.Reflection.Emit; using IKVM.CoreLib.Reflection; +using IKVM.CoreLib.Symbols.Reflection.Emit; namespace IKVM.CoreLib.Symbols.Reflection { @@ -113,6 +115,22 @@ public ReflectionMemberSymbol(ReflectionSymbolContext context, IReflectionModule return base.ResolveFieldSymbol(field); } + /// + [return: NotNullIfNotNull(nameof(field))] + public override IReflectionFieldSymbolBuilder? ResolveFieldSymbol(FieldBuilder? field, ITypeSymbol[]? requiredCustomModifiers, ITypeSymbol[]? optionalCustomModifiers) + { + if (field is null) + return null; + + if (field == UnderlyingMember) + return (IReflectionFieldSymbolBuilder)this; + + if (field.Module == _module.UnderlyingModule) + return _module.GetOrCreateFieldSymbol(field, requiredCustomModifiers, optionalCustomModifiers); + + return base.ResolveFieldSymbol(field, requiredCustomModifiers, optionalCustomModifiers); + } + /// [return: NotNullIfNotNull(nameof(property))] public override IReflectionPropertySymbol? ResolvePropertySymbol(PropertyInfo? property) diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs index 33ff9fa02..5822b5e61 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs @@ -74,7 +74,7 @@ public IReflectionMethodSymbol GetOrCreateGenericMethodSymbol(MethodInfo method) #region IMethodSymbol /// - public IParameterSymbol ReturnParameter => ResolveParameterSymbol(UnderlyingMethod.ReturnParameter); + public IParameterSymbol ReturnParameter => GetReturnParameter(); /// /// Gets the return type of the method. @@ -84,6 +84,8 @@ IParameterSymbol GetReturnParameter() { if (ReflectionExtensions.MethodOnTypeBuilderInstantiationType.IsInstanceOfType(_method)) return GetReturnParameterForMethodOnTypeBuilderInstantiation(); + else if (IsComplete) + return ResolveParameterSymbol(UnderlyingRuntimeMethod.ReturnParameter); else return ResolveParameterSymbol(UnderlyingMethod.ReturnParameter); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs index 5e6ba8deb..fcac53de7 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs @@ -320,16 +320,16 @@ public IReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) if (field.DeclaringType is { } dt) return ResolveTypeSymbol(dt).GetOrCreateFieldSymbol(field); else - return _fieldTable.GetOrCreateFieldSymbol(field); + return _fieldTable.GetOrCreateFieldSymbol(field, ResolveTypeSymbols(field.GetRequiredCustomModifiers()), ResolveTypeSymbols(field.GetOptionalCustomModifiers())); } /// - public IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field) + public IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field, ITypeSymbol[]? requiredCustomModifiers, ITypeSymbol[]? optionalCustomModifiers) { if (field.DeclaringType is { } dt) - return ResolveTypeSymbol((TypeBuilder)dt).GetOrCreateFieldSymbol(field); + return ResolveTypeSymbol((TypeBuilder)dt).GetOrCreateFieldSymbol(field, requiredCustomModifiers, optionalCustomModifiers); else - return _fieldTable.GetOrCreateFieldSymbol(field); + return _fieldTable.GetOrCreateFieldSymbol(field, requiredCustomModifiers, optionalCustomModifiers); } /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbol.cs index b6c191b51..0cbdc1189 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbol.cs @@ -286,12 +286,12 @@ public virtual IReflectionMethodSymbolBuilder ResolveMethodSymbol(MethodBuilder /// [return: NotNullIfNotNull(nameof(field))] - public virtual IReflectionFieldSymbolBuilder ResolveFieldSymbol(FieldBuilder field) + public virtual IReflectionFieldSymbolBuilder ResolveFieldSymbol(FieldBuilder field, ITypeSymbol[]? requiredCustomModifiers, ITypeSymbol[]? optionalCustomModifiers) { if (field is null) throw new ArgumentNullException(nameof(field)); - return _context.GetOrCreateFieldSymbol(field); + return _context.GetOrCreateFieldSymbol(field, requiredCustomModifiers, optionalCustomModifiers); } /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs index b10d2f16a..aef481677 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs @@ -290,9 +290,9 @@ public IReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) /// /// /// - public IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field) + public IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field, ITypeSymbol[]? optionalCustomModifiers, ITypeSymbol[]? requiredCustomModifiers) { - return GetOrCreateModuleSymbol((ModuleBuilder)field.Module).GetOrCreateFieldSymbol(field); + return GetOrCreateModuleSymbol((ModuleBuilder)field.Module).GetOrCreateFieldSymbol(field, optionalCustomModifiers, requiredCustomModifiers); } /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbolBase.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbolBase.cs index 4edd57cb3..50afe9477 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbolBase.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbolBase.cs @@ -93,13 +93,13 @@ public IReflectionMethodSymbolBuilder GetOrCreateMethodSymbol(MethodBuilder meth /// public IReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field) { - return _fieldTable.GetOrCreateFieldSymbol(field); + return _fieldTable.GetOrCreateFieldSymbol(field, null, null); } /// - public IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field) + public IReflectionFieldSymbolBuilder GetOrCreateFieldSymbol(FieldBuilder field, ITypeSymbol[]? requiredCustomModifiers, ITypeSymbol[]? optionalCustomModifiers) { - return _fieldTable.GetOrCreateFieldSymbol(field); + return _fieldTable.GetOrCreateFieldSymbol(field, requiredCustomModifiers, optionalCustomModifiers); } /// @@ -285,10 +285,10 @@ public IReflectionTypeSymbol GetOrCreateByRefTypeSymbol() #else /// - public virtual bool IsFunctionPointer => throw new NotImplementedException(); + public virtual bool IsFunctionPointer => throw new NotImplementedException(); /// - public virtual bool IsUnmanagedFunctionPointer => throw new NotImplementedException(); + public virtual bool IsUnmanagedFunctionPointer => throw new NotImplementedException(); #endif diff --git a/src/IKVM.Runtime/StubGen/StubGenerator.cs b/src/IKVM.Runtime/StubGen/StubGenerator.cs index 9b6aa0198..b8543551e 100644 --- a/src/IKVM.Runtime/StubGen/StubGenerator.cs +++ b/src/IKVM.Runtime/StubGen/StubGenerator.cs @@ -913,7 +913,7 @@ public PackageConstantHandle Map(PackageConstantHandle handle) object[] GetAnnotation(CustomAttribute cad) { // attribute is either a AnnotationAttributeBase or a DynamicAnnotationAttribute with a single object[] in our internal annotation format - if (cad.ConstructorArguments.Length == 1 && cad.ConstructorArguments[0].ArgumentType == context.Types.Object.MakeArrayType() && (cad.Constructor.DeclaringType.BaseType == context.Resolver.ResolveBaseType(typeof(ikvm.@internal.AnnotationAttributeBase).FullName) || cad.Constructor.DeclaringType == context.Resolver.ResolveBaseType(typeof(DynamicAnnotationAttribute).FullName))) + if (cad.ConstructorArguments.Length == 1 && cad.ConstructorArguments[0].ArgumentType == context.Types.Object.MakeArrayType() && (cad.Constructor.DeclaringType.BaseType == context.Resolver.ResolveBaseType(typeof(ikvm.@internal.AnnotationAttributeBase).FullName) || cad.Constructor.DeclaringType == context.Resolver.ResolveRuntimeType(typeof(DynamicAnnotationAttribute).FullName))) { return UnpackArray((IList)cad.ConstructorArguments[0].Value); } From 39311135a1031971974dd113795c17b513a6cc73 Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Sun, 20 Oct 2024 21:23:04 -0500 Subject: [PATCH 48/51] More. --- .../Reflection/ReflectionExtensions.cs | 6 ++++ .../Emit/ReflectionMethodSymbolBuilder.cs | 1 + .../Reflection/ReflectionMethodSymbol.cs | 28 +++++++++++++++++-- 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/IKVM.CoreLib/Reflection/ReflectionExtensions.cs b/src/IKVM.CoreLib/Reflection/ReflectionExtensions.cs index b7966e9d0..1fef51a67 100644 --- a/src/IKVM.CoreLib/Reflection/ReflectionExtensions.cs +++ b/src/IKVM.CoreLib/Reflection/ReflectionExtensions.cs @@ -20,6 +20,7 @@ static class ReflectionExtensions static readonly ParameterExpression _eventBuilderParameter = Expression.Parameter(typeof(EventBuilder), "p"); static readonly ParameterExpression _parameterBuilderParameter = Expression.Parameter(typeof(ParameterBuilder), "p"); + static readonly Type _methodBuilderInstantiationType = typeof(TypeBuilder).Assembly.GetType("System.Reflection.Emit.MethodBuilderInstantiation", true)!; static readonly Type _constructorOnTypeBuilderInstantiationType = typeof(TypeBuilder).Assembly.GetType("System.Reflection.Emit.ConstructorOnTypeBuilderInstantiation", true)!; static readonly Type _methodOnTypeBuilderInstantiationType = typeof(TypeBuilder).Assembly.GetType("System.Reflection.Emit.MethodOnTypeBuilderInstantiation", true)!; static readonly Type _fieldOnTypeBuilderInstantiationType = typeof(TypeBuilder).Assembly.GetType("System.Reflection.Emit.FieldOnTypeBuilderInstantiation", true)!; @@ -192,6 +193,11 @@ static class ReflectionExtensions _eventBuilderParameter) .Compile(); + /// + /// Gets the type. + /// + public static Type MethodBuilderInstantiationType => _methodBuilderInstantiationType; + /// /// Gets the type. /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs index 9a30c7a88..a4a788c0a 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionMethodSymbolBuilder.cs @@ -96,6 +96,7 @@ public void SetSignature(ITypeSymbol? returnType, ITypeSymbol[]? returnTypeRequi UnderlyingMethodBuilder.SetSignature(returnType?.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack()); } + /// public IGenericTypeParameterSymbolBuilder[] DefineGenericParameters(params string[] names) { var l = UnderlyingMethodBuilder.DefineGenericParameters(names); diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs index 5822b5e61..bc75e98a5 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs @@ -3,8 +3,6 @@ using System.Reflection.Emit; using System.Threading; -using IKVM.CoreLib.Threading; -using IKVM.CoreLib.Collections; using IKVM.CoreLib.Reflection; using IKVM.CoreLib.Symbols.Reflection.Emit; @@ -41,7 +39,31 @@ public ReflectionMethodSymbol(ReflectionSymbolContext context, IReflectionModule public virtual MethodInfo UnderlyingMethod => _method; /// - public virtual MethodInfo UnderlyingRuntimeMethod => _method; + public virtual MethodInfo UnderlyingRuntimeMethod => GetUnderlyingRuntimeMethod(); + + /// + /// Gets the underlying runtime method. + /// + /// + MethodInfo GetUnderlyingRuntimeMethod() + { + if (ReflectionExtensions.MethodOnTypeBuilderInstantiationType.IsInstanceOfType(_method)) + return GetUnderlyingRuntimeMethodForMethodOnTypeBuilderInstantiation(); + else if (ReflectionExtensions.MethodBuilderInstantiationType.IsInstanceOfType(_method)) + return GetUnderlyingRuntimeMethodForMethodBuilderInstantiationType(); + else + return _method; + } + + MethodInfo GetUnderlyingRuntimeMethodForMethodOnTypeBuilderInstantiation() + { + return _method; + } + + MethodInfo GetUnderlyingRuntimeMethodForMethodBuilderInstantiationType() + { + return _method; + } /// public override MethodBase UnderlyingMethodBase => UnderlyingMethod; From f86b12ae301ce3a3ab9923d3e9a344aa754af667 Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Tue, 22 Oct 2024 13:13:15 -0500 Subject: [PATCH 49/51] Space. Remove folder. --- .../Diagnostics/DiagnosticChannelWriterExtensions.cs | 1 - src/IKVM.Tools.Core/IKVM.Tools.Core.csproj | 4 ---- 2 files changed, 5 deletions(-) diff --git a/src/IKVM.Tools.Core/Diagnostics/DiagnosticChannelWriterExtensions.cs b/src/IKVM.Tools.Core/Diagnostics/DiagnosticChannelWriterExtensions.cs index 799ae0f0e..85c900ba4 100644 --- a/src/IKVM.Tools.Core/Diagnostics/DiagnosticChannelWriterExtensions.cs +++ b/src/IKVM.Tools.Core/Diagnostics/DiagnosticChannelWriterExtensions.cs @@ -1,6 +1,5 @@ using System; using System.Buffers; -using System.IO; namespace IKVM.Tools.Core.Diagnostics { diff --git a/src/IKVM.Tools.Core/IKVM.Tools.Core.csproj b/src/IKVM.Tools.Core/IKVM.Tools.Core.csproj index 5205a8c68..891c614dc 100644 --- a/src/IKVM.Tools.Core/IKVM.Tools.Core.csproj +++ b/src/IKVM.Tools.Core/IKVM.Tools.Core.csproj @@ -23,9 +23,5 @@ - - - - From 542c29b44e3aa74df70ee0a310fcfc8502661dfc Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Sat, 26 Oct 2024 11:31:49 -0500 Subject: [PATCH 50/51] Hmm --- Directory.Build.props | 4 + .../Reflection/ReflectionSymbolTests.cs | 4 +- src/IKVM.CoreLib/Buffers/MemoryExtensons.cs | 11 + src/IKVM.CoreLib/Buffers/SequenceReader.cs | 505 +++++++++ .../Buffers/SequenceReaderExtensions.cs | 392 +++++++ .../Collections/EnumerableExtensions.cs | 73 ++ .../GenericTypeParameterSymbolBuilderBase.cs | 606 +++++++++++ .../IGenericTypeParameterSymbolBuilder.cs | 2 +- .../Symbols/Emit/IModuleSymbolBuilder.cs | 82 +- .../Symbols/Emit/ITypeSymbolBuilder.cs | 51 +- .../Symbols/Emit/TypeSymbolBuilderBase.cs | 977 ++++++++++++++++++ src/IKVM.CoreLib/Symbols/IMethodBaseSymbol.cs | 7 +- src/IKVM.CoreLib/Symbols/ITypeSymbol.cs | 161 ++- ...ectionGenericTypeParameterSymbolBuilder.cs | 6 +- .../Emit/IkvmReflectionTypeSymbolBuilder.cs | 8 +- ...kvmReflectionGenericTypeParameterSymbol.cs | 6 +- .../IkvmReflectionTypeSymbol.cs | 6 +- ...ectionGenericTypeParameterSymbolBuilder.cs | 4 +- .../Emit/ReflectionTypeSymbolBuilder.cs | 52 +- .../Reflection/ReflectionArrayTypeSymbol.cs | 4 +- .../Reflection/ReflectionByRefTypeSymbol.cs | 4 +- ...flectionGenericInstantiationTypeSymbol.cs} | 46 +- .../ReflectionGenericTypeParameterSymbol.cs | 10 +- .../ReflectionGenericTypeParameterTable.cs | 2 +- .../Reflection/ReflectionPointerTypeSymbol.cs | 4 +- .../Reflection/ReflectionSZArrayTypeSymbol.cs | 4 +- ...peSymbol.cs => ReflectionTypeDefSymbol.cs} | 4 +- .../Reflection/ReflectionTypeSpecSymbol.cs | 12 +- .../Reflection/ReflectionTypeSpecTable.cs | 6 +- .../Reflection/ReflectionTypeSymbolBase.cs | 6 +- .../Symbols/Reflection/ReflectionTypeTable.cs | 2 +- src/IKVM.CoreLib/Symbols/SymbolUtil.cs | 164 ++- .../Symbols/TypeSymbolNameParserHelpers.cs | 393 +++++++ .../Symbols/TypeSymbolNameParserResult.cs | 41 + .../Symbols/TypeSymbolNameReader.cs | 270 +++++ src/IKVM.Reflection/Type.cs | 10 +- .../RuntimeManagedByteCodeJavaType.cs | 3 +- 37 files changed, 3691 insertions(+), 251 deletions(-) create mode 100644 src/IKVM.CoreLib/Buffers/MemoryExtensons.cs create mode 100644 src/IKVM.CoreLib/Buffers/SequenceReader.cs create mode 100644 src/IKVM.CoreLib/Buffers/SequenceReaderExtensions.cs create mode 100644 src/IKVM.CoreLib/Collections/EnumerableExtensions.cs create mode 100644 src/IKVM.CoreLib/Symbols/Emit/GenericTypeParameterSymbolBuilderBase.cs create mode 100644 src/IKVM.CoreLib/Symbols/Emit/TypeSymbolBuilderBase.cs rename src/IKVM.CoreLib/Symbols/Reflection/{ReflectionGenericSpecTypeSymbol.cs => ReflectionGenericInstantiationTypeSymbol.cs} (80%) rename src/IKVM.CoreLib/Symbols/Reflection/{ReflectionTypeSymbol.cs => ReflectionTypeDefSymbol.cs} (84%) create mode 100644 src/IKVM.CoreLib/Symbols/TypeSymbolNameParserHelpers.cs create mode 100644 src/IKVM.CoreLib/Symbols/TypeSymbolNameParserResult.cs create mode 100644 src/IKVM.CoreLib/Symbols/TypeSymbolNameReader.cs diff --git a/Directory.Build.props b/Directory.Build.props index bde86f5e5..bc21f1c58 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -7,6 +7,10 @@ win-x64;win-x86;win-arm64;linux-x64;linux-arm;linux-arm64;linux-musl-x64;linux-musl-arm;linux-musl-arm64;osx-x64;osx-arm64 $(SupportedImageRuntimes) + win-x64;win-x86 + win-x64;win-x86 + win-x64;win-x86 + <_SupportedRuntimes>;$(SupportedRuntimes); <_EnabledRuntimes>;$(EnabledRuntimes); <_SupportedToolRuntimes>;$(SupportedToolRuntimes); diff --git a/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs b/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs index f12186725..f083a2a69 100644 --- a/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs +++ b/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs @@ -61,7 +61,7 @@ public void SameTypeShouldBeSame() var c = new ReflectionSymbolContext(); var s1 = c.GetOrCreateTypeSymbol(typeof(object)); var s2 = c.GetOrCreateTypeSymbol(typeof(object)); - s1.Should().BeOfType(); + s1.Should().BeOfType(); s1.Should().BeSameAs(s2); } @@ -222,7 +222,7 @@ public void CanReadCustomAttributes() var s = c.GetOrCreateTypeSymbol(typeof(ClassWithAttributeWithType)); var a = s.GetCustomAttribute(c.GetOrCreateTypeSymbol(typeof(AttributeWithType))); var v = a.Value.ConstructorArguments[0].Value; - v.Should().BeOfType(); + v.Should().BeOfType(); } [TestMethod] diff --git a/src/IKVM.CoreLib/Buffers/MemoryExtensons.cs b/src/IKVM.CoreLib/Buffers/MemoryExtensons.cs new file mode 100644 index 000000000..4f424d01d --- /dev/null +++ b/src/IKVM.CoreLib/Buffers/MemoryExtensons.cs @@ -0,0 +1,11 @@ +namespace IKVM.CoreLib.Buffers +{ + + internal static class MemoryExtensons + { + + + + } + +} diff --git a/src/IKVM.CoreLib/Buffers/SequenceReader.cs b/src/IKVM.CoreLib/Buffers/SequenceReader.cs new file mode 100644 index 000000000..853c59328 --- /dev/null +++ b/src/IKVM.CoreLib/Buffers/SequenceReader.cs @@ -0,0 +1,505 @@ +// Copyright (c) All contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +/* Licensed to the .NET Foundation under one or more agreements. + * The .NET Foundation licenses this file to you under the MIT license. + * See the LICENSE file in the project root for more information. */ + +using System; +using System.Buffers; +using System.Diagnostics; +using System.Runtime.CompilerServices; + +namespace IKVM.CoreLib.Buffers +{ + +#if NETFRAMEWORK + + internal ref partial struct SequenceReader + where T : unmanaged, IEquatable + { + + /// + /// A value indicating whether we're using (as opposed to . + /// + private bool usingSequence; + + /// + /// Backing for the entire sequence when we're not using . + /// + private ReadOnlySequence sequence; + + /// + /// The position at the start of the . + /// + private SequencePosition currentPosition; + + /// + /// The position at the end of the . + /// + private SequencePosition nextPosition; + + /// + /// Backing for the entire sequence when we're not using . + /// + private ReadOnlyMemory memory; + + /// + /// A value indicating whether there is unread data remaining. + /// + private bool moreData; + + /// + /// The total number of elements in the sequence. + /// + private long length; + + /// + /// Initializes a new instance of the struct + /// over the given . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public SequenceReader(ReadOnlySequence sequence) + { + this.usingSequence = true; + this.CurrentSpanIndex = 0; + this.Consumed = 0; + this.sequence = sequence; + this.memory = default; + this.currentPosition = sequence.Start; + this.length = -1; + + ReadOnlySpan first = sequence.First.Span; + this.nextPosition = sequence.GetPosition(first.Length); + this.CurrentSpan = first; + this.moreData = first.Length > 0; + + if (!this.moreData && !sequence.IsSingleSegment) + { + this.moreData = true; + this.GetNextSpan(); + } + } + + /// + /// Initializes a new instance of the struct + /// over the given . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public SequenceReader(ReadOnlyMemory memory) + { + this.usingSequence = false; + this.CurrentSpanIndex = 0; + this.Consumed = 0; + this.memory = memory; + this.CurrentSpan = memory.Span; + this.length = memory.Length; + this.moreData = memory.Length > 0; + + this.currentPosition = default; + this.nextPosition = default; + this.sequence = default; + } + + /// + /// Gets a value indicating whether there is no more data in the . + /// + public bool End => !this.moreData; + + /// + /// Gets the underlying for the reader. + /// + public ReadOnlySequence Sequence + { + get + { + if (this.sequence.IsEmpty && !this.memory.IsEmpty) + { + // We're in memory mode (instead of sequence mode). + // Lazily fill in the sequence data. + this.sequence = new ReadOnlySequence(this.memory); + this.currentPosition = this.sequence.Start; + this.nextPosition = this.sequence.End; + } + + return this.sequence; + } + } + + /// + /// Gets the current position in the . + /// + public SequencePosition Position + => this.Sequence.GetPosition(this.CurrentSpanIndex, this.currentPosition); + + /// + /// Gets the current segment in the as a span. + /// + public ReadOnlySpan CurrentSpan { get; private set; } + + /// + /// Gets the index in the . + /// + public int CurrentSpanIndex { get; private set; } + + /// + /// Gets the unread portion of the . + /// + public ReadOnlySpan UnreadSpan + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => this.CurrentSpan.Slice(this.CurrentSpanIndex); + } + + /// + /// Gets the total number of 's processed by the reader. + /// + public long Consumed { get; private set; } + + /// + /// Gets remaining 's in the reader's . + /// + public long Remaining => this.Length - this.Consumed; + + /// + /// Gets count of in the reader's . + /// + public long Length + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + if (this.length < 0) + { + // Cache the length + this.length = this.Sequence.Length; + } + + return this.length; + } + } + + /// + /// Peeks at the next value without advancing the reader. + /// + /// The next value or default if at the end. + /// False if at the end of the reader. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryPeek(out T value) + { + if (this.moreData) + { + value = this.CurrentSpan[this.CurrentSpanIndex]; + return true; + } + else + { + value = default; + return false; + } + } + + /// + /// Read the next value and advance the reader. + /// + /// The next value or default if at the end. + /// False if at the end of the reader. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryRead(out T value) + { + if (this.End) + { + value = default; + return false; + } + + value = this.CurrentSpan[this.CurrentSpanIndex]; + this.CurrentSpanIndex++; + this.Consumed++; + + if (this.CurrentSpanIndex >= this.CurrentSpan.Length) + { + if (this.usingSequence) + { + this.GetNextSpan(); + } + else + { + this.moreData = false; + } + } + + return true; + } + + /// + /// Move the reader back the specified number of items. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Rewind(long count) + { + if (count < 0) + { + throw new ArgumentOutOfRangeException(nameof(count)); + } + + this.Consumed -= count; + + if (this.CurrentSpanIndex >= count) + { + this.CurrentSpanIndex -= (int)count; + this.moreData = true; + } + else if (this.usingSequence) + { + // Current segment doesn't have enough data, scan backward through segments + this.RetreatToPreviousSpan(this.Consumed); + } + else + { + throw new ArgumentOutOfRangeException("Rewind went past the start of the memory."); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void RetreatToPreviousSpan(long consumed) + { + Debug.Assert(this.usingSequence, "usingSequence"); + this.ResetReader(); + this.Advance(consumed); + } + + private void ResetReader() + { + Debug.Assert(this.usingSequence, "usingSequence"); + this.CurrentSpanIndex = 0; + this.Consumed = 0; + this.currentPosition = this.Sequence.Start; + this.nextPosition = this.currentPosition; + + if (this.Sequence.TryGet(ref this.nextPosition, out ReadOnlyMemory memory, advance: true)) + { + this.moreData = true; + + if (memory.Length == 0) + { + this.CurrentSpan = default; + + // No data in the first span, move to one with data + this.GetNextSpan(); + } + else + { + this.CurrentSpan = memory.Span; + } + } + else + { + // No data in any spans and at end of sequence + this.moreData = false; + this.CurrentSpan = default; + } + } + + /// + /// Get the next segment with available data, if any. + /// + private void GetNextSpan() + { + Debug.Assert(this.usingSequence, "usingSequence"); + if (!this.Sequence.IsSingleSegment) + { + SequencePosition previousNextPosition = this.nextPosition; + while (this.Sequence.TryGet(ref this.nextPosition, out ReadOnlyMemory memory, advance: true)) + { + this.currentPosition = previousNextPosition; + if (memory.Length > 0) + { + this.CurrentSpan = memory.Span; + this.CurrentSpanIndex = 0; + return; + } + else + { + this.CurrentSpan = default; + this.CurrentSpanIndex = 0; + previousNextPosition = this.nextPosition; + } + } + } + + this.moreData = false; + } + + /// + /// Move the reader ahead the specified number of items. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Advance(long count) + { + const long TooBigOrNegative = unchecked((long)0xFFFFFFFF80000000); + if ((count & TooBigOrNegative) == 0 && this.CurrentSpan.Length - this.CurrentSpanIndex > (int)count) + { + this.CurrentSpanIndex += (int)count; + this.Consumed += count; + } + else if (this.usingSequence) + { + // Can't satisfy from the current span + this.AdvanceToNextSpan(count); + } + else if (this.CurrentSpan.Length - this.CurrentSpanIndex == (int)count) + { + this.CurrentSpanIndex += (int)count; + this.Consumed += count; + this.moreData = false; + } + else + { + throw new ArgumentOutOfRangeException(nameof(count)); + } + } + + /// + /// Unchecked helper to avoid unnecessary checks where you know count is valid. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal void AdvanceCurrentSpan(long count) + { + Debug.Assert(count >= 0, "count >= 0"); + + this.Consumed += count; + this.CurrentSpanIndex += (int)count; + if (this.usingSequence && this.CurrentSpanIndex >= this.CurrentSpan.Length) + { + this.GetNextSpan(); + } + } + + /// + /// Only call this helper if you know that you are advancing in the current span + /// with valid count and there is no need to fetch the next one. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal void AdvanceWithinSpan(long count) + { + Debug.Assert(count >= 0, "count >= 0"); + + this.Consumed += count; + this.CurrentSpanIndex += (int)count; + + Debug.Assert(this.CurrentSpanIndex < this.CurrentSpan.Length, "this.CurrentSpanIndex < this.CurrentSpan.Length"); + } + + /// + /// Move the reader ahead the specified number of items + /// if there are enough elements remaining in the sequence. + /// + /// true if there were enough elements to advance; otherwise false. + internal bool TryAdvance(long count) + { + if (this.Remaining < count) + { + return false; + } + + this.Advance(count); + return true; + } + + private void AdvanceToNextSpan(long count) + { + Debug.Assert(this.usingSequence, "usingSequence"); + if (count < 0) + { + throw new ArgumentOutOfRangeException(nameof(count)); + } + + this.Consumed += count; + while (this.moreData) + { + int remaining = this.CurrentSpan.Length - this.CurrentSpanIndex; + + if (remaining > count) + { + this.CurrentSpanIndex += (int)count; + count = 0; + break; + } + + // As there may not be any further segments we need to + // push the current index to the end of the span. + this.CurrentSpanIndex += remaining; + count -= remaining; + Debug.Assert(count >= 0, "count >= 0"); + + this.GetNextSpan(); + + if (count == 0) + { + break; + } + } + + if (count != 0) + { + // Not enough data left- adjust for where we actually ended and throw + this.Consumed -= count; + throw new ArgumentOutOfRangeException(nameof(count)); + } + } + + /// + /// Copies data from the current to the given span. + /// + /// Destination to copy to. + /// True if there is enough data to copy to the . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryCopyTo(Span destination) + { + ReadOnlySpan firstSpan = this.UnreadSpan; + if (firstSpan.Length >= destination.Length) + { + firstSpan.Slice(0, destination.Length).CopyTo(destination); + return true; + } + + return this.TryCopyMultisegment(destination); + } + + internal bool TryCopyMultisegment(Span destination) + { + if (this.Remaining < destination.Length) + { + return false; + } + + ReadOnlySpan firstSpan = this.UnreadSpan; + Debug.Assert(firstSpan.Length < destination.Length, "firstSpan.Length < destination.Length"); + firstSpan.CopyTo(destination); + int copied = firstSpan.Length; + + SequencePosition next = this.nextPosition; + while (this.Sequence.TryGet(ref next, out ReadOnlyMemory nextSegment, true)) + { + if (nextSegment.Length > 0) + { + ReadOnlySpan nextSpan = nextSegment.Span; + int toCopy = Math.Min(nextSpan.Length, destination.Length - copied); + nextSpan.Slice(0, toCopy).CopyTo(destination.Slice(copied)); + copied += toCopy; + if (copied >= destination.Length) + { + break; + } + } + } + + return true; + } + + } + +#endif + +} \ No newline at end of file diff --git a/src/IKVM.CoreLib/Buffers/SequenceReaderExtensions.cs b/src/IKVM.CoreLib/Buffers/SequenceReaderExtensions.cs new file mode 100644 index 000000000..4609baa44 --- /dev/null +++ b/src/IKVM.CoreLib/Buffers/SequenceReaderExtensions.cs @@ -0,0 +1,392 @@ +using System; +using System.Buffers; +using System.Buffers.Binary; +using System.Diagnostics; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace IKVM.CoreLib.Buffers +{ + + static partial class SequenceReaderExtensions + { + + /// + /// Try to read the given type out of the buffer if possible. Warning: this is dangerous to use with arbitrary + /// structs- see remarks for full details. + /// + /// + /// IMPORTANT: The read is a straight copy of bits. If a struct depends on specific state of its members to + /// behave correctly this can lead to exceptions, etc. If reading endian specific integers, use the explicit + /// overloads such as . + /// + /// + /// True if successful. will be default if failed (due to lack of space). + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe bool TryRead(ref this SequenceReader reader, out T value) + where T : unmanaged + { + var span = reader.UnreadSpan; + if (span.Length < sizeof(T)) + return TryReadMultisegment(ref reader, out value); + + value = Unsafe.ReadUnaligned(ref MemoryMarshal.GetReference(span)); + reader.Advance(sizeof(T)); + return true; + } + + static unsafe bool TryReadMultisegment(ref SequenceReader reader, out T value) + where T : unmanaged + { + Debug.Assert(reader.UnreadSpan.Length < sizeof(T), "reader.UnreadSpan.Length < sizeof(T)"); + + // Not enough data in the current segment, try to peek for the data we need. + var buffer = default(T); + var tempSpan = new Span(&buffer, sizeof(T)); + + if (!reader.TryCopyTo(tempSpan)) + { + value = default; + return false; + } + + value = Unsafe.ReadUnaligned(ref MemoryMarshal.GetReference(tempSpan)); + reader.Advance(sizeof(T)); + return true; + } + + /// + /// Reads an from the next position in the sequence. + /// + /// The reader to read from. + /// Receives the value read. + /// true if there was another byte in the sequence; false otherwise. + public static bool TryRead(ref this SequenceReader reader, out sbyte value) + { + if (TryRead(ref reader, out byte byteValue)) + { + value = unchecked((sbyte)byteValue); + return true; + } + + value = default; + return false; + } + +#if NETFRAMEWORK + + /// + /// Reads an as big endian. + /// + /// False if there wasn't enough data for an . + public static bool TryReadBigEndian(ref this SequenceReader reader, out short value) + { + if (!BitConverter.IsLittleEndian) + { + return reader.TryRead(out value); + } + + return TryReadReverseEndianness(ref reader, out value); + } + +#endif + + /// + /// Reads an as big endian. + /// + /// False if there wasn't enough data for an . + public static bool TryReadBigEndian(ref this SequenceReader reader, out ushort value) + { + if (reader.TryReadBigEndian(out short shortValue)) + { + value = unchecked((ushort)shortValue); + return true; + } + + value = default; + return false; + } + + private static bool TryReadReverseEndianness(ref SequenceReader reader, out short value) + { + if (reader.TryRead(out value)) + { + value = BinaryPrimitives.ReverseEndianness(value); + return true; + } + + return false; + } + +#if NETFRAMEWORK + + /// + /// Reads an as big endian. + /// + /// False if there wasn't enough data for an . + public static bool TryReadBigEndian(ref this SequenceReader reader, out int value) + { + return BitConverter.IsLittleEndian ? TryReadReverseEndianness(ref reader, out value) : reader.TryRead(out value); + } + +#endif + + /// + /// Reads an as big endian. + /// + /// False if there wasn't enough data for an . + public static bool TryReadBigEndian(ref this SequenceReader reader, out uint value) + { + if (reader.TryReadBigEndian(out int intValue)) + { + value = unchecked((uint)intValue); + return true; + } + + value = default; + return false; + } + + static bool TryReadReverseEndianness(ref SequenceReader reader, out int value) + { + if (reader.TryRead(out value)) + { + value = BinaryPrimitives.ReverseEndianness(value); + return true; + } + + return false; + } + +#if NETFRAMEWORK + + /// + /// Reads an as big endian. + /// + /// False if there wasn't enough data for an . + public static bool TryReadBigEndian(ref this SequenceReader reader, out long value) + { + return BitConverter.IsLittleEndian ? TryReadReverseEndianness(ref reader, out value) : reader.TryRead(out value); + } + +#endif + + /// + /// Reads an as big endian. + /// + /// False if there wasn't enough data for an . + public static bool TryReadBigEndian(ref this SequenceReader reader, out ulong value) + { + if (reader.TryReadBigEndian(out long longValue)) + { + value = unchecked((ulong)longValue); + return true; + } + + value = default; + return false; + } + + static bool TryReadReverseEndianness(ref SequenceReader reader, out long value) + { + if (reader.TryRead(out value)) + { + value = BinaryPrimitives.ReverseEndianness(value); + return true; + } + + return false; + } + + /// + /// Reads a as big endian. + /// + /// False if there wasn't enough data for a . + public static unsafe bool TryReadBigEndian(ref this SequenceReader reader, out float value) + { + if (reader.TryReadBigEndian(out int intValue)) + { + value = *(float*)&intValue; + return true; + } + + value = default; + return false; + } + + /// + /// Reads a as big endian. + /// + /// False if there wasn't enough data for a . + public static unsafe bool TryReadBigEndian(ref this SequenceReader reader, out double value) + { + if (reader.TryReadBigEndian(out long longValue)) + { + value = *(double*)&longValue; + return true; + } + + value = default; + return false; + } + + /// + /// Try to read data with given . + /// + /// Read count. + /// The read data, if successfully read requested data. + /// true if remaining items in current is enough for . + public static bool TryReadExact(ref this SequenceReader reader, int count, out ReadOnlySequence sequence) + where T : unmanaged, IEquatable + { + if (count < 0) + throw new ArgumentOutOfRangeException(nameof(count)); + + if (count > reader.Remaining) + { + sequence = default; + return false; + } + + sequence = reader.Sequence.Slice(reader.Position, count); + if (count != 0) + reader.Advance(count); + + return true; + } + + /// + /// Try to read data with given . + /// + /// Read count. + /// The read data, if successfully read requested data. + /// true if remaining items in current is enough for . + public static bool TryReadExact(ref this SequenceReader reader, long count, out ReadOnlySequence sequence) + where T : unmanaged, IEquatable + { + if (count < 0) + throw new ArgumentOutOfRangeException(nameof(count)); + + if (count > reader.Remaining) + { + sequence = default; + return false; + } + + sequence = reader.Sequence.Slice(reader.Position, count); + if (count != 0) + reader.Advance(count); + + return true; + } + + /// + /// Tries to advance the reader over the specified number of bytes. + /// + /// + /// + /// + public static bool TryAdvance(ref this SequenceReader reader, long count) + where T : unmanaged, IEquatable + { + return reader.TryReadExact(count, out _); + } + + + /// + /// Advances bytes up until the alignment is met. + /// + public static bool TryAlign(ref this SequenceReader reader, int alignment) + where T : unmanaged, IEquatable + { + var position = (int)reader.Consumed; + return TryAdvance(ref reader, CalculateAlignment(position, alignment) - position); + } + + /// + /// Returns the number of bits set on the specified . + /// + /// + /// + static int PopCount(int v) + { + return PopCount(unchecked((uint)v)); + } + + /// + /// Returns the number of bits set on the specified . + /// + /// + /// + static int PopCount(uint v) + { +#if NET + return BitOperations.PopCount(v); +#else + unchecked + { + v -= ((v >> 1) & 0x55555555u); + v = (v & 0x33333333u) + ((v >> 2) & 0x33333333u); + return (int)((v + (v >> 4) & 0xF0F0F0Fu) * 0x1010101u) >> 24; + } +#endif + } + + /// + /// Calculates the alignment based on the current position and alignment. + /// + /// + /// + /// + static int CalculateAlignment(int position, int alignment) + { + Debug.Assert(position >= 0 && alignment > 0); + Debug.Assert(PopCount(alignment) == 1); + + int result = position & ~(alignment - 1); + if (result == position) + return result; + + return result + alignment; + } + + /// + /// Skip consecutive instances of any of the given . + /// + /// How many positions the reader has been advanced. + public static long AdvancePastAny(this ref SequenceReader reader, scoped ReadOnlySpan values) + where T : unmanaged, IEquatable + { + var start = reader.Consumed; + + do + { + // Advance past all matches in the current span + int i; + for (i = reader.CurrentSpanIndex; i < reader.CurrentSpan.Length && values.IndexOf(reader.CurrentSpan[i]) != -1; i++) + { + continue; + } + + int advanced = i - reader.CurrentSpanIndex; + if (advanced == 0) + { + // Didn't advance at all in this span, exit. + break; + } + + reader.Advance(advanced); + + // If we're at position 0 after advancing and not at the End, + // we're in a new span and should continue the loop. + } + while (reader.CurrentSpanIndex == 0 && !reader.End); + + return reader.Consumed - start; + } + + } + +} diff --git a/src/IKVM.CoreLib/Collections/EnumerableExtensions.cs b/src/IKVM.CoreLib/Collections/EnumerableExtensions.cs new file mode 100644 index 000000000..c62a08811 --- /dev/null +++ b/src/IKVM.CoreLib/Collections/EnumerableExtensions.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; + +namespace IKVM.CoreLib.Collections +{ + + static class EnumerableExtensions + { + + public static TSource? SingleOrDefaultOrThrow(this IEnumerable source, Func exception) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (exception == null) + throw new ArgumentNullException(nameof(exception)); + + if (source is IReadOnlyList list) + { + switch (list.Count) + { + case 0: + return default; + case 1: + return list[0]; + } + } + else + { + using IEnumerator enumerator = source.GetEnumerator(); + if (enumerator.MoveNext() == false) + return default; + + var current = enumerator.Current; + if (enumerator.MoveNext() == false) + return current; + } + + throw exception(); + } + + public static TSource? SingleOrDefaultOrThrow(this IEnumerable source, Predicate predicate, Func exception) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (predicate == null) + throw new ArgumentNullException(nameof(predicate)); + if (exception == null) + throw new ArgumentNullException(nameof(exception)); + + var val = default(TSource); + var num = 0; + + foreach (var item in source) + { + if (predicate(item)) + { + val = item; + if ((++num) >= 2) + throw exception(); + } + } + + return num switch + { + 0 => default, + 1 => val, + _ => throw new InvalidOperationException(), + }; + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Emit/GenericTypeParameterSymbolBuilderBase.cs b/src/IKVM.CoreLib/Symbols/Emit/GenericTypeParameterSymbolBuilderBase.cs new file mode 100644 index 000000000..b7fa43039 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Emit/GenericTypeParameterSymbolBuilderBase.cs @@ -0,0 +1,606 @@ +using System; +using System.Collections.Immutable; +using System.Reflection; + +namespace IKVM.CoreLib.Symbols.Emit +{ + + class GenericTypeParameterSymbolBuilderBase : IGenericTypeParameterSymbolBuilder + { + + readonly ISymbolContext _context; + readonly IModuleSymbolBuilder _module; + readonly IMemberSymbolBuilder _member; + readonly string _name; + + GenericParameterAttributes _attributes; + ITypeSymbol? _baseTypeConstraint; + ImmutableArray _interfaceConstraints = ImmutableArray.Empty; + ImmutableList _customAttributes = ImmutableList.Empty; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + /// + public GenericTypeParameterSymbolBuilderBase(ISymbolContext context, IModuleSymbolBuilder module, IMemberSymbolBuilder member, string name) + { + _context = context ?? throw new ArgumentNullException(nameof(context)); + _module = module ?? throw new ArgumentNullException(nameof(module)); + _member = member ?? throw new ArgumentNullException(nameof(member)); + _name = name ?? throw new ArgumentNullException(nameof(name)); + } + + /// + public ISymbolContext Context => _context; + + /// + public IModuleSymbolBuilder ResolvingModuleBuilder => _module; + + /// + public IMemberSymbolBuilder ResolvingMemberBuilder => _member; + + #region IGenericTypeParameterSymbolBuilder + + /// + public void SetBaseTypeConstraint(ITypeSymbol? baseTypeConstraint) + { + _baseTypeConstraint = baseTypeConstraint; + } + + /// + public void SetGenericParameterAttributes(GenericParameterAttributes attributes) + { + _attributes = attributes; + } + + /// + public void SetInterfaceConstraints(params ITypeSymbol[] interfaceConstraints) + { + _interfaceConstraints = interfaceConstraints.ToImmutableArray(); + } + + #endregion + + #region ICustomAttributeProviderBuilder + + /// + public void SetCustomAttribute(CustomAttribute attribute) + { + _customAttributes = _customAttributes.Add(attribute); + } + + #endregion + + #region ITypeSymbol + + /// + public virtual IAssemblySymbol Assembly => ResolvingModuleBuilder.Assembly; + + /// + public virtual string? AssemblyQualifiedName => System.Reflection.Assembly.CreateQualifiedName(Assembly.FullName, FullName); + + /// + public virtual TypeAttributes Attributes => _attributes; + + /// + public virtual ITypeSymbol? BaseType => ResolveTypeSymbol(UnderlyingType.BaseType); + + /// + public virtual bool ContainsGenericParameters => UnderlyingType.ContainsGenericParameters; + + /// + public virtual IMethodBaseSymbol? DeclaringMethod => ResolveMethodBaseSymbol(UnderlyingType.DeclaringMethod); + + /// + public virtual string? FullName => UnderlyingType.FullName; + + /// + public virtual string? Namespace => UnderlyingType.Namespace; + + /// + public virtual GenericParameterAttributes GenericParameterAttributes => UnderlyingType.GenericParameterAttributes; + + /// + public virtual int GenericParameterPosition => UnderlyingType.GenericParameterPosition; + + /// + public virtual ITypeSymbol[] GenericTypeArguments => ResolveTypeSymbols(UnderlyingType.GenericTypeArguments); + + /// + public virtual bool HasElementType => UnderlyingType.HasElementType; + + /// + public virtual TypeCode TypeCode => Type.GetTypeCode(UnderlyingType); + + /// + public virtual bool IsAbstract => UnderlyingType.IsAbstract; + + /// + public virtual bool IsSZArray => UnderlyingType.IsSZArray(); + + /// + public virtual bool IsArray => UnderlyingType.IsArray; + + /// + public virtual bool IsAutoLayout => UnderlyingType.IsAutoLayout; + + /// + public virtual bool IsExplicitLayout => UnderlyingType.IsExplicitLayout; + + /// + public virtual bool IsByRef => UnderlyingType.IsByRef; + + /// + public virtual bool IsClass => UnderlyingType.IsClass; + + /// + public virtual bool IsEnum => UnderlyingType.IsEnum; + + /// + public virtual bool IsInterface => UnderlyingType.IsInterface; + + /// + public virtual bool IsConstructedGenericType => UnderlyingType.IsConstructedGenericType; + + /// + public virtual bool IsGenericParameter => UnderlyingType.IsGenericParameter; + + /// + public virtual bool IsGenericType => UnderlyingType.IsGenericType; + + /// + public virtual bool IsGenericTypeDefinition => UnderlyingType.IsGenericTypeDefinition; + + /// + public virtual bool IsLayoutSequential => UnderlyingType.IsLayoutSequential; + + /// + public virtual bool IsNested => UnderlyingType.IsNested; + + /// + public virtual bool IsNestedAssembly => UnderlyingType.IsNestedAssembly; + + /// + public virtual bool IsNestedFamANDAssem => UnderlyingType.IsNestedFamANDAssem; + + /// + public virtual bool IsNestedFamORAssem => UnderlyingType.IsNestedFamORAssem; + + /// + public virtual bool IsNestedFamily => UnderlyingType.IsNestedFamily; + + /// + public virtual bool IsNestedPrivate => UnderlyingType.IsNestedPrivate; + + /// + public virtual bool IsNestedPublic => UnderlyingType.IsNestedPublic; + + /// + public virtual bool IsNotPublic => UnderlyingType.IsNotPublic; + + /// + public virtual bool IsPointer => UnderlyingType.IsPointer; + +#if NET8_0_OR_GREATER + + /// + public virtual bool IsFunctionPointer => UnderlyingType.IsFunctionPointer; + + /// + public virtual bool IsUnmanagedFunctionPointer => UnderlyingType.IsUnmanagedFunctionPointer; + +#else + + /// + public virtual bool IsFunctionPointer => throw new NotImplementedException(); + + /// + public virtual bool IsUnmanagedFunctionPointer => throw new NotImplementedException(); + +#endif + + /// + public virtual bool IsPrimitive => UnderlyingType.IsPrimitive; + + /// + public virtual bool IsPublic => UnderlyingType.IsPublic; + + /// + public virtual bool IsSealed => UnderlyingType.IsSealed; + + /// + public virtual bool IsSerializable => UnderlyingType.IsSerializable; + + /// + public virtual bool IsValueType => UnderlyingType.IsValueType; + + /// + public virtual bool IsVisible => UnderlyingType.IsVisible; + + /// + public virtual bool IsSignatureType => throw new NotImplementedException(); + + /// + public virtual bool IsSpecialName => UnderlyingType.IsSpecialName; + + /// + public virtual IConstructorSymbol? TypeInitializer => ResolveConstructorSymbol(UnderlyingType.TypeInitializer); + + /// + public virtual int GetArrayRank() + { + return UnderlyingType.GetArrayRank(); + } + + /// + public virtual IConstructorSymbol? GetConstructor(BindingFlags bindingAttr, ITypeSymbol[] types) + { + return ResolveConstructorSymbol(UnderlyingType.GetConstructor(bindingAttr, binder: null, types.Unpack(), modifiers: null)); + } + + /// + public virtual IConstructorSymbol? GetConstructor(ITypeSymbol[] types) + { + return ResolveConstructorSymbol(UnderlyingType.GetConstructor(types.Unpack())); + } + + /// + public virtual IConstructorSymbol[] GetConstructors() + { + return ResolveConstructorSymbols(UnderlyingType.GetConstructors()); + } + + /// + public virtual IConstructorSymbol[] GetConstructors(BindingFlags bindingAttr) + { + return ResolveConstructorSymbols(UnderlyingType.GetConstructors(bindingAttr)); + } + + /// + public virtual IMemberSymbol[] GetDefaultMembers() + { + return ResolveMemberSymbols(UnderlyingType.GetDefaultMembers()); + } + + /// + public virtual ITypeSymbol? GetElementType() + { + return ResolveTypeSymbol(UnderlyingType.GetElementType()); + } + + /// + public virtual string? GetEnumName(object value) + { + return UnderlyingType.GetEnumName(value); + } + + /// + public virtual string[] GetEnumNames() + { + return UnderlyingType.GetEnumNames(); + } + + /// + public virtual ITypeSymbol GetEnumUnderlyingType() + { + return ResolveTypeSymbol(UnderlyingType.GetEnumUnderlyingType()); + } + + /// + public virtual Array GetEnumValues() + { + return UnderlyingType.GetEnumValues(); + } + + /// + public virtual IEventSymbol? GetEvent(string name) + { + return ResolveEventSymbol(UnderlyingType.GetEvent(name)); + } + + /// + public virtual IEventSymbol? GetEvent(string name, BindingFlags bindingAttr) + { + return ResolveEventSymbol(UnderlyingType.GetEvent(name, bindingAttr)); + } + + /// + public virtual IEventSymbol[] GetEvents() + { + return ResolveEventSymbols(UnderlyingType.GetEvents()); + } + + /// + public virtual IEventSymbol[] GetEvents(BindingFlags bindingAttr) + { + return ResolveEventSymbols(UnderlyingType.GetEvents(bindingAttr)); + } + + /// + public virtual IFieldSymbol? GetField(string name) + { + return ResolveFieldSymbol(UnderlyingType.GetField(name)); + } + + /// + public virtual IFieldSymbol? GetField(string name, BindingFlags bindingAttr) + { + return ResolveFieldSymbol(UnderlyingType.GetField(name, bindingAttr)); + } + + /// + public virtual IFieldSymbol[] GetFields() + { + return ResolveFieldSymbols(UnderlyingType.GetFields()); + } + + /// + public virtual IFieldSymbol[] GetFields(BindingFlags bindingAttr) + { + return ResolveFieldSymbols(UnderlyingType.GetFields(bindingAttr)); + } + + /// + public virtual ITypeSymbol[] GetGenericArguments() + { + return ResolveTypeSymbols(UnderlyingType.GetGenericArguments()); + } + + /// + public virtual ITypeSymbol[] GetGenericParameterConstraints() + { + return ResolveTypeSymbols(UnderlyingType.GetGenericParameterConstraints()); + } + + /// + public virtual ITypeSymbol GetGenericTypeDefinition() + { + return ResolveTypeSymbol(UnderlyingType.GetGenericTypeDefinition()); + } + + /// + public virtual ITypeSymbol? GetInterface(string name) + { + return ResolveTypeSymbol(UnderlyingType.GetInterface(name)); + } + + /// + public virtual ITypeSymbol? GetInterface(string name, bool ignoreCase) + { + return ResolveTypeSymbol(UnderlyingType.GetInterface(name, ignoreCase)); + } + + /// + public virtual InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) + { + return ResolveInterfaceMapping(UnderlyingType.GetInterfaceMap(interfaceType.Unpack())); + } + + /// + public virtual ITypeSymbol[] GetInterfaces(bool inherit = true) + { + if (inherit) + return ResolveTypeSymbols(UnderlyingType.GetInterfaces()); + else + throw new NotImplementedException(); + } + + /// + public virtual IMemberSymbol[] GetMembers(string name) + { + return ResolveMemberSymbols(UnderlyingType.GetMember(name)); + } + + /// + public virtual IMemberSymbol[] GetMembers(string name, BindingFlags bindingAttr) + { + return ResolveMemberSymbols(UnderlyingType.GetMember(name, bindingAttr)); + } + + /// + public virtual IMemberSymbol[] GetMembers(string name, MemberTypes type, BindingFlags bindingAttr) + { + return ResolveMemberSymbols(UnderlyingType.GetMember(name, type, bindingAttr)); + } + + /// + public virtual IMemberSymbol[] GetMembers(BindingFlags bindingAttr) + { + return ResolveMemberSymbols(UnderlyingType.GetMembers(bindingAttr)); + } + + /// + public virtual IMemberSymbol[] GetMembers() + { + return ResolveMemberSymbols(UnderlyingType.GetMembers()); + } + + /// + public virtual IMethodSymbol? GetMethod(string name) + { + return ResolveMethodSymbol(UnderlyingType.GetMethod(name)); + } + + /// + public virtual IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr) + { + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, bindingAttr)); + } + + /// + public virtual IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) + { + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, types.Unpack())); + } + + /// + public virtual IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types) + { + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, bindingAttr, null, types.Unpack(), null)); + } + + /// + public virtual IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types, ParameterModifier[]? modifiers) + { + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, bindingAttr, null, types.Unpack(), modifiers?.Unpack())); + } + + /// + public virtual IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers) + { + return ResolveMethodSymbol(UnderlyingType.GetMethod(name, bindingAttr, null, callConvention, types.Unpack(), modifiers?.Unpack())); + } + + /// + public virtual IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, ParameterModifier[]? modifiers) + { + throw new NotImplementedException(); + } + + /// + public virtual IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, ITypeSymbol[] types, ParameterModifier[]? modifiers) + { + throw new NotImplementedException(); + } + + /// + public virtual IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers) + { + throw new NotImplementedException(); + } + + /// + public virtual IMethodSymbol[] GetMethods(BindingFlags bindingAttr) + { + return ResolveMethodSymbols(UnderlyingType.GetMethods(bindingAttr)); + } + + /// + public virtual IMethodSymbol[] GetMethods() + { + return ResolveMethodSymbols(UnderlyingType.GetMethods()); + } + + /// + public virtual ITypeSymbol? GetNestedType(string name) + { + return ResolveTypeSymbol(UnderlyingType.GetNestedType(name)); + } + + /// + public virtual ITypeSymbol? GetNestedType(string name, System.Reflection.BindingFlags bindingAttr) + { + return ResolveTypeSymbol(UnderlyingType.GetNestedType(name, bindingAttr)); + } + + /// + public virtual ITypeSymbol[] GetNestedTypes() + { + return ResolveTypeSymbols(UnderlyingType.GetNestedTypes()); + } + + /// + public virtual ITypeSymbol[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr) + { + return ResolveTypeSymbols(UnderlyingType.GetNestedTypes((BindingFlags)bindingAttr)); + } + + /// + public virtual IPropertySymbol[] GetProperties() + { + return ResolvePropertySymbols(UnderlyingType.GetProperties()); + } + + /// + public virtual IPropertySymbol[] GetProperties(System.Reflection.BindingFlags bindingAttr) + { + return ResolvePropertySymbols(UnderlyingType.GetProperties((BindingFlags)bindingAttr)); + } + + /// + public virtual IPropertySymbol? GetProperty(string name, ITypeSymbol[] types) + { + return ResolvePropertySymbol(UnderlyingType.GetProperty(name, types.Unpack())); + } + + /// + public virtual IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types) + { + return ResolvePropertySymbol(UnderlyingType.GetProperty(name, returnType?.Unpack(), types.Unpack())); + } + + /// + public virtual IPropertySymbol? GetProperty(string name, System.Reflection.BindingFlags bindingAttr) + { + return ResolvePropertySymbol(UnderlyingType.GetProperty(name, (BindingFlags)bindingAttr)); + } + + /// + public virtual IPropertySymbol? GetProperty(string name) + { + return ResolvePropertySymbol(UnderlyingType.GetProperty(name)); + } + + /// + public virtual IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) + { + return ResolvePropertySymbol(UnderlyingType.GetProperty(name, returnType?.Unpack())); + } + + /// + public virtual bool IsAssignableFrom(ITypeSymbol? c) + { + return UnderlyingType.IsAssignableFrom(c?.Unpack()); + } + + /// + public virtual bool IsEnumDefined(object value) + { + return UnderlyingType.IsEnumDefined(value); + } + + /// + public virtual bool IsSubclassOf(ITypeSymbol c) + { + return UnderlyingType.IsSubclassOf(c.Unpack()); + } + + /// + public virtual ITypeSymbol MakeArrayType() + { + return ResolveTypeSymbol(UnderlyingType.MakeArrayType()); + } + + /// + public virtual ITypeSymbol MakeArrayType(int rank) + { + return ResolveTypeSymbol(UnderlyingType.MakeArrayType(rank)); + } + + /// + public virtual ITypeSymbol MakeByRefType() + { + return ResolveTypeSymbol(UnderlyingType.MakeByRefType()); + } + + /// + public virtual ITypeSymbol MakePointerType() + { + return ResolveTypeSymbol(UnderlyingType.MakePointerType()); + } + + /// + public virtual ITypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments) + { + return ResolveTypeSymbol(UnderlyingType.MakeGenericType(typeArguments.Unpack())); + } + +#endregion + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/Emit/IGenericTypeParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IGenericTypeParameterSymbolBuilder.cs index cfd742441..575c05d76 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/IGenericTypeParameterSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/IGenericTypeParameterSymbolBuilder.cs @@ -20,7 +20,7 @@ interface IGenericTypeParameterSymbolBuilder : ISymbolBuilder, ITyp /// Sets the interfaces a type must implement in order to be substituted for the type parameter. /// /// - void SetInterfaceConstraints(params ITypeSymbol[]? interfaceConstraints); + void SetInterfaceConstraints(params ITypeSymbol[] interfaceConstraints); } diff --git a/src/IKVM.CoreLib/Symbols/Emit/IModuleSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/IModuleSymbolBuilder.cs index efdd7a7ad..7413e2fad 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/IModuleSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/IModuleSymbolBuilder.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Immutable; using System.Diagnostics.SymbolStore; using System.IO; using System.Reflection; @@ -71,7 +72,7 @@ interface IModuleSymbolBuilder : ISymbolBuilder, IModuleSymbol, I /// /// /// - IMethodSymbolBuilder DefineGlobalMethod(string name, MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes); + IMethodSymbolBuilder DefineGlobalMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, IImmutableList parameterTypes); /// /// Defines a global method with the specified name, attributes, calling convention, return type, custom modifiers for the return type, parameter types, and custom modifiers for the parameter types. @@ -86,7 +87,7 @@ interface IModuleSymbolBuilder : ISymbolBuilder, IModuleSymbol, I /// /// /// - IMethodSymbolBuilder DefineGlobalMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? requiredReturnTypeCustomModifiers, ITypeSymbol[]? optionalReturnTypeCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? requiredParameterTypeCustomModifiers, ITypeSymbol[][]? optionalParameterTypeCustomModifiers); + IMethodSymbolBuilder DefineGlobalMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, IImmutableList requiredReturnTypeCustomModifiers, IImmutableList optionalReturnTypeCustomModifiers, IImmutableList parameterTypes, IImmutableList> requiredParameterTypeCustomModifiers, IImmutableList> optionalParameterTypeCustomModifiers); /// /// Defines a global method with the specified name, attributes, return type, and parameter types. @@ -96,7 +97,7 @@ interface IModuleSymbolBuilder : ISymbolBuilder, IModuleSymbol, I /// /// /// - IMethodSymbolBuilder DefineGlobalMethod(string name, MethodAttributes attributes, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes); + IMethodSymbolBuilder DefineGlobalMethod(string name, MethodAttributes attributes, ITypeSymbol? returnType, IImmutableList parameterTypes); /// /// Constructs a TypeBuilder for a private type with the specified name in this module. @@ -161,7 +162,79 @@ interface IModuleSymbolBuilder : ISymbolBuilder, IModuleSymbol, I /// /// /// - ITypeSymbolBuilder DefineType(string name, TypeAttributes attr, ITypeSymbol? parent, ITypeSymbol[]? interfaces); + ITypeSymbolBuilder DefineType(string name, TypeAttributes attr, ITypeSymbol? parent, IImmutableList interfaces); + + /// + /// Defines a nested type, given its name. + /// + /// + /// + /// + ITypeSymbolBuilder DefineNestedType(ITypeSymbolBuilder enclosingType, string name); + + /// + /// Defines a nested type, given its name and attributes. + /// + /// + /// + /// + /// + ITypeSymbolBuilder DefineNestedType(ITypeSymbolBuilder enclosingType, string name, TypeAttributes attr); + + /// + /// Defines a nested type, given its name, attributes, and the type that it extends. + /// + /// + /// + /// + /// + /// + ITypeSymbolBuilder DefineNestedType(ITypeSymbolBuilder enclosingType, string name, TypeAttributes attr, ITypeSymbol? parent); + + /// + /// Defines a nested type, given its name, attributes, the type that it extends, and the interfaces that it implements. + /// + /// + /// + /// + /// + /// + /// + ITypeSymbolBuilder DefineNestedType(ITypeSymbolBuilder enclosingType, string name, TypeAttributes attr, ITypeSymbol? parent, IImmutableList interfaces); + + /// + /// Defines a nested type, given its name, attributes, size, and the type that it extends. + /// + /// + /// + /// + /// + /// + /// + ITypeSymbolBuilder DefineNestedType(ITypeSymbolBuilder enclosingType, string name, TypeAttributes attr, ITypeSymbol? parent, int typeSize); + + /// + /// Defines a nested type, given its name, attributes, the type that it extends, and the packing size. + /// + /// + /// + /// + /// + /// + /// + ITypeSymbolBuilder DefineNestedType(ITypeSymbolBuilder enclosingType, string name, TypeAttributes attr, ITypeSymbol? parent, PackingSize packSize); + + /// + /// Defines a nested type, given its name, attributes, size, and the type that it extends. + /// + /// + /// + /// + /// + /// + /// + /// + ITypeSymbolBuilder DefineNestedType(ITypeSymbolBuilder enclosingType, string name, TypeAttributes attr, ITypeSymbol? parent, PackingSize packSize, int typeSize); /// /// Explicitely adds a reference to the specified assembly. @@ -180,6 +253,7 @@ interface IModuleSymbolBuilder : ISymbolBuilder, IModuleSymbol, I /// /// void Save(PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine); + } } diff --git a/src/IKVM.CoreLib/Symbols/Emit/ITypeSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Emit/ITypeSymbolBuilder.cs index dfa306cf8..5a05624bb 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/ITypeSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/ITypeSymbolBuilder.cs @@ -1,4 +1,7 @@ -using System.Reflection; +using System.Collections.Immutable; +using System.Reflection; +using System.Reflection.Emit; +using System.Runtime.InteropServices; namespace IKVM.CoreLib.Symbols.Emit { @@ -17,7 +20,7 @@ interface ITypeSymbolBuilder : ISymbolBuilder, IMemberSymbolBuilder /// /// /// - IGenericTypeParameterSymbolBuilder[] DefineGenericParameters(params string[] names); + IImmutableList DefineGenericParameters(IImmutableList names); /// /// Defines the initializer for this type. @@ -37,7 +40,7 @@ interface ITypeSymbolBuilder : ISymbolBuilder, IMemberSymbolBuilder /// /// /// - IConstructorSymbolBuilder DefineConstructor(System.Reflection.MethodAttributes attributes, ITypeSymbol[]? parameterTypes); + IConstructorSymbolBuilder DefineConstructor(MethodAttributes attributes, IImmutableList parameterTypes); /// /// Adds a new constructor to the type, with the given attributes and signature. @@ -46,7 +49,7 @@ interface ITypeSymbolBuilder : ISymbolBuilder, IMemberSymbolBuilder /// /// /// - IConstructorSymbolBuilder DefineConstructor(System.Reflection.MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol[]? parameterTypes); + IConstructorSymbolBuilder DefineConstructor(MethodAttributes attributes, CallingConventions callingConvention, IImmutableList parameterTypes); /// /// Adds a new constructor to the type, with the given attributes, signature, and custom modifiers. @@ -57,7 +60,7 @@ interface ITypeSymbolBuilder : ISymbolBuilder, IMemberSymbolBuilder /// /// /// - IConstructorSymbolBuilder DefineConstructor(MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? requiredCustomModifiers, ITypeSymbol[][]? optionalCustomModifiers); + IConstructorSymbolBuilder DefineConstructor(MethodAttributes attributes, CallingConventions callingConvention, IImmutableList parameterTypes, IImmutableList> requiredCustomModifiers, IImmutableList> optionalCustomModifiers); /// /// Defines the parameterless constructor. The constructor defined here will simply call the parameterless constructor of the parent. @@ -93,7 +96,7 @@ interface ITypeSymbolBuilder : ISymbolBuilder, IMemberSymbolBuilder /// /// /// - IFieldSymbolBuilder DefineField(string fieldName, ITypeSymbol type, ITypeSymbol[]? requiredCustomModifiers, ITypeSymbol[]? optionalCustomModifiers, FieldAttributes attributes); + IFieldSymbolBuilder DefineField(string fieldName, ITypeSymbol type, IImmutableList requiredCustomModifiers, IImmutableList optionalCustomModifiers, FieldAttributes attributes); /// /// Adds a new method to the type, with the specified name, method attributes, calling convention, method signature, and custom modifiers. @@ -108,7 +111,7 @@ interface ITypeSymbolBuilder : ISymbolBuilder, IMemberSymbolBuilder /// /// /// - IMethodSymbolBuilder DefineMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers); + IMethodSymbolBuilder DefineMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, IImmutableList returnTypeRequiredCustomModifiers, IImmutableList returnTypeOptionalCustomModifiers, IImmutableList parameterTypes, IImmutableList> parameterTypeRequiredCustomModifiers, IImmutableList> parameterTypeOptionalCustomModifiers); /// /// Adds a new method to the type, with the specified name, method attributes, calling convention, and method signature. @@ -119,7 +122,7 @@ interface ITypeSymbolBuilder : ISymbolBuilder, IMemberSymbolBuilder /// /// /// - IMethodSymbolBuilder DefineMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes); + IMethodSymbolBuilder DefineMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, IImmutableList parameterTypes); /// /// Adds a new method to the type, with the specified name, method attributes, and calling convention. @@ -128,7 +131,7 @@ interface ITypeSymbolBuilder : ISymbolBuilder, IMemberSymbolBuilder /// /// /// - IMethodSymbolBuilder DefineMethod(string name, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention); + IMethodSymbolBuilder DefineMethod(string name, MethodAttributes attributes, CallingConventions callingConvention); /// /// Adds a new method to the type, with the specified name and method attributes. @@ -136,7 +139,7 @@ interface ITypeSymbolBuilder : ISymbolBuilder, IMemberSymbolBuilder /// /// /// - IMethodSymbolBuilder DefineMethod(string name, System.Reflection.MethodAttributes attributes); + IMethodSymbolBuilder DefineMethod(string name, MethodAttributes attributes); /// /// Adds a new method to the type, with the specified name, method attributes, and method signature. @@ -146,7 +149,7 @@ interface ITypeSymbolBuilder : ISymbolBuilder, IMemberSymbolBuilder /// /// /// - IMethodSymbolBuilder DefineMethod(string name, System.Reflection.MethodAttributes attributes, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes); + IMethodSymbolBuilder DefineMethod(string name, MethodAttributes attributes, ITypeSymbol? returnType, IImmutableList parameterTypes); /// /// Specifies a given method body that implements a given method declaration, potentially with a different name. @@ -163,7 +166,7 @@ interface ITypeSymbolBuilder : ISymbolBuilder, IMemberSymbolBuilder /// /// /// - ITypeSymbolBuilder DefineNestedType(string name, System.Reflection.TypeAttributes attr, ITypeSymbol? parent, ITypeSymbol[]? interfaces); + ITypeSymbolBuilder DefineNestedType(string name, TypeAttributes attr, ITypeSymbol? parent, IImmutableList interfaces); /// /// Defines a nested type, given its name, attributes, size, and the type that it extends. @@ -174,7 +177,7 @@ interface ITypeSymbolBuilder : ISymbolBuilder, IMemberSymbolBuilder /// /// /// - ITypeSymbolBuilder DefineNestedType(string name, System.Reflection.TypeAttributes attr, ITypeSymbol? parent, System.Reflection.Emit.PackingSize packSize, int typeSize); + ITypeSymbolBuilder DefineNestedType(string name, TypeAttributes attr, ITypeSymbol? parent, PackingSize packSize, int typeSize); /// /// Defines a nested type, given its name, attributes, the type that it extends, and the packing size. @@ -184,7 +187,7 @@ interface ITypeSymbolBuilder : ISymbolBuilder, IMemberSymbolBuilder /// /// /// - ITypeSymbolBuilder DefineNestedType(string name, System.Reflection.TypeAttributes attr, ITypeSymbol? parent, System.Reflection.Emit.PackingSize packSize); + ITypeSymbolBuilder DefineNestedType(string name, TypeAttributes attr, ITypeSymbol? parent, PackingSize packSize); /// /// Defines a nested type, given its name. @@ -200,7 +203,7 @@ interface ITypeSymbolBuilder : ISymbolBuilder, IMemberSymbolBuilder /// /// /// - ITypeSymbolBuilder DefineNestedType(string name, System.Reflection.TypeAttributes attr, ITypeSymbol? parent); + ITypeSymbolBuilder DefineNestedType(string name, TypeAttributes attr, ITypeSymbol? parent); /// /// Defines a nested type, given its name and attributes. @@ -208,7 +211,7 @@ interface ITypeSymbolBuilder : ISymbolBuilder, IMemberSymbolBuilder /// /// /// - ITypeSymbolBuilder DefineNestedType(string name, System.Reflection.TypeAttributes attr); + ITypeSymbolBuilder DefineNestedType(string name, TypeAttributes attr); /// /// Defines a nested type, given its name, attributes, the total size of the type, and the type that it extends. @@ -218,7 +221,7 @@ interface ITypeSymbolBuilder : ISymbolBuilder, IMemberSymbolBuilder /// /// /// - ITypeSymbolBuilder DefineNestedType(string name, System.Reflection.TypeAttributes attr, ITypeSymbol? parent, int typeSize); + ITypeSymbolBuilder DefineNestedType(string name, TypeAttributes attr, ITypeSymbol? parent, int typeSize); /// /// Defines a PInvoke method given its name, the name of the DLL in which the method is defined, the attributes of the method, the calling convention of the method, the return type of the method, the types of the parameters of the method, and the PInvoke flags. @@ -232,7 +235,7 @@ interface ITypeSymbolBuilder : ISymbolBuilder, IMemberSymbolBuilder /// /// /// - IMethodSymbolBuilder DefinePInvokeMethod(string name, string dllName, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes, System.Runtime.InteropServices.CallingConvention nativeCallConv, System.Runtime.InteropServices.CharSet nativeCharSet); + IMethodSymbolBuilder DefinePInvokeMethod(string name, string dllName, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, IImmutableList parameterTypes, System.Runtime.InteropServices.CallingConvention nativeCallConv, System.Runtime.InteropServices.CharSet nativeCharSet); /// /// Defines a PInvoke method given its name, the name of the DLL in which the method is defined, the name of the entry point, the attributes of the method, the calling convention of the method, the return type of the method, the types of the parameters of the method, and the PInvoke flags. @@ -247,7 +250,7 @@ interface ITypeSymbolBuilder : ISymbolBuilder, IMemberSymbolBuilder /// /// /// - IMethodSymbolBuilder DefinePInvokeMethod(string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes, System.Runtime.InteropServices.CallingConvention nativeCallConv, System.Runtime.InteropServices.CharSet nativeCharSet); + IMethodSymbolBuilder DefinePInvokeMethod(string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, IImmutableList parameterTypes, System.Runtime.InteropServices.CallingConvention nativeCallConv, System.Runtime.InteropServices.CharSet nativeCharSet); /// /// Defines a PInvoke method given its name, the name of the DLL in which the method is defined, the name of the entry point, the attributes of the method, the calling convention of the method, the return type of the method, the types of the parameters of the method, the PInvoke flags, and custom modifiers for the parameters and return type. @@ -266,7 +269,7 @@ interface ITypeSymbolBuilder : ISymbolBuilder, IMemberSymbolBuilder /// /// /// - IMethodSymbolBuilder DefinePInvokeMethod(string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers, System.Runtime.InteropServices.CallingConvention nativeCallConv, System.Runtime.InteropServices.CharSet nativeCharSet); + IMethodSymbolBuilder DefinePInvokeMethod(string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, IImmutableList returnTypeRequiredCustomModifiers, IImmutableList returnTypeOptionalCustomModifiers, IImmutableList parameterTypes, IImmutableList> parameterTypeRequiredCustomModifiers, IImmutableList> parameterTypeOptionalCustomModifiers, CallingConvention nativeCallConv, CharSet nativeCharSet); /// /// Adds a new property to the type, with the given name and property signature. @@ -276,7 +279,7 @@ interface ITypeSymbolBuilder : ISymbolBuilder, IMemberSymbolBuilder /// /// /// - IPropertySymbolBuilder DefineProperty(string name, PropertyAttributes attributes, ITypeSymbol returnType, ITypeSymbol[]? parameterTypes); + IPropertySymbolBuilder DefineProperty(string name, PropertyAttributes attributes, ITypeSymbol returnType, IImmutableList parameterTypes); /// /// Adds a new property to the type, with the given name, attributes, calling convention, and property signature. @@ -287,7 +290,7 @@ interface ITypeSymbolBuilder : ISymbolBuilder, IMemberSymbolBuilder /// /// /// - IPropertySymbolBuilder DefineProperty(string name, PropertyAttributes attributes, CallingConventions callingConvention, ITypeSymbol returnType, ITypeSymbol[]? parameterTypes); + IPropertySymbolBuilder DefineProperty(string name, PropertyAttributes attributes, CallingConventions callingConvention, ITypeSymbol returnType, IImmutableList parameterTypes); /// /// Adds a new property to the type, with the given name, property signature, and custom modifiers. @@ -301,7 +304,7 @@ interface ITypeSymbolBuilder : ISymbolBuilder, IMemberSymbolBuilder /// /// /// - IPropertySymbolBuilder DefineProperty(string name, PropertyAttributes attributes, ITypeSymbol returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers); + IPropertySymbolBuilder DefineProperty(string name, PropertyAttributes attributes, ITypeSymbol returnType, IImmutableList returnTypeRequiredCustomModifiers, IImmutableList returnTypeOptionalCustomModifiers, IImmutableList parameterTypes, IImmutableList> parameterTypeRequiredCustomModifiers, IImmutableList> parameterTypeOptionalCustomModifiers); /// /// Adds a new property to the type, with the given name, calling convention, property signature, and custom modifiers. @@ -316,7 +319,7 @@ interface ITypeSymbolBuilder : ISymbolBuilder, IMemberSymbolBuilder /// /// /// - IPropertySymbolBuilder DefineProperty(string name, PropertyAttributes attributes, CallingConventions callingConvention, ITypeSymbol returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers); + IPropertySymbolBuilder DefineProperty(string name, PropertyAttributes attributes, CallingConventions callingConvention, ITypeSymbol returnType, IImmutableList returnTypeRequiredCustomModifiers, IImmutableList returnTypeOptionalCustomModifiers, IImmutableList parameterTypes, IImmutableList> parameterTypeRequiredCustomModifiers, IImmutableList> parameterTypeOptionalCustomModifiers); /// /// Finishes the type, updating the associated symbol. diff --git a/src/IKVM.CoreLib/Symbols/Emit/TypeSymbolBuilderBase.cs b/src/IKVM.CoreLib/Symbols/Emit/TypeSymbolBuilderBase.cs new file mode 100644 index 000000000..5c0818432 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/Emit/TypeSymbolBuilderBase.cs @@ -0,0 +1,977 @@ +using System; +using System.Collections.Immutable; +using System.Diagnostics; +using System.Linq; +using System.Reflection; +using System.Reflection.Emit; +using System.Runtime.InteropServices; + +using IKVM.CoreLib.Reflection; + +namespace IKVM.CoreLib.Symbols.Emit +{ + + abstract class TypeSymbolBuilderBase : ITypeSymbolBuilder + { + + const BindingFlags DefaultBindingFlags = BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance; + + readonly ISymbolContext _context; + readonly IModuleSymbolBuilder _module; + + string _name; + TypeAttributes _attributes; + ITypeSymbol? _parentType; + ImmutableList _genericTypeParameters = ImmutableList.Empty; + ImmutableList _interfaces = ImmutableList.Empty; + ImmutableList _fields = ImmutableList.Empty; + ImmutableList _constructors = ImmutableList.Empty; + ImmutableList _methods = ImmutableList.Empty; + ImmutableList<(IMethodSymbol, IMethodSymbol)> _methodOverrides = ImmutableList<(IMethodSymbol, IMethodSymbol)>.Empty; + ImmutableList _properties = ImmutableList.Empty; + ImmutableList _events = ImmutableList.Empty; + ImmutableList _customAttributes = ImmutableList.Empty; + + /// + /// Initializes a new instance. + /// + /// + /// + public TypeSymbolBuilderBase(ISymbolContext context, IModuleSymbolBuilder module, TypeAttributes attributes) + { + _context = context ?? throw new ArgumentNullException(nameof(context)); + _module = module ?? throw new ArgumentNullException(nameof(module)); + _attributes = attributes; + } + + /// + public ISymbolContext Context => _context; + + /// + public IModuleSymbolBuilder ResolvingModuleBuilder => _module; + + #region ITypeSymbolBuilder + + /// + public void SetParent(ITypeSymbol? parent) + { + _parentType = parent; + } + + /// + public IImmutableList DefineGenericParameters(IImmutableList names) + { + if (names.Count >= 1 && _genericTypeParameters.IsEmpty == false) + throw new InvalidOperationException("Generic parameters already defined."); + + var a = ImmutableList.Create(); + for (int i = 0; i < names.Count; i++) + a = a.Add(CreateGenericParameter(names[i])); + + return _genericTypeParameters = a; + } + + /// + /// Override this method to implement the creation of a . + /// + /// + /// + protected abstract IGenericTypeParameterSymbolBuilder CreateGenericParameter(string name); + + /// + public void AddInterfaceImplementation(ITypeSymbol interfaceType) + { + _interfaces = _interfaces.Add(interfaceType); + } + + /// + /// Override this method to implement the creation of a . + /// + /// + /// + /// + /// + /// + /// + /// + public IConstructorSymbolBuilder DefineConstructor(MethodAttributes attributes, CallingConventions callingConvention, IImmutableList parameterTypes, IImmutableList> requiredCustomModifiers, IImmutableList> optionalCustomModifiers) + { + var constructor = CreateConstructorBuilder(attributes, callingConvention, parameterTypes, requiredCustomModifiers, optionalCustomModifiers); + _constructors = _constructors.Add(constructor); + return constructor; + } + + /// + /// Override this method to implement the creation of a . + /// + /// + /// + /// + /// + /// + /// + protected abstract IConstructorSymbolBuilder CreateConstructorBuilder(MethodAttributes attributes, CallingConventions callingConvention, IImmutableList parameterTypes, IImmutableList> requiredCustomModifiers, IImmutableList> optionalCustomModifiers); + + /// + public IConstructorSymbolBuilder DefineConstructor(MethodAttributes attributes, IImmutableList parameterTypes) + { + var constructor = CreateConstructorBuilder(attributes, parameterTypes); + _constructors = _constructors.Add(constructor); + return constructor; + } + + /// + /// Override this method to implement the creation of a . + /// + /// + /// + /// + protected abstract IConstructorSymbolBuilder CreateConstructorBuilder(MethodAttributes attributes, IImmutableList parameterTypes); + + /// + public IConstructorSymbolBuilder DefineConstructor(MethodAttributes attributes, CallingConventions callingConvention, IImmutableList parameterTypes) + { + var constructor = CreateConstructorBuilder(attributes, callingConvention, parameterTypes); + _constructors = _constructors.Add(constructor); + return constructor; + } + + /// + /// Override this method to implement the creation of a . + /// + /// + /// + /// + /// + protected abstract IConstructorSymbolBuilder CreateConstructorBuilder(MethodAttributes attributes, CallingConventions callingConvention, IImmutableList parameterTypes); + + /// + public IConstructorSymbolBuilder DefineConstructor(MethodAttributes attributes, CallingConventions callingConvention, IImmutableList parameterTypes, IImmutableList> requiredCustomModifiers, ImmutableArray> optionalCustomModifiers) + { + var constructor = CreateConstructorBuilder(attributes, callingConvention, parameterTypes, requiredCustomModifiers, optionalCustomModifiers); + _constructors = _constructors.Add(constructor); + return constructor; + } + + /// + /// Override this method to implement the creation of a . + /// + /// + /// + /// + /// + /// + /// + protected abstract IConstructorSymbolBuilder CreateConstructorBuilder(MethodAttributes attributes, CallingConventions callingConvention, IImmutableList parameterTypes, IImmutableList> requiredCustomModifiers, ImmutableArray> optionalCustomModifiers); + + /// + public IConstructorSymbolBuilder DefineDefaultConstructor(MethodAttributes attributes) + { + var constructor = CreateConstructorBuilder(attributes); + _constructors = _constructors.Add(constructor); + return constructor; + } + + /// + /// Override this method to implement the creation of a . + /// + /// + /// + protected abstract IConstructorSymbolBuilder CreateConstructorBuilder(MethodAttributes attributes); + + /// + public IEventSymbolBuilder DefineEvent(string name, EventAttributes attributes, ITypeSymbol eventtype) + { + var @event = CreateEventBuilder(name, attributes, eventtype); + _events = _events.Add(@event); + return @event; + } + + /// + /// Override this method to implement the creation of a . + /// + /// + /// + /// + /// + protected abstract IEventSymbolBuilder CreateEventBuilder(string name, EventAttributes attributes, ITypeSymbol eventtype); + + /// + public IFieldSymbolBuilder DefineField(string fieldName, ITypeSymbol type, FieldAttributes attributes) + { + var field = CreateFieldBuilder(fieldName, type, attributes); + _fields = _fields.Add(field); + return field; + } + + /// + /// Override this method to implement the creation of a . + /// + /// + /// + /// + /// + protected abstract IFieldSymbolBuilder CreateFieldBuilder(string fieldName, ITypeSymbol type, FieldAttributes attributes); + + /// + public IFieldSymbolBuilder DefineField(string fieldName, ITypeSymbol type, IImmutableList requiredCustomModifiers, IImmutableList optionalCustomModifiers, FieldAttributes attributes) + { + var field = CreateFieldBuilder(fieldName, type, requiredCustomModifiers, optionalCustomModifiers, attributes); + _fields = _fields.Add(field); + return field; + } + + /// + /// + /// Override this method to implement the creation of a . + /// + /// + /// + /// + /// + /// + /// + protected abstract IFieldSymbolBuilder CreateFieldBuilder(string fieldName, ITypeSymbol type, IImmutableList requiredCustomModifiers, IImmutableList optionalCustomModifiers, FieldAttributes attributes); + + /// + public IMethodSymbolBuilder DefineMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, IImmutableList returnTypeRequiredCustomModifiers, IImmutableList returnTypeOptionalCustomModifiers, IImmutableList parameterTypes, IImmutableList> parameterTypeRequiredCustomModifiers, IImmutableList> parameterTypeOptionalCustomModifiers) + { + var method = CreateMethodBuilder(name, attributes, callingConvention, returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers); + _methods = _methods.Add(method); + return method; + } + + /// + /// Override this method to implement the creation of a . + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + protected abstract IMethodSymbolBuilder CreateMethodBuilder(string name, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, IImmutableList returnTypeRequiredCustomModifiers, IImmutableList returnTypeOptionalCustomModifiers, IImmutableList parameterTypes, IImmutableList> parameterTypeRequiredCustomModifiers, IImmutableList> parameterTypeOptionalCustomModifiers); + + /// + public IMethodSymbolBuilder DefineMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, IImmutableList parameterTypes) + { + var method = CreateMethodBuilder(name, attributes, callingConvention, returnType, parameterTypes); + _methods = _methods.Add(method); + return method; + } + + /// + /// Override this method to implement the creation of a . + /// + /// + /// + /// + /// + /// + /// + protected abstract IMethodSymbolBuilder CreateMethodBuilder(string name, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, IImmutableList parameterTypes); + + /// + public IMethodSymbolBuilder DefineMethod(string name, MethodAttributes attributes, CallingConventions callingConvention) + { + var method = CreateMethodBuilder(name, attributes, callingConvention); + _methods = _methods.Add(method); + return method; + } + + /// + /// Override this method to implement the creation of a . + /// + /// + /// + /// + /// + protected abstract IMethodSymbolBuilder CreateMethodBuilder(string name, MethodAttributes attributes, CallingConventions callingConvention); + + /// + public IMethodSymbolBuilder DefineMethod(string name, MethodAttributes attributes) + { + var method = CreateMethodBuilder(name, attributes); + _methods = _methods.Add(method); + return method; + } + + /// + /// Override this method to implement the creation of a . + /// + /// + /// + /// + protected abstract IMethodSymbolBuilder CreateMethodBuilder(string name, MethodAttributes attributes); + + /// + public IMethodSymbolBuilder DefineMethod(string name, MethodAttributes attributes, ITypeSymbol? returnType, IImmutableList parameterTypes) + { + var method = CreateMethodBuilder(name, attributes, returnType, parameterTypes); + _methods = _methods.Add(method); + return method; + } + + /// + /// Override this method to implement the creation of a . + /// + /// + /// + /// + /// + /// + protected abstract IMethodSymbolBuilder CreateMethodBuilder(string name, MethodAttributes attributes, ITypeSymbol? returnType, IImmutableList parameterTypes); + + /// + public void DefineMethodOverride(IMethodSymbol methodInfoBody, IMethodSymbol methodInfoDeclaration) + { + _methodOverrides = _methodOverrides.Add((methodInfoBody, methodInfoDeclaration)); + } + + /// + public ITypeSymbolBuilder DefineNestedType(string name) + { + return _module.DefineNestedType(this, name); + } + + /// + public ITypeSymbolBuilder DefineNestedType(string name, TypeAttributes attr) + { + return _module.DefineNestedType(this, name, attr); + } + + /// + public ITypeSymbolBuilder DefineNestedType(string name, TypeAttributes attr, ITypeSymbol? parent) + { + return _module.DefineNestedType(this, name, attr, parent); + } + + /// + public ITypeSymbolBuilder DefineNestedType(string name, TypeAttributes attr, ITypeSymbol? parent, IImmutableList interfaces) + { + return _module.DefineNestedType(this, name, attr, parent, interfaces); + } + + /// + public ITypeSymbolBuilder DefineNestedType(string name, TypeAttributes attr, ITypeSymbol? parent, int typeSize) + { + return _module.DefineNestedType(this, name, attr, parent, typeSize); + } + + /// + public ITypeSymbolBuilder DefineNestedType(string name, TypeAttributes attr, ITypeSymbol? parent, PackingSize packSize) + { + return _module.DefineNestedType(this, name, attr, parent, packSize); + } + + /// + public ITypeSymbolBuilder DefineNestedType(string name, TypeAttributes attr, ITypeSymbol? parent, PackingSize packSize, int typeSize) + { + return _module.DefineNestedType(this, name, attr, parent, packSize, typeSize); + } + + /// + public IMethodSymbolBuilder DefinePInvokeMethod(string name, string dllName, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, IImmutableList parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet) + { + var method = CreatePInvokeMethodBuilder(name, dllName, attributes, callingConvention, returnType, parameterTypes, nativeCallConv, nativeCharSet); + _methods = _methods.Add(method); + return method; + } + + protected abstract IMethodSymbolBuilder CreatePInvokeMethodBuilder(string name, string dllName, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, IImmutableList parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet); + + /// + public IMethodSymbolBuilder DefinePInvokeMethod(string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, IImmutableList parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet) + { + var method = CreatePInvokeMethodBuilder(name, dllName, entryName, attributes, callingConvention, returnType, parameterTypes, nativeCallConv, nativeCharSet); + _methods = _methods.Add(method); + return method; + } + + protected abstract IMethodSymbolBuilder CreatePInvokeMethodBuilder(string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, IImmutableList parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet); + + /// + public IMethodSymbolBuilder DefinePInvokeMethod(string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, IImmutableList returnTypeRequiredCustomModifiers, IImmutableList returnTypeOptionalCustomModifiers, IImmutableList parameterTypes, IImmutableList> parameterTypeRequiredCustomModifiers, IImmutableList> parameterTypeOptionalCustomModifiers, CallingConvention nativeCallConv, CharSet nativeCharSet) + { + var method = CreatePInvokeMethodBuilder(name, dllName, entryName, attributes, callingConvention, returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers, nativeCallConv, nativeCharSet); + _methods = _methods.Add(method); + return method; + } + + protected abstract IMethodSymbolBuilder CreatePInvokeMethodBuilder(string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, IImmutableList returnTypeRequiredCustomModifiers, IImmutableList returnTypeOptionalCustomModifiers, IImmutableList parameterTypes, IImmutableList> parameterTypeRequiredCustomModifiers, IImmutableList> parameterTypeOptionalCustomModifiers, CallingConvention nativeCallConv, CharSet nativeCharSet); + + /// + public IPropertySymbolBuilder DefineProperty(string name, PropertyAttributes attributes, ITypeSymbol returnType, IImmutableList parameterTypes) + { + var property = CreatePropertyBuilder(name, attributes, returnType, parameterTypes); + _properties = _properties.Add(property); + return property; + } + + protected abstract IPropertySymbolBuilder CreatePropertyBuilder(string name, PropertyAttributes attributes, ITypeSymbol returnType, IImmutableList parameterTypes); + + /// + public IPropertySymbolBuilder DefineProperty(string name, PropertyAttributes attributes, CallingConventions callingConvention, ITypeSymbol returnType, IImmutableList parameterTypes) + { + var property = CreatePropertyBuilder(name, attributes, callingConvention, returnType, parameterTypes); + _properties = _properties.Add(property); + return property; + } + + protected abstract IPropertySymbolBuilder CreatePropertyBuilder(string name, PropertyAttributes attributes, CallingConventions callingConvention, ITypeSymbol returnType, IImmutableList parameterTypes); + + /// + public IPropertySymbolBuilder DefineProperty(string name, PropertyAttributes attributes, ITypeSymbol returnType, IImmutableList returnTypeRequiredCustomModifiers, IImmutableList returnTypeOptionalCustomModifiers, IImmutableList parameterTypes, IImmutableList> parameterTypeRequiredCustomModifiers, IImmutableList> parameterTypeOptionalCustomModifiers) + { + var property = CreatePropertyBuilder(name, attributes, returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers); + _properties = _properties.Add(property); + return property; + } + + protected abstract IPropertySymbolBuilder CreatePropertyBuilder(string name, PropertyAttributes attributes, ITypeSymbol returnType, IImmutableList returnTypeRequiredCustomModifiers, IImmutableList returnTypeOptionalCustomModifiers, IImmutableList parameterTypes, IImmutableList> parameterTypeRequiredCustomModifiers, IImmutableList> parameterTypeOptionalCustomModifiers); + + /// + public IPropertySymbolBuilder DefineProperty(string name, PropertyAttributes attributes, CallingConventions callingConvention, ITypeSymbol returnType, IImmutableList returnTypeRequiredCustomModifiers, IImmutableList returnTypeOptionalCustomModifiers, IImmutableList parameterTypes, IImmutableList> parameterTypeRequiredCustomModifiers, IImmutableList> parameterTypeOptionalCustomModifiers) + { + var property = CreatePropertyBuilder(name, attributes, callingConvention, returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers); + _properties = _properties.Add(property); + return property; + } + + protected abstract IPropertySymbolBuilder CreatePropertyBuilder(string name, PropertyAttributes attributes, CallingConventions callingConvention, ITypeSymbol returnType, IImmutableList returnTypeRequiredCustomModifiers, IImmutableList returnTypeOptionalCustomModifiers, IImmutableList parameterTypes, IImmutableList> parameterTypeRequiredCustomModifiers, IImmutableList> parameterTypeOptionalCustomModifiers); + + /// + public IConstructorSymbolBuilder DefineTypeInitializer() + { + var constructor = CreateTypeInitializerBuilder(); + _constructors = _constructors.Add(constructor); + return constructor; + } + + protected abstract IConstructorSymbolBuilder CreateTypeInitializerBuilder(); + + #endregion + + #region ICustomAttributeProviderBuilder + + /// + public void SetCustomAttribute(CustomAttribute attribute) + { + _customAttributes = _customAttributes.Add(attribute); + } + + #endregion + + #region ITypeSymbol + + public void Foo() + { + System.Reflection.Metadata.TypeName t; + } + + public TypeAttributes Attributes => _attributes; + + public IAssemblySymbol Assembly => _module.Assembly; + + public IMethodBaseSymbol? DeclaringMethod => null; + + public string? AssemblyQualifiedName => System.Reflection.Assembly.CreateQualifiedName(Assembly.FullName, FullName); + + public string? FullName => _name; + + public string? Namespace => throw new NotImplementedException(); + + public TypeCode TypeCode => throw new NotImplementedException(); + + public ITypeSymbol? BaseType => throw new NotImplementedException(); + + public bool ContainsGenericParameters => throw new NotImplementedException(); + + public GenericParameterAttributes GenericParameterAttributes => throw new NotImplementedException(); + + public int GenericParameterPosition => throw new NotImplementedException(); + + public IImmutableList GenericTypeArguments => throw new NotImplementedException(); + + public bool IsConstructedGenericType => throw new NotImplementedException(); + + public bool IsGenericType => throw new NotImplementedException(); + + public bool IsGenericTypeDefinition => throw new NotImplementedException(); + + public bool IsGenericParameter => throw new NotImplementedException(); + + public bool IsAutoLayout => throw new NotImplementedException(); + + public bool IsExplicitLayout => throw new NotImplementedException(); + + public bool IsLayoutSequential => throw new NotImplementedException(); + + public bool HasElementType => throw new NotImplementedException(); + + public bool IsClass => throw new NotImplementedException(); + + public bool IsValueType => throw new NotImplementedException(); + + public bool IsInterface => throw new NotImplementedException(); + + public bool IsPrimitive => throw new NotImplementedException(); + + public bool IsSZArray => throw new NotImplementedException(); + + public bool IsArray => throw new NotImplementedException(); + + public bool IsEnum => throw new NotImplementedException(); + + public bool IsPointer => throw new NotImplementedException(); + + public bool IsFunctionPointer => throw new NotImplementedException(); + + public bool IsUnmanagedFunctionPointer => throw new NotImplementedException(); + + public bool IsByRef => throw new NotImplementedException(); + + public bool IsAbstract => throw new NotImplementedException(); + + public bool IsSealed => throw new NotImplementedException(); + + public bool IsVisible => throw new NotImplementedException(); + + public bool IsPublic => throw new NotImplementedException(); + + public bool IsNotPublic => throw new NotImplementedException(); + + public bool IsNested => throw new NotImplementedException(); + + public bool IsNestedAssembly => throw new NotImplementedException(); + + public bool IsNestedFamANDAssem => throw new NotImplementedException(); + + public bool IsNestedFamily => throw new NotImplementedException(); + + public bool IsNestedFamORAssem => throw new NotImplementedException(); + + public bool IsNestedPrivate => throw new NotImplementedException(); + + public bool IsNestedPublic => throw new NotImplementedException(); + + public bool IsSerializable => throw new NotImplementedException(); + + public bool IsSignatureType => throw new NotImplementedException(); + + public bool IsSpecialName => throw new NotImplementedException(); + + public IConstructorSymbol? TypeInitializer => throw new NotImplementedException(); + + public IModuleSymbol Module => throw new NotImplementedException(); + + public ITypeSymbol? DeclaringType => throw new NotImplementedException(); + + public MemberTypes MemberType => throw new NotImplementedException(); + + public int MetadataToken => throw new NotImplementedException(); + + public string Name => throw new NotImplementedException(); + + public bool IsMissing => throw new NotImplementedException(); + + public bool ContainsMissing => throw new NotImplementedException(); + + public bool IsComplete => throw new NotImplementedException(); + + public int GetArrayRank() + { + throw new NotImplementedException(); + } + + public IImmutableList GetDefaultMembers() + { + throw new NotImplementedException(); + } + + public ITypeSymbol? GetElementType() + { + throw new NotImplementedException(); + } + + public string? GetEnumName(object value) + { + throw new NotImplementedException(); + } + + public IImmutableList GetEnumNames() + { + throw new NotImplementedException(); + } + + public ITypeSymbol GetEnumUnderlyingType() + { + throw new NotImplementedException(); + } + + public IImmutableList GetGenericArguments() + { + throw new NotImplementedException(); + } + + public IImmutableList GetGenericParameterConstraints() + { + throw new NotImplementedException(); + } + + public ITypeSymbol GetGenericTypeDefinition() + { + throw new NotImplementedException(); + } + + public ITypeSymbol? GetInterface(string name) + { + throw new NotImplementedException(); + } + + public ITypeSymbol? GetInterface(string name, bool ignoreCase) + { + throw new NotImplementedException(); + } + + public IImmutableList GetInterfaces(bool inherit = true) + { + throw new NotImplementedException(); + } + + public InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) + { + throw new NotImplementedException(); + } + + public IImmutableList GetDeclaredConstructors() + { + throw new NotImplementedException(); + } + + public IConstructorSymbol? GetConstructor(IImmutableList types) + { + throw new NotImplementedException(); + } + + public IConstructorSymbol? GetConstructor(BindingFlags bindingFlags, IImmutableList types) + { + throw new NotImplementedException(); + } + + public IImmutableList GetConstructors() + { + throw new NotImplementedException(); + } + + public IImmutableList GetConstructors(BindingFlags bindingFlags) + { + throw new NotImplementedException(); + } + + public IFieldSymbol? GetField(string name) + { + throw new NotImplementedException(); + } + + public IFieldSymbol? GetField(string name, BindingFlags bindingFlags) + { + throw new NotImplementedException(); + } + + public IImmutableList GetFields() + { + throw new NotImplementedException(); + } + + public IImmutableList GetFields(BindingFlags bindingFlags) + { + throw new NotImplementedException(); + } + + public IImmutableList GetDeclaredMethods() + { + throw new NotImplementedException(); + } + + /// + public IMethodSymbol? GetMethod(string name) + { + return SymbolUtil.SelectMethod(this, DefaultBindingFlags, name, null, null); + } + + /// + public IMethodSymbol? GetMethod(string name, BindingFlags bindingFlags, IImmutableList? types, IImmutableList? modifiers) + { + return SymbolUtil.SelectMethod(this, DefaultBindingFlags, name, types, modifiers); + } + + public IMethodSymbol? GetMethod(string name, IImmutableList types) + { + throw new NotImplementedException(); + } + + public IMethodSymbol? GetMethod(string name, BindingFlags bindingFlags) + { + throw new NotImplementedException(); + } + + public IMethodSymbol? GetMethod(string name, BindingFlags bindingFlags, IImmutableList types) + { + throw new NotImplementedException(); + } + + public IMethodSymbol? GetMethod(string name, BindingFlags bindingFlags, CallingConventions callConvention, IImmutableList types, IImmutableList modifiers) + { + throw new NotImplementedException(); + } + + public IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingFlags, CallingConventions callConvention, IImmutableList types, IImmutableList modifiers) + { + throw new NotImplementedException(); + } + + public IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingFlags, IImmutableList types, IImmutableList modifiers) + { + throw new NotImplementedException(); + } + + public IMethodSymbol? GetMethod(string name, int genericParameterCount, IImmutableList types, IImmutableList modifiers) + { + throw new NotImplementedException(); + } + + /// + public IImmutableList GetMethods() + { + return SymbolUtil.SelectMethods(this, DefaultBindingFlags, null, null, null); + } + + /// + public IImmutableList GetMethods(BindingFlags bindingFlags) + { + return SymbolUtil.SelectMethods(this, bindingFlags, null, null, null); + } + + public IImmutableList GetDeclaredProperties() + { + throw new NotImplementedException(); + } + + public IPropertySymbol? GetProperty(string name) + { + throw new NotImplementedException(); + } + + public IPropertySymbol? GetProperty(string name, BindingFlags bindingFlags) + { + throw new NotImplementedException(); + } + + public IPropertySymbol? GetProperty(string name, IImmutableList types) + { + throw new NotImplementedException(); + } + + public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, IImmutableList types) + { + throw new NotImplementedException(); + } + + public IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType) + { + throw new NotImplementedException(); + } + + public IImmutableList GetProperties() + { + throw new NotImplementedException(); + } + + public IImmutableList GetProperties(BindingFlags bindingFlags) + { + throw new NotImplementedException(); + } + + public IImmutableList GetDeclaredEvents() + { + throw new NotImplementedException(); + } + + public IEventSymbol? GetEvent(string name) + { + throw new NotImplementedException(); + } + + public IEventSymbol? GetEvent(string name, BindingFlags bindingFlags) + { + throw new NotImplementedException(); + } + + public IImmutableList GetEvents() + { + throw new NotImplementedException(); + } + + public IImmutableList GetEvents(BindingFlags bindingFlags) + { + throw new NotImplementedException(); + } + + public ITypeSymbol? GetNestedType(string name) + { + throw new NotImplementedException(); + } + + public ITypeSymbol? GetNestedType(string name, BindingFlags bindingFlags) + { + throw new NotImplementedException(); + } + + public IImmutableList GetNestedTypes() + { + throw new NotImplementedException(); + } + + public IImmutableList GetNestedTypes(BindingFlags bindingFlags) + { + throw new NotImplementedException(); + } + + public bool IsAssignableFrom(ITypeSymbol? c) + { + throw new NotImplementedException(); + } + + public bool IsSubclassOf(ITypeSymbol c) + { + throw new NotImplementedException(); + } + + public bool IsEnumDefined(object value) + { + throw new NotImplementedException(); + } + + public ITypeSymbol MakeArrayType() + { + throw new NotImplementedException(); + } + + public ITypeSymbol MakeArrayType(int rank) + { + throw new NotImplementedException(); + } + + public ITypeSymbol MakeGenericType(IImmutableList typeArguments) + { + throw new NotImplementedException(); + } + + public ITypeSymbol MakePointerType() + { + throw new NotImplementedException(); + } + + public ITypeSymbol MakeByRefType() + { + throw new NotImplementedException(); + } + + CustomAttribute[] ICustomAttributeProvider.GetCustomAttributes(bool inherit) + { + throw new NotImplementedException(); + } + + public bool IsDefined(ITypeSymbol attributeType, bool inherit = false) + { + throw new NotImplementedException(); + } + + #endregion + + #region ICustomAttributeProvider + + /// + public override IImmutableList GetCustomAttributes(bool inherit = false) + { + if (inherit == false || BaseType == null) + return _customAttributes?.ToArray() ?? []; + else + return Enumerable.Concat(_customAttributes?.ToArray() ?? [], ResolveCustomAttributes(BaseType.Unpack().GetInheritedCustomAttributesData())).ToArray(); + } + + /// + public override CustomAttribute? GetCustomAttribute(ITypeSymbol attributeType, bool inherit = false) + { + return GetCustomAttributes(inherit).FirstOrDefault(i => i.AttributeType == attributeType); + } + + /// + public override CustomAttribute[] GetCustomAttributes(ITypeSymbol attributeType, bool inherit = false) + { + return GetCustomAttributes(inherit).Where(i => i.AttributeType == attributeType).ToArray(); + } + + #endregion + + /// + public void Complete() + { + if (_builder != null) + { + // complete type + if (_builder.IsCreated() == false) + { + _type = _builder.CreateType() ?? throw new InvalidOperationException(); + _methods = null; + _customAttributes = null; + } + + // force module to reresolve + Context.GetOrCreateModuleSymbol(ResolvingModule.UnderlyingModule); + OnComplete(); + } + } + + /// + public void OnComplete() + { + const BindingFlags DefaultBindingFlags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static; + + // apply the runtime generic type parameters and pass them to the symbols for completion + var srcGenericArgs = UnderlyingRuntimeType.GetGenericArguments() ?? []; + var dstGenericArgs = GetGenericArguments() ?? []; + Debug.Assert(srcGenericArgs.Length == dstGenericArgs.Length); + for (int i = 0; i < srcGenericArgs.Length; i++) + if (dstGenericArgs[i] is IReflectionGenericTypeParameterSymbolBuilder b) + b.OnComplete(srcGenericArgs[i]); + + foreach (var i in GetConstructors(DefaultBindingFlags) ?? []) + if (i is IReflectionConstructorSymbolBuilder b) + b.OnComplete(); + + foreach (var i in GetMethods(DefaultBindingFlags) ?? []) + if (i is IReflectionMethodSymbolBuilder b) + b.OnComplete(); + + foreach (var i in GetFields(DefaultBindingFlags) ?? []) + if (i is IReflectionFieldSymbolBuilder b) + b.OnComplete(); + + foreach (var i in GetProperties(DefaultBindingFlags) ?? []) + if (i is IReflectionPropertySymbolBuilder b) + b.OnComplete(); + + foreach (var m in GetEvents(DefaultBindingFlags) ?? []) + if (m is IReflectionPropertySymbolBuilder b) + b.OnComplete(); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/IMethodBaseSymbol.cs b/src/IKVM.CoreLib/Symbols/IMethodBaseSymbol.cs index 00b6144a0..99c9a7473 100644 --- a/src/IKVM.CoreLib/Symbols/IMethodBaseSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IMethodBaseSymbol.cs @@ -1,4 +1,5 @@ -using System.Reflection; +using System.Collections.Immutable; +using System.Reflection; namespace IKVM.CoreLib.Symbols { @@ -108,13 +109,13 @@ interface IMethodBaseSymbol : IMemberSymbol /// Returns an array of objects that represent the type arguments of a generic method or the type parameters of a generic method definition. /// /// - ITypeSymbol[] GetGenericArguments(); + ImmutableArray GetGenericArguments(); /// /// When overridden in a derived class, gets the parameters of the specified method or constructor. /// /// - IParameterSymbol[] GetParameters(); + ImmutableArray GetParameters(); /// /// When overridden in a derived class, returns the MethodImplAttributes flags. diff --git a/src/IKVM.CoreLib/Symbols/ITypeSymbol.cs b/src/IKVM.CoreLib/Symbols/ITypeSymbol.cs index 21926c44b..47f1d6532 100644 --- a/src/IKVM.CoreLib/Symbols/ITypeSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/ITypeSymbol.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Collections.Immutable; using System.Reflection; namespace IKVM.CoreLib.Symbols @@ -68,7 +70,7 @@ interface ITypeSymbol : IMemberSymbol /// /// Gets an array of the generic type arguments for this type. /// - ITypeSymbol[] GenericTypeArguments { get; } + IImmutableList GenericTypeArguments { get; } /// /// Gets a value that indicates whether this object represents a constructed generic type. You can create instances of a constructed generic type. @@ -255,7 +257,7 @@ interface ITypeSymbol : IMemberSymbol /// Searches for the members defined for the current whose DefaultMemberAttribute is set. /// /// - IMemberSymbol[] GetDefaultMembers(); + IImmutableList GetDefaultMembers(); /// /// When overridden in a derived class, returns the of the object encompassed or referred to by the current array, pointer or reference type. @@ -274,7 +276,7 @@ interface ITypeSymbol : IMemberSymbol /// Returns the names of the members of the current enumeration type. /// /// - string[] GetEnumNames(); + IImmutableList GetEnumNames(); /// /// Returns the underlying type of the current enumeration type. @@ -286,13 +288,13 @@ interface ITypeSymbol : IMemberSymbol /// Returns an array of objects that represent the type arguments of a closed generic type or the type parameters of a generic type definition. /// /// - ITypeSymbol[] GetGenericArguments(); + IImmutableList GetGenericArguments(); /// /// Returns an array of objects that represent the constraints on the current generic type parameter. /// /// - ITypeSymbol[] GetGenericParameterConstraints(); + IImmutableList GetGenericParameterConstraints(); /// /// Returns a object that represents a generic type definition from which the current generic type can be constructed. @@ -319,7 +321,7 @@ interface ITypeSymbol : IMemberSymbol /// When overridden in a derived class, gets all the interfaces implemented or if specified,inherited by the current . /// /// - ITypeSymbol[] GetInterfaces(bool inherit = true); + IImmutableList GetInterfaces(bool inherit = true); /// /// Returns an interface mapping for the specified interface type. @@ -329,69 +331,38 @@ interface ITypeSymbol : IMemberSymbol InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType); /// - /// Searches for the public members with the specified name. + /// Returns all the declared constructors of the current . /// - /// - /// - IMemberSymbol[] GetMember(string name); - - /// - /// Searches for the specified members, using the specified binding constraints. - /// - /// - /// - /// - IMemberSymbol[] GetMember(string name, BindingFlags bindingAttr); - - /// - /// Searches for the specified members of the specified member type, using the specified binding constraints. - /// - /// - /// - /// /// - IMemberSymbol[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr); - - /// - /// Returns all the public members of the current . - /// - /// - IMemberSymbol[] GetMembers(); - - /// - /// When overridden in a derived class, searches for the members defined for the current , using the specified binding constraints. - /// - /// - /// - IMemberSymbol[] GetMembers(BindingFlags bindingAttr); + IImmutableList GetDeclaredConstructors(); /// /// Searches for a public instance constructor whose parameters match the types in the specified array. /// /// /// - IConstructorSymbol? GetConstructor(ITypeSymbol[] types); + IConstructorSymbol? GetConstructor(IImmutableList types); /// /// Searches for a constructor whose parameters match the specified argument types, using the specified binding constraints. /// - /// + /// /// /// - IConstructorSymbol? GetConstructor(BindingFlags bindingAttr, ITypeSymbol[] types); + IConstructorSymbol? GetConstructor(BindingFlags bindingFlags, IImmutableList types); /// /// Returns all the public constructors defined for the current . /// /// - IConstructorSymbol[] GetConstructors(); + IImmutableList GetConstructors(); /// /// When overridden in a derived class, searches for the constructors defined for the current , using the specified BindingFlags. /// - /// + /// /// - IConstructorSymbol[] GetConstructors(BindingFlags bindingAttr); + IImmutableList GetConstructors(BindingFlags bindingFlags); /// /// Searches for the public field with the specified name. @@ -404,22 +375,28 @@ interface ITypeSymbol : IMemberSymbol /// Searches for the specified field, using the specified binding constraints. /// /// - /// + /// /// - IFieldSymbol? GetField(string name, BindingFlags bindingAttr); + IFieldSymbol? GetField(string name, BindingFlags bindingFlags); /// /// Returns all the public fields of the current . /// /// - IFieldSymbol[] GetFields(); + IImmutableList GetFields(); /// /// When overridden in a derived class, searches for the fields defined for the current , using the specified binding constraints. /// - /// + /// /// - IFieldSymbol[] GetFields(BindingFlags bindingAttr); + IImmutableList GetFields(BindingFlags bindingFlags); + + /// + /// Returns all the declared methods of the current . + /// + /// + IImmutableList GetDeclaredMethods(); /// /// Searches for the public method with the specified name. @@ -434,58 +411,58 @@ interface ITypeSymbol : IMemberSymbol /// /// /// - IMethodSymbol? GetMethod(string name, ITypeSymbol[] types); + IMethodSymbol? GetMethod(string name, IImmutableList types); /// /// Searches for the specified method, using the specified binding constraints. /// /// - /// + /// /// - IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr); + IMethodSymbol? GetMethod(string name, BindingFlags bindingFlags); /// /// Searches for the specified method whose parameters match the specified argument types, using the specified binding constraints. /// /// - /// + /// /// /// - IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types); + IMethodSymbol? GetMethod(string name, BindingFlags bindingFlags, IImmutableList types); /// /// Searches for the specified method whose parameters match the specified argument types and modifiers, using the specified binding constraints and the specified calling convention. /// /// - /// + /// /// /// /// /// - IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers); + IMethodSymbol? GetMethod(string name, BindingFlags bindingFlags, CallingConventions callConvention, IImmutableList types, IImmutableList modifiers); /// /// Searches for the specified method whose parameters match the specified generic parameter count, argument types and modifiers, using the specified binding constraints and the specified calling convention. /// /// /// - /// + /// /// /// /// /// - IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers); + IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingFlags, CallingConventions callConvention, IImmutableList types, IImmutableList modifiers); /// /// Searches for the specified method whose parameters match the specified generic parameter count, argument types and modifiers, using the specified binding constraints. /// /// /// - /// + /// /// /// /// - IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, ITypeSymbol[] types, ParameterModifier[]? modifiers); + IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingFlags, IImmutableList types, IImmutableList modifiers); /// /// Searches for the specified method whose parameters match the specified argument types and modifiers, using the specified binding constraints. @@ -495,7 +472,7 @@ interface ITypeSymbol : IMemberSymbol /// /// /// - IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types, ParameterModifier[]? modifiers); + IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, IImmutableList types, IImmutableList modifiers); /// /// Searches for the specified public method whose parameters match the specified generic parameter count, argument types and modifiers. @@ -505,20 +482,26 @@ interface ITypeSymbol : IMemberSymbol /// /// /// - IMethodSymbol? GetMethod(string name, int genericParameterCount, ITypeSymbol[] types, ParameterModifier[]? modifiers); + IMethodSymbol? GetMethod(string name, int genericParameterCount, IImmutableList types, IImmutableList modifiers); /// /// Returns all the public methods of the current . /// /// - IMethodSymbol[] GetMethods(); + IImmutableList GetMethods(); /// /// When overridden in a derived class, searches for the methods defined for the current , using the specified binding constraints. /// - /// + /// /// - IMethodSymbol[] GetMethods(BindingFlags bindingAttr); + IImmutableList GetMethods(BindingFlags bindingFlags); + + /// + /// Returns all the declared properties of the current . + /// + /// + IImmutableList GetDeclaredProperties(); /// /// Searches for the public property with the specified name. @@ -531,9 +514,9 @@ interface ITypeSymbol : IMemberSymbol /// Searches for the specified property, using the specified binding constraints. /// /// - /// + /// /// - IPropertySymbol? GetProperty(string name, BindingFlags bindingAttr); + IPropertySymbol? GetProperty(string name, BindingFlags bindingFlags); /// /// Searches for the specified public property whose parameters match the specified argument types. @@ -541,7 +524,7 @@ interface ITypeSymbol : IMemberSymbol /// /// /// - IPropertySymbol? GetProperty(string name, ITypeSymbol[] types); + IPropertySymbol? GetProperty(string name, IImmutableList types); /// /// Searches for the specified public property whose parameters match the specified argument types. @@ -550,7 +533,7 @@ interface ITypeSymbol : IMemberSymbol /// /// /// - IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types); + IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, IImmutableList types); /// /// Searches for the public property with the specified name and return type. @@ -564,42 +547,48 @@ interface ITypeSymbol : IMemberSymbol /// Returns all the public properties of the current . /// /// - IPropertySymbol[] GetProperties(); + IImmutableList GetProperties(); /// /// When overridden in a derived class, searches for the properties of the current , using the specified binding constraints. /// - /// + /// + /// + IImmutableList GetProperties(BindingFlags bindingFlags); + + /// + /// Returns all the declared events of the current . + /// /// - IPropertySymbol[] GetProperties(BindingFlags bindingAttr); + IImmutableList GetDeclaredEvents(); /// - /// Returns the EventInfo object representing the specified public event. + /// Returns the object representing the specified public event. /// /// /// IEventSymbol? GetEvent(string name); /// - /// When overridden in a derived class, returns the EventInfo object representing the specified event, using the specified binding constraints. + /// When overridden in a derived class, returns the object representing the specified event, using the specified binding constraints. /// /// - /// + /// /// - IEventSymbol? GetEvent(string name, BindingFlags bindingAttr); + IEventSymbol? GetEvent(string name, BindingFlags bindingFlags); /// /// Returns all the public events that are declared or inherited by the current . /// /// - IEventSymbol[] GetEvents(); + IImmutableList GetEvents(); /// /// When overridden in a derived class, searches for events that are declared or inherited by the current , using the specified binding constraints. /// - /// + /// /// - IEventSymbol[] GetEvents(BindingFlags bindingAttr); + IImmutableList GetEvents(BindingFlags bindingFlags); /// /// Searches for the public nested type with the specified name. @@ -612,22 +601,22 @@ interface ITypeSymbol : IMemberSymbol /// When overridden in a derived class, searches for the specified nested type, using the specified binding constraints. /// /// - /// + /// /// - ITypeSymbol? GetNestedType(string name, BindingFlags bindingAttr); + ITypeSymbol? GetNestedType(string name, BindingFlags bindingFlags); /// /// Returns the public types nested in the current . /// /// - ITypeSymbol[] GetNestedTypes(); + IImmutableList GetNestedTypes(); /// /// When overridden in a derived class, searches for the types nested in the current , using the specified binding constraints. /// - /// + /// /// - ITypeSymbol[] GetNestedTypes(BindingFlags bindingAttr); + IImmutableList GetNestedTypes(BindingFlags bindingFlags); /// /// Determines whether an instance of a specified type c can be assigned to a variable of the current type. @@ -668,7 +657,7 @@ interface ITypeSymbol : IMemberSymbol /// /// /// - ITypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments); + ITypeSymbol MakeGenericType(IImmutableList typeArguments); /// /// Returns a object that represents a pointer to the current type. diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionGenericTypeParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionGenericTypeParameterSymbolBuilder.cs index ad8e18c99..a392b6062 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionGenericTypeParameterSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionGenericTypeParameterSymbolBuilder.cs @@ -486,19 +486,19 @@ public ITypeSymbol[] GetInterfaces(bool inherit = true) } /// - public IMemberSymbol[] GetMember(string name) + public IMemberSymbol[] GetMembers(string name) { return ResolveMemberSymbols(UnderlyingType.GetMember(name)); } /// - public IMemberSymbol[] GetMember(string name, System.Reflection.BindingFlags bindingAttr) + public IMemberSymbol[] GetMembers(string name, System.Reflection.BindingFlags bindingAttr) { return ResolveMemberSymbols(UnderlyingType.GetMember(name, (BindingFlags)bindingAttr)); } /// - public IMemberSymbol[] GetMember(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) + public IMemberSymbol[] GetMembers(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) { return ResolveMemberSymbols(UnderlyingType.GetMember(name, (MemberTypes)type, (BindingFlags)bindingAttr)); } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionTypeSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionTypeSymbolBuilder.cs index 376f463cc..948889034 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionTypeSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/Emit/IkvmReflectionTypeSymbolBuilder.cs @@ -687,19 +687,19 @@ public ITypeSymbol[] GetInterfaces(bool inherit = true) } /// - public IMemberSymbol[] GetMember(string name) + public IMemberSymbol[] GetMembers(string name) { return ResolveMemberSymbols(UnderlyingType.GetMember(name)); } /// - public IMemberSymbol[] GetMember(string name, System.Reflection.BindingFlags bindingAttr) + public IMemberSymbol[] GetMembers(string name, System.Reflection.BindingFlags bindingAttr) { return ResolveMemberSymbols(UnderlyingType.GetMember(name, (BindingFlags)bindingAttr)); } /// - public IMemberSymbol[] GetMember(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) + public IMemberSymbol[] GetMembers(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) { return ResolveMemberSymbols(UnderlyingType.GetMember(name, (MemberTypes)type, (BindingFlags)bindingAttr)); } @@ -815,7 +815,7 @@ IMethodSymbol[] GetIncompleteMethods(System.Reflection.BindingFlags bindingAttr if (_incompleteMethods == null) return []; else - return SymbolUtil.FilterMethods(this, _incompleteMethods, bindingAttr).Cast().ToArray(); + return SymbolUtil.SelectMethods(this, _incompleteMethods, bindingAttr).Cast().ToArray(); } /// diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionGenericTypeParameterSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionGenericTypeParameterSymbol.cs index 1b92b0131..5ab7b330b 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionGenericTypeParameterSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionGenericTypeParameterSymbol.cs @@ -436,19 +436,19 @@ public ITypeSymbol[] GetInterfaces(bool inherit = true) } /// - public IMemberSymbol[] GetMember(string name) + public IMemberSymbol[] GetMembers(string name) { return ResolveMemberSymbols(UnderlyingType.GetMember(name)); } /// - public IMemberSymbol[] GetMember(string name, System.Reflection.BindingFlags bindingAttr) + public IMemberSymbol[] GetMembers(string name, System.Reflection.BindingFlags bindingAttr) { return ResolveMemberSymbols(UnderlyingType.GetMember(name, (BindingFlags)bindingAttr)); } /// - public IMemberSymbol[] GetMember(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) + public IMemberSymbol[] GetMembers(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) { return ResolveMemberSymbols(UnderlyingType.GetMember(name, (MemberTypes)type, (BindingFlags)bindingAttr)); } diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs index f9ab22f98..153e846d5 100644 --- a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs @@ -446,19 +446,19 @@ public ITypeSymbol[] GetInterfaces(bool inherit = true) } /// - public IMemberSymbol[] GetMember(string name) + public IMemberSymbol[] GetMembers(string name) { return ResolveMemberSymbols(UnderlyingType.GetMember(name)); } /// - public IMemberSymbol[] GetMember(string name, System.Reflection.BindingFlags bindingAttr) + public IMemberSymbol[] GetMembers(string name, System.Reflection.BindingFlags bindingAttr) { return ResolveMemberSymbols(UnderlyingType.GetMember(name, (BindingFlags)bindingAttr)); } /// - public IMemberSymbol[] GetMember(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) + public IMemberSymbol[] GetMembers(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) { return ResolveMemberSymbols(UnderlyingType.GetMember(name, (MemberTypes)type, (BindingFlags)bindingAttr)); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionGenericTypeParameterSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionGenericTypeParameterSymbolBuilder.cs index f181b5f3d..a483bceb0 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionGenericTypeParameterSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionGenericTypeParameterSymbolBuilder.cs @@ -18,8 +18,8 @@ class ReflectionGenericTypeParameterSymbolBuilder : ReflectionGenericTypeParamet /// /// /// - public ReflectionGenericTypeParameterSymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbolBuilder resolvingModule, IReflectionMemberSymbolBuilder resolvingMember, GenericTypeParameterBuilder builder) : - base(context, resolvingModule, resolvingMember, builder) + public ReflectionGenericTypeParameterSymbolBuilder(ReflectionSymbolContext context, IReflectionModuleSymbolBuilder resolvingModule, IReflectionMemberSymbolBuilder resolvingMember) : + base(context, resolvingModule, resolvingMember,) { _builder = builder ?? throw new ArgumentNullException(nameof(builder)); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs index ac8e95076..3d393a04d 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/Emit/ReflectionTypeSymbolBuilder.cs @@ -18,8 +18,15 @@ class ReflectionTypeSymbolBuilder : ReflectionTypeSymbolBase, IReflectionTypeSym readonly TypeBuilder _builder; Type? _type; - List? _incompleteMethods; - List? _incompleteCustomAttributes; + ITypeSymbol _parentType; + List? _genericTypeParameters; + List _interfaces; + List _fields; + List? _constructors; + List? _methods; + List? _properties; + List? _events; + List? _customAttributes; /// /// Initializes a new instance. @@ -50,16 +57,15 @@ public ReflectionTypeSymbolBuilder(ReflectionSymbolContext context, IReflectionM /// public void SetParent(ITypeSymbol? parent) { - UnderlyingTypeBuilder.SetParent(parent?.Unpack()); + _parentType = (IReflectionTypeSymbol?)parent; } /// public IGenericTypeParameterSymbolBuilder[] DefineGenericParameters(params string[] names) { - var l = UnderlyingTypeBuilder.DefineGenericParameters(names); var a = new IGenericTypeParameterSymbolBuilder[l.Length]; for (int i = 0; i < l.Length; i++) - a[i] = ResolveGenericTypeParameterSymbol(l[i]); + a[i] = new ReflectionGenericTypeParameterSymbolBuilder(Context, ResolvingModuleBuilder, this); return a; } @@ -116,8 +122,8 @@ public IFieldSymbolBuilder DefineField(string fieldName, ITypeSymbol type, IType public IMethodSymbolBuilder DefineMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? returnTypeRequiredCustomModifiers, ITypeSymbol[]? returnTypeOptionalCustomModifiers, ITypeSymbol[]? parameterTypes, ITypeSymbol[][]? parameterTypeRequiredCustomModifiers, ITypeSymbol[][]? parameterTypeOptionalCustomModifiers) { var m = ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, (MethodAttributes)attributes, (CallingConventions)callingConvention, returnType?.Unpack(), returnTypeRequiredCustomModifiers?.Unpack(), returnTypeOptionalCustomModifiers?.Unpack(), parameterTypes?.Unpack(), parameterTypeRequiredCustomModifiers?.Unpack(), parameterTypeOptionalCustomModifiers?.Unpack())); - _incompleteMethods ??= []; - _incompleteMethods.Add(m); + _methods ??= []; + _methods.Add(m); return m; } @@ -125,8 +131,8 @@ public IMethodSymbolBuilder DefineMethod(string name, MethodAttributes attribute public IMethodSymbolBuilder DefineMethod(string name, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes) { var m = ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, (MethodAttributes)attributes, (CallingConventions)callingConvention, returnType?.Unpack(), parameterTypes?.Unpack())); - _incompleteMethods ??= []; - _incompleteMethods.Add(m); + _methods ??= []; + _methods.Add(m); return m; } @@ -134,8 +140,8 @@ public IMethodSymbolBuilder DefineMethod(string name, System.Reflection.MethodAt public IMethodSymbolBuilder DefineMethod(string name, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention) { var m = ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, (MethodAttributes)attributes, (CallingConventions)callingConvention)); - _incompleteMethods ??= []; - _incompleteMethods.Add(m); + _methods ??= []; + _methods.Add(m); return m; } @@ -143,8 +149,8 @@ public IMethodSymbolBuilder DefineMethod(string name, System.Reflection.MethodAt public IMethodSymbolBuilder DefineMethod(string name, System.Reflection.MethodAttributes attributes) { var m = ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, (MethodAttributes)attributes)); - _incompleteMethods ??= []; - _incompleteMethods.Add(m); + _methods ??= []; + _methods.Add(m); return m; } @@ -152,8 +158,8 @@ public IMethodSymbolBuilder DefineMethod(string name, System.Reflection.MethodAt public IMethodSymbolBuilder DefineMethod(string name, System.Reflection.MethodAttributes attributes, ITypeSymbol? returnType, ITypeSymbol[]? parameterTypes) { var m = ResolveMethodSymbol(UnderlyingTypeBuilder.DefineMethod(name, (MethodAttributes)attributes, returnType?.Unpack(), parameterTypes?.Unpack())); - _incompleteMethods ??= []; - _incompleteMethods.Add(m); + _methods ??= []; + _methods.Add(m); return m; } @@ -257,8 +263,8 @@ public IConstructorSymbolBuilder DefineTypeInitializer() public void SetCustomAttribute(CustomAttribute attribute) { UnderlyingTypeBuilder.SetCustomAttribute(attribute.Unpack()); - _incompleteCustomAttributes ??= []; - _incompleteCustomAttributes.Add(attribute); + _customAttributes ??= []; + _customAttributes.Add(attribute); } #endregion @@ -319,10 +325,10 @@ public override IMethodSymbol[] GetMethods(BindingFlags bindingAttr) /// IMethodSymbol[] GetIncompleteMethods(BindingFlags bindingAttr = BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance) { - if (_incompleteMethods == null) + if (_methods == null) return []; else - return SymbolUtil.FilterMethods(this, _incompleteMethods, bindingAttr).Cast().ToArray(); + return SymbolUtil.SelectMethods(this, _methods, bindingAttr).Cast().ToArray(); } #endregion @@ -335,9 +341,9 @@ public override CustomAttribute[] GetCustomAttributes(bool inherit = false) if (IsComplete) return ResolveCustomAttributes(UnderlyingRuntimeMember.GetCustomAttributesData(inherit).ToArray()); else if (inherit == false || BaseType == null) - return _incompleteCustomAttributes?.ToArray() ?? []; + return _customAttributes?.ToArray() ?? []; else - return Enumerable.Concat(_incompleteCustomAttributes?.ToArray() ?? [], ResolveCustomAttributes(BaseType.Unpack().GetInheritedCustomAttributesData())).ToArray(); + return Enumerable.Concat(_customAttributes?.ToArray() ?? [], ResolveCustomAttributes(BaseType.Unpack().GetInheritedCustomAttributesData())).ToArray(); } /// @@ -363,8 +369,8 @@ public void Complete() if (_builder.IsCreated() == false) { _type = _builder.CreateType() ?? throw new InvalidOperationException(); - _incompleteMethods = null; - _incompleteCustomAttributes = null; + _methods = null; + _customAttributes = null; } // force module to reresolve diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionArrayTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionArrayTypeSymbol.cs index d11a94fcf..b9456e1c7 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionArrayTypeSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionArrayTypeSymbol.cs @@ -21,10 +21,10 @@ public ReflectionArrayTypeSymbol(ReflectionSymbolContext context, IReflectionMod } /// - public override Type UnderlyingType => ElementType.UnderlyingType.MakeArrayType(rank); + public override Type UnderlyingType => SpecifiedType.UnderlyingType.MakeArrayType(rank); /// - public override Type UnderlyingRuntimeType => ElementType.UnderlyingRuntimeType.MakeArrayType(rank); + public override Type UnderlyingRuntimeType => SpecifiedType.UnderlyingRuntimeType.MakeArrayType(rank); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionByRefTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionByRefTypeSymbol.cs index 9e0c79d87..0dfc4d623 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionByRefTypeSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionByRefTypeSymbol.cs @@ -19,10 +19,10 @@ public ReflectionByRefTypeSymbol(ReflectionSymbolContext context, IReflectionMod } /// - public override Type UnderlyingType => ElementType.UnderlyingType.MakeByRefType(); + public override Type UnderlyingType => SpecifiedType.UnderlyingType.MakeByRefType(); /// - public override Type UnderlyingRuntimeType => ElementType.UnderlyingRuntimeType.MakeByRefType(); + public override Type UnderlyingRuntimeType => SpecifiedType.UnderlyingRuntimeType.MakeByRefType(); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericSpecTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericInstantiationTypeSymbol.cs similarity index 80% rename from src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericSpecTypeSymbol.cs rename to src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericInstantiationTypeSymbol.cs index e369f1e10..457afdbde 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericSpecTypeSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericInstantiationTypeSymbol.cs @@ -6,7 +6,7 @@ namespace IKVM.CoreLib.Symbols.Reflection { - class ReflectionGenericSpecTypeSymbol : ReflectionTypeSpecSymbol + class ReflectionGenericInstantiationTypeSymbol : ReflectionTypeSpecSymbol { /// @@ -44,17 +44,17 @@ static bool ContainsTypeBuilder(Type type) /// /// /// - public ReflectionGenericSpecTypeSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol elementType, IReflectionTypeSymbol[] genericTypeArguments) : + public ReflectionGenericInstantiationTypeSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol elementType, IReflectionTypeSymbol[] genericTypeArguments) : base(context, resolvingModule, elementType) { _genericTypeArguments = genericTypeArguments ?? throw new ArgumentNullException(nameof(genericTypeArguments)); } /// - public override Type UnderlyingType => _underlyingType ??= ElementType.UnderlyingType.MakeGenericType(_genericTypeArguments.Select(i => i.UnderlyingType).ToArray()); + public override Type UnderlyingType => _underlyingType ??= SpecifiedType.UnderlyingType.MakeGenericType(_genericTypeArguments.Select(i => i.UnderlyingType).ToArray()); /// - public override Type UnderlyingRuntimeType => ElementType.UnderlyingRuntimeType.MakeGenericType(_genericTypeArguments.Select(i => i.UnderlyingRuntimeType).ToArray()); + public override Type UnderlyingRuntimeType => SpecifiedType.UnderlyingRuntimeType.MakeGenericType(_genericTypeArguments.Select(i => i.UnderlyingRuntimeType).ToArray()); /// /// Returns true if the underlying type contains a type builder. @@ -67,7 +67,7 @@ public override IFieldSymbol[] GetFields() { if (UnderlyingTypeContainsTypeBuilder) { - var l = ElementType.UnderlyingType.GetFields(); + var l = SpecifiedType.UnderlyingType.GetFields(); var a = new IFieldSymbol[l.Length]; for (int i = 0; i < l.Length; i++) a[i] = ResolveFieldSymbol(TypeBuilder.GetField(UnderlyingType, l[i])); @@ -83,7 +83,7 @@ public override IFieldSymbol[] GetFields(BindingFlags bindingAttr) { if (UnderlyingTypeContainsTypeBuilder) { - var l = ElementType.UnderlyingType.GetFields(bindingAttr); + var l = SpecifiedType.UnderlyingType.GetFields(bindingAttr); var a = new IFieldSymbol[l.Length]; for (int i = 0; i < l.Length; i++) a[i] = ResolveFieldSymbol(TypeBuilder.GetField(UnderlyingType, l[i])); @@ -98,7 +98,7 @@ public override IFieldSymbol[] GetFields(BindingFlags bindingAttr) public override IFieldSymbol? GetField(string name) { if (UnderlyingTypeContainsTypeBuilder) - if (ElementType.UnderlyingType.GetField(name) is { } f) + if (SpecifiedType.UnderlyingType.GetField(name) is { } f) return ResolveFieldSymbol(TypeBuilder.GetField(UnderlyingType, f)); return base.GetField(name); @@ -108,7 +108,7 @@ public override IFieldSymbol[] GetFields(BindingFlags bindingAttr) public override IFieldSymbol? GetField(string name, BindingFlags bindingAttr) { if (UnderlyingTypeContainsTypeBuilder) - if (ElementType.UnderlyingType.GetField(name, bindingAttr) is { } f) + if (SpecifiedType.UnderlyingType.GetField(name, bindingAttr) is { } f) return ResolveFieldSymbol(TypeBuilder.GetField(UnderlyingType, f)); return base.GetField(name, bindingAttr); @@ -119,7 +119,7 @@ public override IConstructorSymbol[] GetConstructors() { if (UnderlyingTypeContainsTypeBuilder) { - var l = ElementType.UnderlyingType.GetConstructors(); + var l = SpecifiedType.UnderlyingType.GetConstructors(); var a = new IConstructorSymbol[l.Length]; for (int i = 0; i < l.Length; i++) a[i] = ResolveConstructorSymbol(TypeBuilder.GetConstructor(UnderlyingType, l[i])); @@ -135,7 +135,7 @@ public override IConstructorSymbol[] GetConstructors(BindingFlags bindingAttr) { if (UnderlyingTypeContainsTypeBuilder) { - var l = ElementType.UnderlyingType.GetConstructors(bindingAttr); + var l = SpecifiedType.UnderlyingType.GetConstructors(bindingAttr); var a = new IConstructorSymbol[l.Length]; for (int i = 0; i < l.Length; i++) a[i] = ResolveConstructorSymbol(TypeBuilder.GetConstructor(UnderlyingType, l[i])); @@ -150,7 +150,7 @@ public override IConstructorSymbol[] GetConstructors(BindingFlags bindingAttr) public override IConstructorSymbol? GetConstructor(ITypeSymbol[] types) { if (UnderlyingTypeContainsTypeBuilder) - if (ElementType.UnderlyingType.GetConstructor(types.Unpack()) is { } m) + if (SpecifiedType.UnderlyingType.GetConstructor(types.Unpack()) is { } m) return ResolveConstructorSymbol(TypeBuilder.GetConstructor(UnderlyingType, m)); return base.GetConstructor(types); @@ -160,7 +160,7 @@ public override IConstructorSymbol[] GetConstructors(BindingFlags bindingAttr) public override IConstructorSymbol? GetConstructor(BindingFlags bindingAttr, ITypeSymbol[] types) { if (UnderlyingTypeContainsTypeBuilder) - if (ElementType.UnderlyingType.GetConstructor(bindingAttr, null, types.Unpack(), null) is { } m) + if (SpecifiedType.UnderlyingType.GetConstructor(bindingAttr, null, types.Unpack(), null) is { } m) return ResolveConstructorSymbol(TypeBuilder.GetConstructor(UnderlyingType, m)); return base.GetConstructor(bindingAttr, types); @@ -171,7 +171,7 @@ public override IMethodSymbol[] GetMethods() { if (UnderlyingTypeContainsTypeBuilder) { - var l = ElementType.UnderlyingType.GetMethods(); + var l = SpecifiedType.UnderlyingType.GetMethods(); var a = new IMethodSymbol[l.Length]; for (int i = 0; i < l.Length; i++) a[i] = ResolveMethodSymbol(TypeBuilder.GetMethod(UnderlyingType, l[i])); @@ -187,7 +187,7 @@ public override IMethodSymbol[] GetMethods(BindingFlags bindingAttr) { if (UnderlyingTypeContainsTypeBuilder) { - var l = ElementType.UnderlyingType.GetMethods(bindingAttr); + var l = SpecifiedType.UnderlyingType.GetMethods(bindingAttr); var a = new IMethodSymbol[l.Length]; for (int i = 0; i < l.Length; i++) a[i] = ResolveMethodSymbol(TypeBuilder.GetMethod(UnderlyingType, l[i])); @@ -202,7 +202,7 @@ public override IMethodSymbol[] GetMethods(BindingFlags bindingAttr) public override IMethodSymbol? GetMethod(string name) { if (UnderlyingTypeContainsTypeBuilder) - if (ElementType.UnderlyingType.GetMethod(name) is { } m) + if (SpecifiedType.UnderlyingType.GetMethod(name) is { } m) return ResolveMethodSymbol(TypeBuilder.GetMethod(UnderlyingType, m)); return base.GetMethod(name); @@ -212,7 +212,7 @@ public override IMethodSymbol[] GetMethods(BindingFlags bindingAttr) public override IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr) { if (UnderlyingTypeContainsTypeBuilder) - if (ElementType.UnderlyingType.GetMethod(name, bindingAttr) is { } m) + if (SpecifiedType.UnderlyingType.GetMethod(name, bindingAttr) is { } m) return ResolveMethodSymbol(TypeBuilder.GetMethod(UnderlyingType, m)); return base.GetMethod(name, bindingAttr); @@ -222,7 +222,7 @@ public override IMethodSymbol[] GetMethods(BindingFlags bindingAttr) public override IMethodSymbol? GetMethod(string name, ITypeSymbol[] types) { if (UnderlyingTypeContainsTypeBuilder) - if (ElementType.UnderlyingType.GetMethod(name, types.Unpack()) is { } m) + if (SpecifiedType.UnderlyingType.GetMethod(name, types.Unpack()) is { } m) return ResolveMethodSymbol(TypeBuilder.GetMethod(UnderlyingType, m)); return base.GetMethod(name, types); @@ -232,7 +232,7 @@ public override IMethodSymbol[] GetMethods(BindingFlags bindingAttr) public override IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types) { if (UnderlyingTypeContainsTypeBuilder) - if (ElementType.UnderlyingType.GetMethod(name, bindingAttr, null, types.Unpack(), null) is { } m) + if (SpecifiedType.UnderlyingType.GetMethod(name, bindingAttr, null, types.Unpack(), null) is { } m) return ResolveMethodSymbol(TypeBuilder.GetMethod(UnderlyingType, m)); return base.GetMethod(name, bindingAttr, types); @@ -242,7 +242,7 @@ public override IMethodSymbol[] GetMethods(BindingFlags bindingAttr) public override IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types, ParameterModifier[]? modifiers) { if (UnderlyingTypeContainsTypeBuilder) - if (ElementType.UnderlyingType.GetMethod(name, bindingAttr, null, types.Unpack(), modifiers) is { } m) + if (SpecifiedType.UnderlyingType.GetMethod(name, bindingAttr, null, types.Unpack(), modifiers) is { } m) return ResolveMethodSymbol(TypeBuilder.GetMethod(UnderlyingType, m)); return base.GetMethod(name, bindingAttr, types, modifiers); @@ -252,7 +252,7 @@ public override IMethodSymbol[] GetMethods(BindingFlags bindingAttr) public override IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers) { if (UnderlyingTypeContainsTypeBuilder) - if (ElementType.UnderlyingType.GetMethod(name, bindingAttr, null, callConvention, types.Unpack(), modifiers) is { } m) + if (SpecifiedType.UnderlyingType.GetMethod(name, bindingAttr, null, callConvention, types.Unpack(), modifiers) is { } m) return ResolveMethodSymbol(TypeBuilder.GetMethod(UnderlyingType, m)); return base.GetMethod(name, bindingAttr, callConvention, types, modifiers); @@ -265,7 +265,7 @@ public override IMethodSymbol[] GetMethods(BindingFlags bindingAttr) #if NETFRAMEWORK throw new NotSupportedException(); #else - if (ElementType.UnderlyingType.GetMethod(name, genericParameterCount, types.Unpack(), modifiers) is { } m) + if (SpecifiedType.UnderlyingType.GetMethod(name, genericParameterCount, types.Unpack(), modifiers) is { } m) return ResolveMethodSymbol(TypeBuilder.GetMethod(UnderlyingType, m)); #endif @@ -279,7 +279,7 @@ public override IMethodSymbol[] GetMethods(BindingFlags bindingAttr) #if NETFRAMEWORK throw new NotSupportedException(); #else - if (ElementType.UnderlyingType.GetMethod(name, genericParameterCount, bindingAttr, null, types.Unpack(), modifiers) is { } m) + if (SpecifiedType.UnderlyingType.GetMethod(name, genericParameterCount, bindingAttr, null, types.Unpack(), modifiers) is { } m) return ResolveMethodSymbol(TypeBuilder.GetMethod(UnderlyingType, m)); #endif @@ -293,7 +293,7 @@ public override IMethodSymbol[] GetMethods(BindingFlags bindingAttr) #if NETFRAMEWORK throw new NotSupportedException(); #else - if (ElementType.UnderlyingType.GetMethod(name, genericParameterCount, bindingAttr, null, callConvention, types.Unpack(), modifiers) is { } m) + if (SpecifiedType.UnderlyingType.GetMethod(name, genericParameterCount, bindingAttr, null, callConvention, types.Unpack(), modifiers) is { } m) return ResolveMethodSymbol(TypeBuilder.GetMethod(UnderlyingType, m)); #endif diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericTypeParameterSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericTypeParameterSymbol.cs index b33ae45c3..dfea498d4 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericTypeParameterSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericTypeParameterSymbol.cs @@ -13,7 +13,6 @@ class ReflectionGenericTypeParameterSymbol : ReflectionMemberSymbol, IReflection { readonly IReflectionMemberSymbol _resolvingMember; - readonly Type _type; ReflectionTypeSpecTable _specTable; @@ -25,11 +24,10 @@ class ReflectionGenericTypeParameterSymbol : ReflectionMemberSymbol, IReflection /// /// /// - public ReflectionGenericTypeParameterSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionMemberSymbol resolvingMember, Type type) : + public ReflectionGenericTypeParameterSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionMemberSymbol resolvingMember) : base(context, resolvingModule, resolvingMember as IReflectionTypeSymbol) { _resolvingMember = resolvingMember ?? throw new ArgumentNullException(nameof(resolvingMember)); - _type = type ?? throw new ArgumentNullException(nameof(type)); _specTable = new ReflectionTypeSpecTable(); } @@ -485,19 +483,19 @@ public ITypeSymbol[] GetInterfaces(bool inherit = true) } /// - public IMemberSymbol[] GetMember(string name) + public IMemberSymbol[] GetMembers(string name) { return ResolveMemberSymbols(UnderlyingType.GetMember(name)); } /// - public IMemberSymbol[] GetMember(string name, System.Reflection.BindingFlags bindingAttr) + public IMemberSymbol[] GetMembers(string name, System.Reflection.BindingFlags bindingAttr) { return ResolveMemberSymbols(UnderlyingType.GetMember(name, (BindingFlags)bindingAttr)); } /// - public IMemberSymbol[] GetMember(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) + public IMemberSymbol[] GetMembers(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) { return ResolveMemberSymbols(UnderlyingType.GetMember(name, (MemberTypes)type, (BindingFlags)bindingAttr)); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericTypeParameterTable.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericTypeParameterTable.cs index 604583160..1c9dde430 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericTypeParameterTable.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionGenericTypeParameterTable.cs @@ -34,7 +34,7 @@ public ReflectionGenericTypeParameterTable(ReflectionSymbolContext context, IRef } /// - /// Gets or creates the cached for the module by type. + /// Gets or creates the cached for the module by type. /// /// /// diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionPointerTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionPointerTypeSymbol.cs index 195f15544..fa959d0ba 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionPointerTypeSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionPointerTypeSymbol.cs @@ -19,10 +19,10 @@ public ReflectionPointerTypeSymbol(ReflectionSymbolContext context, IReflectionM } /// - public override Type UnderlyingType => ElementType.UnderlyingType.MakePointerType(); + public override Type UnderlyingType => SpecifiedType.UnderlyingType.MakePointerType(); /// - public override Type UnderlyingRuntimeType => ElementType.UnderlyingRuntimeType.MakePointerType(); + public override Type UnderlyingRuntimeType => SpecifiedType.UnderlyingRuntimeType.MakePointerType(); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSZArrayTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSZArrayTypeSymbol.cs index c50573f6c..760074bc8 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSZArrayTypeSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSZArrayTypeSymbol.cs @@ -19,10 +19,10 @@ public ReflectionSZArrayTypeSymbol(ReflectionSymbolContext context, IReflectionM } /// - public override Type UnderlyingType => ElementType.UnderlyingType.MakeArrayType(); + public override Type UnderlyingType => SpecifiedType.UnderlyingType.MakeArrayType(); /// - public override Type UnderlyingRuntimeType => ElementType.UnderlyingRuntimeType.MakeArrayType(); + public override Type UnderlyingRuntimeType => SpecifiedType.UnderlyingRuntimeType.MakeArrayType(); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeDefSymbol.cs similarity index 84% rename from src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbol.cs rename to src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeDefSymbol.cs index 1f10ce439..5f04f8c93 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeDefSymbol.cs @@ -4,7 +4,7 @@ namespace IKVM.CoreLib.Symbols.Reflection { - class ReflectionTypeSymbol : ReflectionTypeSymbolBase + class ReflectionTypeDefSymbol : ReflectionTypeSymbolBase { readonly Type _type; @@ -15,7 +15,7 @@ class ReflectionTypeSymbol : ReflectionTypeSymbolBase /// /// /// - public ReflectionTypeSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, Type type) : + public ReflectionTypeDefSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, Type type) : base(context, resolvingModule) { _type = type ?? throw new ArgumentNullException(nameof(type)); diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSpecSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSpecSymbol.cs index abea83797..71ae05a00 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSpecSymbol.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSpecSymbol.cs @@ -6,27 +6,27 @@ namespace IKVM.CoreLib.Symbols.Reflection abstract class ReflectionTypeSpecSymbol : ReflectionTypeSymbolBase { - readonly IReflectionTypeSymbol _elementType; + readonly IReflectionTypeSymbol _specifiedType; /// /// Initializes a new instance. /// /// /// - /// - public ReflectionTypeSpecSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol elementType) : + /// + public ReflectionTypeSpecSymbol(ReflectionSymbolContext context, IReflectionModuleSymbol resolvingModule, IReflectionTypeSymbol specifiedType) : base(context, resolvingModule) { - _elementType = elementType ?? throw new ArgumentNullException(nameof(elementType)); + _specifiedType = specifiedType ?? throw new ArgumentNullException(nameof(specifiedType)); } /// /// Gets the element type. /// - protected IReflectionTypeSymbol ElementType => _elementType; + protected IReflectionTypeSymbol SpecifiedType => _specifiedType; /// - public override bool IsComplete => ElementType.IsComplete; + public override bool IsComplete => SpecifiedType.IsComplete; } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSpecTable.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSpecTable.cs index b115fb485..db46cc187 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSpecTable.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSpecTable.cs @@ -20,7 +20,7 @@ struct ReflectionTypeSpecTable ReflectionSZArrayTypeSymbol? _asSZArray; ReflectionPointerTypeSymbol? _asPointer; ReflectionByRefTypeSymbol? _asByRef; - ConcurrentDictionary? _genericTypeSymbols; + ConcurrentDictionary? _genericTypeSymbols; /// /// Initializes a new instance. @@ -118,9 +118,9 @@ public IReflectionTypeSymbol GetOrCreateGenericTypeSymbol(IReflectionTypeSymbol[ /// /// /// - readonly ReflectionGenericSpecTypeSymbol CreateGenericTypeSymbol(IReflectionTypeSymbol[] genericTypeArguments) + readonly ReflectionGenericInstantiationTypeSymbol CreateGenericTypeSymbol(IReflectionTypeSymbol[] genericTypeArguments) { - return new ReflectionGenericSpecTypeSymbol(_context, _module, _elementType, genericTypeArguments); + return new ReflectionGenericInstantiationTypeSymbol(_context, _module, _elementType, genericTypeArguments); } } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbolBase.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbolBase.cs index 50afe9477..2961f315a 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbolBase.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbolBase.cs @@ -479,19 +479,19 @@ public virtual ITypeSymbol[] GetInterfaces(bool inherit = true) } /// - public virtual IMemberSymbol[] GetMember(string name) + public virtual IMemberSymbol[] GetMembers(string name) { return ResolveMemberSymbols(UnderlyingType.GetMember(name)); } /// - public virtual IMemberSymbol[] GetMember(string name, BindingFlags bindingAttr) + public virtual IMemberSymbol[] GetMembers(string name, BindingFlags bindingAttr) { return ResolveMemberSymbols(UnderlyingType.GetMember(name, bindingAttr)); } /// - public virtual IMemberSymbol[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) + public virtual IMemberSymbol[] GetMembers(string name, MemberTypes type, BindingFlags bindingAttr) { return ResolveMemberSymbols(UnderlyingType.GetMember(name, type, bindingAttr)); } diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeTable.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeTable.cs index 37cb46aec..f3a9f249a 100644 --- a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeTable.cs +++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeTable.cs @@ -64,7 +64,7 @@ public IReflectionTypeSymbol GetOrCreateTypeSymbol(Type type) if (type is TypeBuilder builder) return _table[row] = new ReflectionTypeSymbolBuilder(_context, (IReflectionModuleSymbolBuilder)_module, builder); else - return _table[row] = new ReflectionTypeSymbol(_context, _module, type); + return _table[row] = new ReflectionTypeDefSymbol(_context, _module, type); return _table[row] ?? throw new InvalidOperationException(); } diff --git a/src/IKVM.CoreLib/Symbols/SymbolUtil.cs b/src/IKVM.CoreLib/Symbols/SymbolUtil.cs index 2d7c43142..71e68dc1b 100644 --- a/src/IKVM.CoreLib/Symbols/SymbolUtil.cs +++ b/src/IKVM.CoreLib/Symbols/SymbolUtil.cs @@ -1,7 +1,11 @@ -using System.Collections.Generic; -using System.ComponentModel; +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; using System.Reflection; +using IKVM.CoreLib.Collections; + namespace IKVM.CoreLib.Symbols { @@ -46,49 +50,143 @@ public static bool BindingFlagsMatchInherited(IMethodSymbol method, BindingFlags } /// - /// Filters the set of methods by the binding attributes. + /// Selects the single method that corresponds to the given query. Throws an if multiple candidates are found. /// + /// + /// + /// + /// + /// /// - public static IEnumerable FilterMethods(ITypeSymbol type, IEnumerable methods, BindingFlags bindingAttr = BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance) + /// + /// + public static IMethodSymbol? SelectMethod(ITypeSymbol type, BindingFlags bindingFlags, string? name, IReadOnlyList? parameterTypes, IReadOnlyList? modifiers) { - var list = new HashSet(); + var list = SelectMethods(type, bindingFlags, name, parameterTypes, modifiers); + if (list == null) + throw new InvalidOperationException(); - foreach (var mb in methods) + return list.Count switch { - var mi = mb as IMethodSymbol; - if (mi != null && BindingFlagsMatch(mi, bindingAttr)) - if (list.Add(mi)) - yield return mi; - } + 0 => null, + 1 => list[0], + _ => throw new AmbiguousMatchException(), + }; + } - if ((bindingAttr & BindingFlags.DeclaredOnly) == 0) + /// + /// Selects the methods that corresponds to the given query. + /// + /// + /// + /// + public static IImmutableList SelectMethods(ITypeSymbol type, BindingFlags bindingFlags, string? name, IReadOnlyList? parameterTypes, IReadOnlyList? modifiers) + { + // we start by copying the declared methods and either removing or adding + // optimally, if doing no work, we end up returning the same list + // but we might also be appending only, thus preserving some space thanks to the immutable collection + var list = type.GetDeclaredMethods(); + + // remove items that do not match binding flags + foreach (var declaredMethod in list) + if (BindingFlagsMatch(declaredMethod, bindingFlags) == false) + list = list.Remove(declaredMethod); + + // we do want to check inherited methods + if ((bindingFlags & BindingFlags.DeclaredOnly) == 0) { - var baseMethods = new List(); - foreach (var mi in list) - if (mi.IsVirtual) - baseMethods.Add(mi.GetBaseDefinition()); + // keep a record of those methods which have been preserved + var baseMethods = new HashSet(); + + // record base methods of already emitted virtual methods + foreach (var method in list) + if (method.IsVirtual) + baseMethods.Add(method.GetBaseDefinition()); for (var baseType = type.BaseType; baseType != null; baseType = baseType.BaseType) { - foreach (var mi in baseType.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance)) - { - if (BindingFlagsMatchInherited(mi, bindingAttr)) - { - if (mi.IsVirtual) - { - baseMethods ??= []; - if (baseMethods.Contains(mi.GetBaseDefinition())) - continue; - - baseMethods.Add(mi.GetBaseDefinition()); - } - - if (list.Add(mi)) - yield return mi; - } - } + var baseTypeMethods = baseType.GetDeclaredMethods(); + if (baseTypeMethods == null) + throw new InvalidOperationException(); + + // remove base methods that do not match inherited binding flags + // remove base methods that are virtual and already tracked + foreach (var baseTypeMethod in baseTypeMethods) + if (BindingFlagsMatchInherited(baseTypeMethod, bindingFlags) == false || baseTypeMethod.IsVirtual && baseMethods.Contains(baseTypeMethod.GetBaseDefinition())) + baseTypeMethods = baseTypeMethods.Remove(baseTypeMethod); + + // append to emitted list + list = list.AddRange(baseTypeMethods); } } + + // remove methods that do not match filter conditions + foreach (var method in list) + if (MethodFilterPredicate(method, bindingFlags, name, parameterTypes, modifiers) == false) + list = list.Remove(method); + + // return final list + return list; + } + + /// + /// Predicate that determines if the method matches the specification. + /// + /// + /// + /// + /// + /// + static bool MethodFilterPredicate(IMethodSymbol method, BindingFlags bindingFlags, string? name, IReadOnlyList? parameterTypes, IReadOnlyList? modifiers) + { + if (name != null) + { + var nameComparison = StringComparison.Ordinal; + if ((bindingFlags & BindingFlags.IgnoreCase) != 0) + nameComparison = StringComparison.OrdinalIgnoreCase; + if (string.Equals(method.Name, name, nameComparison) == false) + return false; + } + + if (parameterTypes != null) + if (MatchParameterTypes(method, parameterTypes) == false) + return false; + + if (modifiers != null) + if (MatchModifiers(method, modifiers) == false) + return false; + + return true; + } + + /// + /// Checks that the parameters types of the method match the given parameter types. + /// + /// + /// + /// + static bool MatchParameterTypes(IMethodSymbol method, IReadOnlyList parameterTypes) + { + var methodParameters = method.GetParameters(); + if (methodParameters.Length != parameterTypes.Count) + return false; + + for (int i = 0; i < methodParameters.Length; i++) + if (methodParameters[i].ParameterType != parameterTypes[i]) + return false; + + return true; + } + + /// + /// Checks that the parameter modifiers match. For now does nothing. + /// + /// + /// + /// + static bool MatchModifiers(IMethodSymbol method, IReadOnlyList modifiers) + { + return true; } } diff --git a/src/IKVM.CoreLib/Symbols/TypeSymbolNameParserHelpers.cs b/src/IKVM.CoreLib/Symbols/TypeSymbolNameParserHelpers.cs new file mode 100644 index 000000000..bf940d819 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/TypeSymbolNameParserHelpers.cs @@ -0,0 +1,393 @@ +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Diagnostics; + +using IKVM.CoreLib.Text; + +namespace IKVM.CoreLib.Symbols +{ + + internal static class TypeNameParserHelpers + { + + const int maxDepth = 32; + internal const int SZArray = -1; + internal const int Pointer = -2; + internal const int ByRef = -3; + const char EscapeCharacter = '\\'; + + // Keep this in sync with GetFullTypeNameLength/NeedsEscaping + private static readonly string s_endOfFullTypeNameDelimitersSearchValues = "[]&*,+\\"; + + internal static string GetGenericTypeFullName(ReadOnlySpan fullTypeName, ReadOnlySpan genericArgs) + { + Debug.Assert(genericArgs.Length > 0); + + ValueStringBuilder result = new(stackalloc char[128]); + result.Append(fullTypeName); + + result.Append('['); + foreach (var genericArg in genericArgs) + { + result.Append('['); + result.Append(genericArg.AssemblyQualifiedName); // see recursion comments in TypeName.FullName + result.Append(']'); + result.Append(','); + } + result[result.Length - 1] = ']'; // replace ',' with ']' + + return result.ToString(); + } + + /// Positive length or negative value for invalid name + internal static int GetFullTypeNameLength(ReadOnlySpan input, out bool isNestedType) + { + isNestedType = false; + + // NET 6+ guarantees that MemoryExtensions.IndexOfAny has worst-case complexity + // O(m * i) if a match is found, or O(m * n) if a match is not found, where: + // i := index of match position + // m := number of needles + // n := length of search space (haystack) + // + // Downlevel versions of .NET do not make this guarantee, instead having a + // worst-case complexity of O(m * n) even if a match occurs at the beginning of + // the search space. Since we're running this in a loop over untrusted user + // input, that makes the total loop complexity potentially O(m * n^2), where + // 'n' is adversary-controlled. To avoid DoS issues here, we'll loop manually. + + int offset = input.IndexOfAny(s_endOfFullTypeNameDelimitersSearchValues.AsSpan()); + if (offset < 0) + { + return input.Length; // no type name end chars were found, the whole input is the type name + } + + if (input[offset] == EscapeCharacter) // this is very rare (IL Emit or pure IL) + { + offset = GetUnescapedOffset(input, startOffset: offset); // this is slower, but very rare so acceptable + } + isNestedType = offset > 0 && offset < input.Length && input[offset] == '+'; + return offset; + + static int GetUnescapedOffset(ReadOnlySpan input, int startOffset) + { + int offset = startOffset; + for (; offset < input.Length; offset++) + { + char c = input[offset]; + if (c == EscapeCharacter) + { + offset++; // skip the escaped char + + if (offset == input.Length || // invalid name that ends with escape character + !NeedsEscaping(input[offset])) // invalid name, escapes a char that does not need escaping + { + return -1; + } + } + else if (NeedsEscaping(c)) + { + break; + } + } + return offset; + } + + // Keep this in sync with s_endOfFullTypeNameDelimitersSearchValues + static bool NeedsEscaping(char c) => c is '[' or ']' or '&' or '*' or ',' or '+' or EscapeCharacter; + } + + internal static ReadOnlySpan GetName(ReadOnlySpan fullName) + { + // The two-value form of MemoryExtensions.LastIndexOfAny does not suffer + // from the behavior mentioned in the comment at the top of GetFullTypeNameLength. + // It always takes O(m * i) worst-case time and is safe to use here. + + int offset = fullName.LastIndexOfAny('.', '+'); + + if (offset > 0 && fullName[offset - 1] == EscapeCharacter) // this should be very rare (IL Emit & pure IL) + { + offset = GetUnescapedOffset(fullName, startIndex: offset); + } + + return offset < 0 ? fullName : fullName.Slice(offset + 1); + + static int GetUnescapedOffset(ReadOnlySpan fullName, int startIndex) + { + int offset = startIndex; + for (; offset >= 0; offset--) + { + if (fullName[offset] is '.' or '+') + { + if (offset == 0 || fullName[offset - 1] != EscapeCharacter) + { + break; + } + offset--; // skip the escaping character + } + } + return offset; + } + } + + // this method handles escaping of the ] just to let the AssemblyNameParser fail for the right input + internal static ReadOnlySpan GetAssemblyNameCandidate(ReadOnlySpan input) + { + // The only delimiter which can terminate an assembly name is ']'. + // Otherwise EOL serves as the terminator. + int offset = input.IndexOf(']'); + + if (offset > 0 && input[offset - 1] == EscapeCharacter) // this should be very rare (IL Emit & pure IL) + { + offset = GetUnescapedOffset(input, startIndex: offset); + } + + return offset < 0 ? input : input.Slice(0, offset); + + static int GetUnescapedOffset(ReadOnlySpan input, int startIndex) + { + int offset = startIndex; + for (; offset < input.Length; offset++) + { + if (input[offset] is ']') + { + if (input[offset - 1] != EscapeCharacter) + { + break; + } + } + } + return offset; + } + } + + internal static string GetRankOrModifierStringRepresentation(int rankOrModifier, ref ValueStringBuilder builder) + { + if (rankOrModifier == ByRef) + { + builder.Append('&'); + } + else if (rankOrModifier == Pointer) + { + builder.Append('*'); + } + else if (rankOrModifier == SZArray) + { + builder.Append("[]"); + } + else if (rankOrModifier == 1) + { + builder.Append("[*]"); + } + else + { + Debug.Assert(rankOrModifier >= 2); + + // O(rank) work, so we have to assume the rank is trusted. We don't put a hard cap on this, + // but within the TypeName parser, we do require the input string to contain the correct number + // of commas. This forces the input string to have at least O(rank) length, so there's no + // alg. complexity attack possible here. Callers can of course pass any arbitrary value to + // TypeName.MakeArrayTypeName, but per first sentence in this comment, we have to assume any + // such arbitrary value which is programmatically fed in originates from a trustworthy source. + + builder.Append('['); + builder.Append(',', rankOrModifier - 1); + builder.Append(']'); + } + + return builder.ToString(); + } + + /// + /// Are there any captured generic args? We'll look for "[[" and "[" that is not followed by "]", "*" and ",". + /// + internal static bool IsBeginningOfGenericArgs(ref ReadOnlySpan span, out bool doubleBrackets) + { + doubleBrackets = false; + + if (!span.IsEmpty && span[0] == '[') + { + // There are no spaces allowed before the first '[', but spaces are allowed after that. + ReadOnlySpan trimmed = span.Slice(1).TrimStart(); + if (!trimmed.IsEmpty) + { + if (trimmed[0] == '[') + { + doubleBrackets = true; + span = trimmed.Slice(1).TrimStart(); + return true; + } + if (!(trimmed[0] is ',' or '*' or ']')) // [] or [*] or [,] or [,,,, ...] + { + span = trimmed; + return true; + } + } + } + + return false; + } + + internal static bool TryGetTypeNameInfo(ref ReadOnlySpan input, ref List? nestedNameLengths, ref int recursiveDepth, out int totalLength) + { + bool isNestedType; + + totalLength = 0; + do + { + int length = GetFullTypeNameLength(input.Slice(totalLength), out isNestedType); + if (length <= 0) + { + // invalid type names: + // -1: invalid escaping + // 0: pair of unescaped "++" characters + return false; + } + + // Compat: Ignore leading '.' for type names without namespace. .NET Framework historically ignored leading '.' here. It is likely + // that code out there depends on this behavior. For example, type names formed by concatenating namespace and name, without checking for + // empty namespace (bug), are going to have superfluous leading '.'. + // This behavior means that types that start with '.' are not round-trippable via type name. + if (length > 1 && input[0] == '.' && input.Slice(0, length).LastIndexOf('.') == 0) + { + input = input.Slice(1); + length--; + } + + if (isNestedType) + { + if (!TryDive(ref recursiveDepth)) + { + return false; + } + + (nestedNameLengths ??= new()).Add(length); + totalLength += 1; // skip the '+' sign in next search + } + totalLength += length; + } while (isNestedType); + + return true; + } + + internal static bool TryParseNextDecorator(ref ReadOnlySpan input, out int rankOrModifier) + { + // Then try pulling a single decorator. + // Whitespace cannot precede the decorator, but it can follow the decorator. + + ReadOnlySpan originalInput = input; // so we can restore on 'false' return + + if (TryStripFirstCharAndTrailingSpaces(ref input, '*')) + { + rankOrModifier = Pointer; + return true; + } + + if (TryStripFirstCharAndTrailingSpaces(ref input, '&')) + { + rankOrModifier = ByRef; + return true; + } + + if (TryStripFirstCharAndTrailingSpaces(ref input, '[')) + { + // SZArray := [] + // MDArray := [*] or [,] or [,,,, ...] + + int rank = 1; + bool hasSeenAsterisk = false; + + ReadNextArrayToken: + + if (TryStripFirstCharAndTrailingSpaces(ref input, ']')) + { + // End of array marker + rankOrModifier = rank == 1 && !hasSeenAsterisk ? SZArray : rank; + return true; + } + + if (!hasSeenAsterisk) + { + if (rank == 1 && TryStripFirstCharAndTrailingSpaces(ref input, '*')) + { + // [*] + hasSeenAsterisk = true; + goto ReadNextArrayToken; + } + else if (TryStripFirstCharAndTrailingSpaces(ref input, ',')) + { + // [,,, ...] + // The runtime restricts arrays to rank 32, but we don't enforce that here. + // Instead, the max rank is controlled by the total number of commas present + // in the array decorator. + checked { rank++; } + goto ReadNextArrayToken; + } + } + + // Don't know what this token is. + // Fall through to 'return false' statement. + } + + input = originalInput; // ensure 'ref input' not mutated + rankOrModifier = 0; + return false; + } + + internal static bool TryStripFirstCharAndTrailingSpaces(ref ReadOnlySpan span, char value) + { + if (!span.IsEmpty && span[0] == value) + { + span = span.Slice(1).TrimStart(); + return true; + } + return false; + } + + internal static void ThrowArgumentException_InvalidTypeName(int errorIndex) + { + throw new InvalidOperationException(); + } + + internal static void ThrowInvalidOperation_MaxNodesExceeded(int limit) + { + throw new InvalidOperationException(); + } + + internal static void ThrowInvalidOperation_NotGenericType() + { + throw new InvalidOperationException(); + } + + internal static void ThrowInvalidOperation_NotNestedType() + { + throw new InvalidOperationException(); + } + + internal static void ThrowInvalidOperation_NoElement() + { + throw new InvalidOperationException(); + } + + internal static void ThrowInvalidOperation_HasToBeArrayClass() + { + throw new InvalidOperationException(); + } + + internal static bool IsMaxDepthExceeded(int depth) => depth > maxDepth; + + internal static bool TryDive(ref int depth) + { + depth++; + return !IsMaxDepthExceeded(depth); + } + + internal static void ThrowInvalidOperation_NotSimpleName(string fullName) + { + throw new InvalidOperationException(); + } + + } + +} diff --git a/src/IKVM.CoreLib/Symbols/TypeSymbolNameParserResult.cs b/src/IKVM.CoreLib/Symbols/TypeSymbolNameParserResult.cs new file mode 100644 index 000000000..984395419 --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/TypeSymbolNameParserResult.cs @@ -0,0 +1,41 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Immutable; +using System.Diagnostics; + +namespace IKVM.CoreLib.Symbols +{ + + [DebuggerDisplay("{AssemblyQualifiedName}")] + struct TypeSymbolNameParserResult + { + + readonly ReadOnlyMemory _namespaceName; + readonly ReadOnlyMemory _name; + readonly AssemblyIdentity? _assembly; + readonly ImmutableArray _genericTypeArguments; + readonly int _rankOrModifier; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + internal TypeSymbolNameParserResult(ReadOnlyMemory namespaceName, ReadOnlyMemory name, AssemblyIdentity? assembly, ImmutableArray genericTypeArguments, int rankOrModifier = default) + { + _namespaceName = namespaceName; + _name = name; + _assembly = assembly; + _genericTypeArguments = genericTypeArguments; + _rankOrModifier = rankOrModifier; + } + + public string AssemblyQualifiedName { get; } + + } + +} \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/TypeSymbolNameReader.cs b/src/IKVM.CoreLib/Symbols/TypeSymbolNameReader.cs new file mode 100644 index 000000000..c50c7527a --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/TypeSymbolNameReader.cs @@ -0,0 +1,270 @@ +using System; +using System.Buffers; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Diagnostics; + +using IKVM.CoreLib.Buffers; + +namespace IKVM.CoreLib.Symbols +{ + + ref struct TypeSymbolNameReader + { + + private readonly bool _throwOnError; + private ReadOnlySpan _inputString; + + private TypeSymbolNameReader(ReadOnlySpan name, bool throwOnError, TypeNameParseOptions? options) : this() + { + _inputString = name; + _throwOnError = throwOnError; + _parseOptions = options ?? s_defaults; + } + + internal static TypeName? Parse(ReadOnlySpan typeName, bool throwOnError, TypeNameParseOptions? options = default) + { + ReadOnlySpan trimmedName = typeName.TrimStart(); // whitespaces at beginning are always OK + if (trimmedName.IsEmpty) + { + if (throwOnError) + { + ThrowArgumentException_InvalidTypeName(errorIndex: 0); // whitespace input needs to report the error index as 0 + } + + return null; + } + + int recursiveDepth = 0; + TypeNameParser parser = new(trimmedName, throwOnError, options); + TypeName? parsedName = parser.ParseNextTypeName(allowFullyQualifiedName: true, ref recursiveDepth); + + if (parsedName is null || !parser._inputString.IsEmpty) // unconsumed input == error + { + if (throwOnError) + { + if (IsMaxDepthExceeded(parser._parseOptions, recursiveDepth)) + { + ThrowInvalidOperation_MaxNodesExceeded(parser._parseOptions.MaxNodes); + } + + int errorIndex = typeName.Length - parser._inputString.Length; + ThrowArgumentException_InvalidTypeName(errorIndex); + } + + return null; + } + + Debug.Assert(parsedName.GetNodeCount() == recursiveDepth, $"Node count mismatch for '{typeName.ToString()}'"); + + return parsedName; + } + + // this method should return null instead of throwing, so the caller can get errorIndex and include it in error msg + private TypeName? ParseNextTypeName(bool allowFullyQualifiedName, ref int recursiveDepth) + { + if (!TryDive(_parseOptions, ref recursiveDepth)) + { + return null; + } + + List? nestedNameLengths = null; + if (!TryGetTypeNameInfo(_parseOptions, ref _inputString, ref nestedNameLengths, ref recursiveDepth, out int fullTypeNameLength)) + { + return null; + } + + // At this point, we have performed O(fullTypeNameLength) total work. + + ReadOnlySpan fullTypeName = _inputString.Slice(0, fullTypeNameLength); + _inputString = _inputString.Slice(fullTypeNameLength); + + // Don't allocate now, as it may be an open generic type like "Name`1" +#if SYSTEM_PRIVATE_CORELIB + List? genericArgs = null; +#else + ImmutableArray.Builder? genericArgs = null; +#endif + + // Are there any captured generic args? We'll look for "[[" and "[". + // There are no spaces allowed before the first '[', but spaces are allowed + // after that. The check slices _inputString, so we'll capture it into + // a local so we can restore it later if needed. + ReadOnlySpan capturedBeforeProcessing = _inputString; + if (IsBeginningOfGenericArgs(ref _inputString, out bool doubleBrackets)) + { + ParseAnotherGenericArg: + + // Namespace.Type`2[[GenericArgument1, AssemblyName1],[GenericArgument2, AssemblyName2]] - double square bracket syntax allows for fully qualified type names + // Namespace.Type`2[GenericArgument1,GenericArgument2] - single square bracket syntax is legal only for non-fully qualified type names + // Namespace.Type`2[[GenericArgument1, AssemblyName1], GenericArgument2] - mixed mode + // Namespace.Type`2[GenericArgument1, [GenericArgument2, AssemblyName2]] - mixed mode + TypeName? genericArg = ParseNextTypeName(allowFullyQualifiedName: doubleBrackets, ref recursiveDepth); + if (genericArg is null) // parsing failed + { + return null; + } + + // For [[, there had better be a ']' after the type name. + if (doubleBrackets && !TryStripFirstCharAndTrailingSpaces(ref _inputString, ']')) + { + return null; + } + + if (genericArgs is null) + { +#if SYSTEM_PRIVATE_CORELIB + genericArgs = new List(2); +#else + genericArgs = ImmutableArray.CreateBuilder(2); +#endif + } + genericArgs.Add(genericArg); + + // Is there a ',[' indicating fully qualified generic type arg? + // Is there a ',' indicating non-fully qualified generic type arg? + if (TryStripFirstCharAndTrailingSpaces(ref _inputString, ',')) + { + doubleBrackets = TryStripFirstCharAndTrailingSpaces(ref _inputString, '['); + + goto ParseAnotherGenericArg; + } + + // The only other allowable character is ']', indicating the end of + // the generic type arg list. + if (!TryStripFirstCharAndTrailingSpaces(ref _inputString, ']')) + { + return null; + } + } + + // At this point, we may have performed O(fullTypeNameLength + _inputString.Length) total work. + // This will be the case if there was whitespace after the full type name in the original input + // string. We could end up looking at these same whitespace chars again later in this method, + // such as when parsing decorators. We rely on the TryDive routine to limit the total number + // of times we might inspect the same character. + + // If there was an error stripping the generic args, back up to + // before we started processing them, and let the decorator + // parser try handling it. + if (genericArgs is null) + { + _inputString = capturedBeforeProcessing; + } + else + { + // Every constructed generic type needs the generic type definition. + if (!TryDive(_parseOptions, ref recursiveDepth)) + { + return null; + } + // If that generic type is a nested type, we don't increase the recursiveDepth any further, + // as generic type definition uses exactly the same declaring type as the constructed generic type. + } + + int previousDecorator = default; + // capture the current state so we can reprocess it again once we know the AssemblyName + capturedBeforeProcessing = _inputString; + // iterate over the decorators to ensure there are no illegal combinations + while (TryParseNextDecorator(ref _inputString, out int parsedDecorator)) + { + if (!TryDive(_parseOptions, ref recursiveDepth)) + { + return null; + } + + // Currently it's illegal for managed reference to be followed by any other decorator, + // but this is a runtime-specific behavior and the parser is not enforcing that rule. + previousDecorator = parsedDecorator; + } + + AssemblyNameInfo? assemblyName = null; + if (allowFullyQualifiedName && !TryParseAssemblyName(ref assemblyName)) + { +#if SYSTEM_PRIVATE_CORELIB + // backward compat: throw FileLoadException for non-empty invalid strings + if (_throwOnError || !_inputString.TrimStart().StartsWith(",")) + { + throw new IO.FileLoadException(SR.InvalidAssemblyName, _inputString.ToString()); + } +#else + return null; +#endif + } + + // No matter what was parsed, the full name string is allocated only once. + // In case of generic, nested, array, pointer and byref types the full name is allocated + // when needed for the first time . + string fullName = fullTypeName.ToString(); + + TypeName? declaringType = GetDeclaringType(fullName, nestedNameLengths, assemblyName); + TypeName result = new(fullName, assemblyName, declaringType: declaringType); + if (genericArgs is not null) + { + result = new(fullName: null, assemblyName, elementOrGenericType: result, declaringType, genericArgs); + } + + // The loop below is protected by the dive check during the first decorator pass prior + // to assembly name parsing above. + + if (previousDecorator != default) // some decorators were recognized + { + while (TryParseNextDecorator(ref capturedBeforeProcessing, out int parsedModifier)) + { + result = new(fullName: null, assemblyName, elementOrGenericType: result, rankOrModifier: parsedModifier); + } + } + + return result; + } + + /// false means the input was invalid and parsing has failed. Empty input is valid and returns true. + private bool TryParseAssemblyName(ref AssemblyIdentity? assemblyName) + { + ReadOnlySpan capturedBeforeProcessing = _inputString; + if (TryStripFirstCharAndTrailingSpaces(ref _inputString, ',')) + { + if (_inputString.IsEmpty) + { + _inputString = capturedBeforeProcessing; // restore the state + return false; + } + + ReadOnlySpan candidate = GetAssemblyNameCandidate(_inputString); + if (!AssemblyIdentity.TryParse(candidate, out assemblyName)) + { + return false; + } + + _inputString = _inputString.Slice(candidate.Length); + return true; + } + + return true; + } + + private static TypeSymbolNameParserResult? GetDeclaringType(string fullTypeName, List? nestedNameLengths, AssemblyIdentity? assemblyName) + { + if (nestedNameLengths is null) + { + return null; + } + + // The loop below is protected by the dive check in GetFullTypeNameLength. + + TypeSymbolNameParserResult? declaringType = null; + int nameOffset = 0; + foreach (int nestedNameLength in nestedNameLengths) + { + Debug.Assert(nestedNameLength > 0, "TryGetTypeNameInfo should return error on zero lengths"); + int fullNameLength = nameOffset + nestedNameLength; + declaringType = new(fullTypeName, assemblyName, declaringType: declaringType, nestedNameLength: fullNameLength); + nameOffset += nestedNameLength + 1; // include the '+' that was skipped in name + } + + return declaringType; + } + + } + +} diff --git a/src/IKVM.Reflection/Type.cs b/src/IKVM.Reflection/Type.cs index 5eecf0c1e..0db2343c0 100644 --- a/src/IKVM.Reflection/Type.cs +++ b/src/IKVM.Reflection/Type.cs @@ -162,7 +162,7 @@ public virtual EventInfo[] __GetDeclaredEvents() { return Array.Empty(); } - + public virtual PropertyInfo[] __GetDeclaredProperties() { return Array.Empty(); @@ -935,9 +935,7 @@ public MethodInfo GetMethod(string name, Type[] types, ParameterModifier[] modif public MethodInfo GetMethod(string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers) { // first we try an exact match and only if that fails we fall back to using the binder - return GetMemberByName(name, bindingAttr, - delegate (MethodInfo method) { return method.MethodSignature.MatchParameterTypes(types); }) - ?? GetMethodWithBinder(name, bindingAttr, binder ?? DefaultBinder, types, modifiers); + return GetMemberByName(name, bindingAttr, (MethodInfo m) => m.MethodSignature.MatchParameterTypes(types)) ?? GetMethodWithBinder(name, bindingAttr, binder ?? DefaultBinder, types, modifiers); } private T GetMethodWithBinder(string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers) @@ -1809,7 +1807,7 @@ void FillInInterfaceMethods(Type interfaceType, MethodInfo[] interfaceMethods, M type.FillInImplicitInterfaceMethods(interfaceMethods, targetMethods); } - void FillInImplicitInterfaceMethods(MethodInfo[] interfaceMethods, MethodInfo[] targetMethods) + void FillInImplicitInterfaceMethods(MethodInfo[] interfaceMethods, MethodInfo[] targetMethods) { MethodBase[] methods = null; @@ -1970,7 +1968,7 @@ public MethodBase __CreateMissingMethod(string name, CallingConventions callingC return CreateMissingMethod(name, callingConvention, returnType, parameterTypes, PackedCustomModifiers.CreateFromExternal(returnTypeCustomModifiers, parameterTypeCustomModifiers, parameterTypes.Length)); } - MethodBase CreateMissingMethod(string name, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, PackedCustomModifiers customModifiers) + MethodBase CreateMissingMethod(string name, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, PackedCustomModifiers customModifiers) { var sig = new MethodSignature(returnType ?? Module.Universe.System_Void, Util.Copy(parameterTypes), customModifiers, callingConvention, 0); var method = new MissingMethod(this, name, sig); diff --git a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs index 94939dec1..6363309cb 100644 --- a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs @@ -23,6 +23,7 @@ Jeroen Frijters */ using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.Diagnostics; using System.Linq; using System.Reflection; @@ -678,7 +679,7 @@ protected override void LazyPublishMethods() SetMethods(methods.ToArray()); } - private void AddMethods(IMethodSymbol[] add, List methods) + private void AddMethods(IReadOnlyList add, List methods) { foreach (var method in add) AddMethodOrConstructor(method, Context.AttributeHelper.GetHideFromJavaFlags(method), methods); From 6d06fdb9e6fb7323348247561c4a7aadbb87929a Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Mon, 28 Oct 2024 20:42:00 -0500 Subject: [PATCH 51/51] Hmmm --- .../AssemblyIdentityParts.cs | 489 ++++++++++ .../Buffers/SequenceReader.Search.cs | 861 ++++++++++++++++++ src/IKVM.CoreLib/Buffers/SequenceReader.cs | 431 ++++----- .../Buffers/SequenceReaderExtensions.cs | 35 - src/IKVM.CoreLib/Symbols/AssemblyIdentity.cs | 28 + .../Symbols/Emit/TypeSymbolBuilderBase.cs | 276 ++++-- src/IKVM.CoreLib/Symbols/ISymbolContext.cs | 8 + src/IKVM.CoreLib/Symbols/TypeSymbolName.cs | 503 ++++++++++ .../Symbols/TypeSymbolNameParserHelpers.cs | 62 +- .../Symbols/TypeSymbolNameParserResult.cs | 41 - .../Symbols/TypeSymbolNameReader.cs | 92 +- 11 files changed, 2357 insertions(+), 469 deletions(-) create mode 100644 src/IKVM.CoreLib/AssemblyIdentityParser/AssemblyIdentityParts.cs create mode 100644 src/IKVM.CoreLib/Buffers/SequenceReader.Search.cs create mode 100644 src/IKVM.CoreLib/Symbols/TypeSymbolName.cs delete mode 100644 src/IKVM.CoreLib/Symbols/TypeSymbolNameParserResult.cs diff --git a/src/IKVM.CoreLib/AssemblyIdentityParser/AssemblyIdentityParts.cs b/src/IKVM.CoreLib/AssemblyIdentityParser/AssemblyIdentityParts.cs new file mode 100644 index 000000000..73aaf0ddf --- /dev/null +++ b/src/IKVM.CoreLib/AssemblyIdentityParser/AssemblyIdentityParts.cs @@ -0,0 +1,489 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Globalization; +using System.Reflection; +using System.Runtime.CompilerServices; + +using IKVM.CoreLib.Text; + +namespace IKVM.CoreLib.Symbols +{ + + /// + /// Parses an assembly name. + /// + internal ref partial struct AssemblyIdentityParser + { + + public readonly struct AssemblyIdentityParts + { + + public AssemblyIdentityParts(string name, Version? version, string? cultureName, AssemblyNameFlags flags, byte[]? publicKeyOrToken) + { + _name = name; + _version = version; + _cultureName = cultureName; + _flags = flags; + _publicKeyOrToken = publicKeyOrToken; + } + + public readonly string _name; + public readonly Version? _version; + public readonly string? _cultureName; + public readonly AssemblyNameFlags _flags; + public readonly byte[]? _publicKeyOrToken; + + } + + /// + /// Token categories for the lexer. + /// + private enum Token + { + Equals = 1, + Comma = 2, + String = 3, + End = 4, + } + + private enum AttributeKind + { + Version = 1, + Culture = 2, + PublicKeyOrToken = 4, + ProcessorArchitecture = 8, + Retargetable = 16, + ContentType = 32 + } + + private readonly ReadOnlySpan _input; + private int _index; + + private AssemblyIdentityParser(ReadOnlySpan input) + { + if (input.Length == 0) + throw new ArgumentException(nameof(input)); + + _input = input; + _index = 0; + } + + internal static bool TryParse(ReadOnlySpan name, ref AssemblyIdentityParts parts) + { + AssemblyIdentityParser parser = new(name); + return parser.TryParse(ref parts); + } + + private static bool TryRecordNewSeen(scoped ref AttributeKind seenAttributes, AttributeKind newAttribute) + { + if ((seenAttributes & newAttribute) != 0) + { + return false; + } + seenAttributes |= newAttribute; + return true; + } + + private bool TryParse(ref AssemblyIdentityParts result) + { + // Name must come first. + if (!TryGetNextToken(out string name, out Token token) || token != Token.String || string.IsNullOrEmpty(name)) + return false; + + Version? version = null; + string? cultureName = null; + byte[]? pkt = null; + AssemblyNameFlags flags = 0; + + AttributeKind alreadySeen = default; + if (!TryGetNextToken(out _, out token)) + return false; + + while (token != Token.End) + { + if (token != Token.Comma) + return false; + + if (!TryGetNextToken(out string attributeName, out token) || token != Token.String) + return false; + + if (!TryGetNextToken(out _, out token) || token != Token.Equals) + return false; + + if (!TryGetNextToken(out string attributeValue, out token) || token != Token.String) + return false; + + if (attributeName == string.Empty) + return false; + + if (IsAttribute(attributeName, "Version")) + { + if (!TryRecordNewSeen(ref alreadySeen, AttributeKind.Version)) + { + return false; + } + if (!TryParseVersion(attributeValue, ref version)) + { + return false; + } + } + else if (IsAttribute(attributeName, "Culture")) + { + if (!TryRecordNewSeen(ref alreadySeen, AttributeKind.Culture)) + { + return false; + } + if (!TryParseCulture(attributeValue, out cultureName)) + { + return false; + } + } + else if (IsAttribute(attributeName, "PublicKeyToken")) + { + if (!TryRecordNewSeen(ref alreadySeen, AttributeKind.PublicKeyOrToken)) + { + return false; + } + if (!TryParsePKT(attributeValue, isToken: true, out pkt)) + { + return false; + } + } + else if (IsAttribute(attributeName, "PublicKey")) + { + if (!TryRecordNewSeen(ref alreadySeen, AttributeKind.PublicKeyOrToken)) + { + return false; + } + if (!TryParsePKT(attributeValue, isToken: false, out pkt)) + { + return false; + } + flags |= AssemblyNameFlags.PublicKey; + } + else if (IsAttribute(attributeName, "ProcessorArchitecture")) + { + if (!TryRecordNewSeen(ref alreadySeen, AttributeKind.ProcessorArchitecture)) + { + return false; + } + if (!TryParseProcessorArchitecture(attributeValue, out ProcessorArchitecture arch)) + { + return false; + } + flags |= (AssemblyNameFlags)(((int)arch) << 4); + } + else if (IsAttribute(attributeName, "Retargetable")) + { + if (!TryRecordNewSeen(ref alreadySeen, AttributeKind.Retargetable)) + { + return false; + } + + if (attributeValue.Equals("Yes", StringComparison.OrdinalIgnoreCase)) + { + flags |= AssemblyNameFlags.Retargetable; + } + else if (attributeValue.Equals("No", StringComparison.OrdinalIgnoreCase)) + { + // nothing to do + } + else + { + return false; + } + } + else if (IsAttribute(attributeName, "ContentType")) + { + if (!TryRecordNewSeen(ref alreadySeen, AttributeKind.ContentType)) + { + return false; + } + + if (attributeValue.Equals("WindowsRuntime", StringComparison.OrdinalIgnoreCase)) + { + flags |= (AssemblyNameFlags)(((int)AssemblyContentType.WindowsRuntime) << 9); + } + else + { + return false; + } + } + else + { + // Desktop compat: If we got here, the attribute name is unknown to us. Ignore it. + } + + if (!TryGetNextToken(out _, out token)) + { + return false; + } + } + + result = new AssemblyIdentityParts(name, version, cultureName, flags, pkt); + return true; + } + + private static bool IsAttribute(string candidate, string attributeKind) + => candidate.Equals(attributeKind, StringComparison.OrdinalIgnoreCase); + + private static bool TryParseVersion(string attributeValue, ref Version? version) + { +#if NET8_0_OR_GREATER + ReadOnlySpan attributeValueSpan = attributeValue; + Span parts = stackalloc Range[5]; + parts = parts.Slice(0, attributeValueSpan.Split(parts, '.')); +#else + string[] parts = attributeValue.Split('.'); +#endif + if (parts.Length is < 2 or > 4) + { + return false; + } + + Span versionNumbers = [ushort.MaxValue, ushort.MaxValue, ushort.MaxValue, ushort.MaxValue]; + for (int i = 0; i < parts.Length; i++) + { + if (!ushort.TryParse( +#if NET8_0_OR_GREATER + attributeValueSpan[parts[i]], +#else + parts[i], +#endif + NumberStyles.None, NumberFormatInfo.InvariantInfo, out versionNumbers[i])) + { + return false; + } + } + + if (versionNumbers[0] == ushort.MaxValue || + versionNumbers[1] == ushort.MaxValue) + { + return false; + } + + version = + versionNumbers[2] == ushort.MaxValue ? new Version(versionNumbers[0], versionNumbers[1]) : + versionNumbers[3] == ushort.MaxValue ? new Version(versionNumbers[0], versionNumbers[1], versionNumbers[2]) : + new Version(versionNumbers[0], versionNumbers[1], versionNumbers[2], versionNumbers[3]); + + return true; + } + + private static bool TryParseCulture(string attributeValue, out string? result) + { + if (attributeValue.Equals("Neutral", StringComparison.OrdinalIgnoreCase)) + { + result = ""; + return true; + } + + result = attributeValue; + return true; + } + + private static bool TryParsePKT(string attributeValue, bool isToken, out byte[]? result) + { + if (attributeValue.Equals("null", StringComparison.OrdinalIgnoreCase) || attributeValue == string.Empty) + { + result = Array.Empty(); + return true; + } + + if (attributeValue.Length % 2 != 0 || (isToken && attributeValue.Length != 8 * 2)) + { + result = null; + return false; + } + + byte[] pkt = new byte[attributeValue.Length / 2]; + if (!HexConverter.TryDecodeFromUtf16(attributeValue.AsSpan(), pkt, out int _)) + { + result = null; + return false; + } + + result = pkt; + return true; + } + + private static bool TryParseProcessorArchitecture(string attributeValue, out ProcessorArchitecture result) + { + result = attributeValue switch + { + _ when attributeValue.Equals("msil", StringComparison.OrdinalIgnoreCase) => ProcessorArchitecture.MSIL, + _ when attributeValue.Equals("x86", StringComparison.OrdinalIgnoreCase) => ProcessorArchitecture.X86, + _ when attributeValue.Equals("ia64", StringComparison.OrdinalIgnoreCase) => ProcessorArchitecture.IA64, + _ when attributeValue.Equals("amd64", StringComparison.OrdinalIgnoreCase) => ProcessorArchitecture.Amd64, + _ when attributeValue.Equals("arm", StringComparison.OrdinalIgnoreCase) => ProcessorArchitecture.Arm, + _ when attributeValue.Equals("msil", StringComparison.OrdinalIgnoreCase) => ProcessorArchitecture.MSIL, + _ => ProcessorArchitecture.None + }; + return result != ProcessorArchitecture.None; + } + + private static bool IsWhiteSpace(char ch) + => ch is '\n' or '\r' or ' ' or '\t'; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private bool TryGetNextChar(out char ch) + { + if (_index < _input.Length) + { + ch = _input[_index++]; + if (ch == '\0') + { + return false; + } + } + else + { + ch = '\0'; + } + + return true; + } + + // + // Return the next token in assembly name. If the result is Token.String, + // sets "tokenString" to the tokenized string. + // + private bool TryGetNextToken(out string tokenString, out Token token) + { + tokenString = string.Empty; + char c; + + while (true) + { + if (!TryGetNextChar(out c)) + { + token = default; + return false; + } + + switch (c) + { + case ',': + { + token = Token.Comma; + return true; + } + case '=': + { + token = Token.Equals; + return true; + } + case '\0': + { + token = Token.End; + return true; + } + } + + if (!IsWhiteSpace(c)) + { + break; + } + } + + using ValueStringBuilder sb = new ValueStringBuilder(stackalloc char[64]); + + char quoteChar = '\0'; + if (c is '\'' or '\"') + { + quoteChar = c; + if (!TryGetNextChar(out c)) + { + token = default; + return false; + } + } + + for (; ; ) + { + if (c == 0) + { + if (quoteChar != 0) + { + // EOS and unclosed quotes is an error + token = default; + return false; + } + // Reached end of input and therefore of string + break; + } + + if (quoteChar != 0 && c == quoteChar) + break; // Terminate: Found closing quote of quoted string. + + if (quoteChar == 0 && (c is ',' or '=')) + { + _index--; + break; // Terminate: Found start of a new ',' or '=' token. + } + + if (quoteChar == 0 && (c is '\'' or '\"')) + { + token = default; + return false; + } + + if (c is '\\') + { + if (!TryGetNextChar(out c)) + { + token = default; + return false; + } + + switch (c) + { + case '\\': + case ',': + case '=': + case '\'': + case '"': + sb.Append(c); + break; + case 't': + sb.Append('\t'); + break; + case 'r': + sb.Append('\r'); + break; + case 'n': + sb.Append('\n'); + break; + default: + token = default; + return false; + } + } + else + { + sb.Append(c); + } + + if (!TryGetNextChar(out c)) + { + token = default; + return false; + } + } + + + int length = sb.Length; + if (quoteChar == 0) + { + while (length > 0 && IsWhiteSpace(sb[length - 1])) + length--; + } + + tokenString = sb.AsSpan(0, length).ToString(); + token = Token.String; + return true; + } + } +} \ No newline at end of file diff --git a/src/IKVM.CoreLib/Buffers/SequenceReader.Search.cs b/src/IKVM.CoreLib/Buffers/SequenceReader.Search.cs new file mode 100644 index 000000000..c6f68c37a --- /dev/null +++ b/src/IKVM.CoreLib/Buffers/SequenceReader.Search.cs @@ -0,0 +1,861 @@ +#if NETFRAMEWORK + +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Buffers; +using System.Diagnostics; +using System.Runtime.CompilerServices; + +namespace IKVM.CoreLib.Buffers +{ + + internal ref partial struct SequenceReader + where T : unmanaged, IEquatable + { + + /// + /// Try to read everything up to the given . + /// + /// The read data, if any. + /// The delimiter to look for. + /// True to move past the if found. + /// True if the was found. + public bool TryReadTo(out ReadOnlySpan span, T delimiter, bool advancePastDelimiter = true) + { + ReadOnlySpan remaining = UnreadSpan; + int index = remaining.IndexOf(delimiter); + + if (index != -1) + { + span = index == 0 ? default : remaining.Slice(0, index); + AdvanceCurrentSpan(index + (advancePastDelimiter ? 1 : 0)); + return true; + } + + return TryReadToSlow(out span, delimiter, advancePastDelimiter); + } + + private bool TryReadToSlow(out ReadOnlySpan span, T delimiter, bool advancePastDelimiter) + { + if (!TryReadToInternal(out ReadOnlySequence sequence, delimiter, advancePastDelimiter, CurrentSpan.Length - CurrentSpanIndex)) + { + span = default; + return false; + } + + span = sequence.IsSingleSegment ? sequence.First.Span : sequence.ToArray(); + return true; + } + + /// + /// Try to read everything up to the given , ignoring delimiters that are + /// preceded by . + /// + /// The read data, if any. + /// The delimiter to look for. + /// If found prior to it will skip that occurrence. + /// True to move past the if found. + /// True if the was found. + public bool TryReadTo(out ReadOnlySpan span, T delimiter, T delimiterEscape, bool advancePastDelimiter = true) + { + ReadOnlySpan remaining = UnreadSpan; + int index = remaining.IndexOf(delimiter); + + if ((index > 0 && !remaining[index - 1].Equals(delimiterEscape)) || index == 0) + { + span = remaining.Slice(0, index); + AdvanceCurrentSpan(index + (advancePastDelimiter ? 1 : 0)); + return true; + } + + // This delimiter might be skipped, go down the slow path + return TryReadToSlow(out span, delimiter, delimiterEscape, index, advancePastDelimiter); + } + + private bool TryReadToSlow(out ReadOnlySpan span, T delimiter, T delimiterEscape, int index, bool advancePastDelimiter) + { + if (!TryReadToSlow(out ReadOnlySequence sequence, delimiter, delimiterEscape, index, advancePastDelimiter)) + { + span = default; + return false; + } + + Debug.Assert(sequence.Length > 0); + span = sequence.IsSingleSegment ? sequence.First.Span : sequence.ToArray(); + return true; + } + + private bool TryReadToSlow(out ReadOnlySequence sequence, T delimiter, T delimiterEscape, int index, bool advancePastDelimiter) + { + SequenceReader copy = this; + + ReadOnlySpan remaining = UnreadSpan; + bool priorEscape = false; + + do + { + if (index >= 0) + { + if (index == 0 && priorEscape) + { + // We were in the escaped state, so skip this delimiter + priorEscape = false; + Advance(index + 1); + remaining = UnreadSpan; + goto Continue; + } + else if (index > 0 && remaining[index - 1].Equals(delimiterEscape)) + { + // This delimiter might be skipped + + // Count our escapes + int escapeCount = 1; + int i = index - 2; + for (; i >= 0; i--) + { + if (!remaining[i].Equals(delimiterEscape)) + break; + } + if (i < 0 && priorEscape) + { + // Started and ended with escape, increment once more + escapeCount++; + } + escapeCount += index - 2 - i; + + if ((escapeCount & 1) != 0) + { + // An odd escape count means we're currently escaped, + // skip the delimiter and reset escaped state. + Advance(index + 1); + priorEscape = false; + remaining = UnreadSpan; + goto Continue; + } + } + + // Found the delimiter. Move to it, slice, then move past it. + AdvanceCurrentSpan(index); + + sequence = Sequence.Slice(copy.Position, Position); + if (advancePastDelimiter) + { + Advance(1); + } + return true; + } + else + { + // No delimiter, need to check the end of the span for odd number of escapes then advance + if (remaining.EndsWith([delimiterEscape])) + { + int escapeCount = 1; + int i = remaining.Length - 2; + for (; i >= 0; i--) + { + if (!remaining[i].Equals(delimiterEscape)) + break; + } + + escapeCount += remaining.Length - 2 - i; + if (i < 0 && priorEscape) + priorEscape = (escapeCount & 1) == 0; // equivalent to incrementing escapeCount before setting priorEscape + else + priorEscape = (escapeCount & 1) != 0; + } + else + { + priorEscape = false; + } + } + + // Nothing in the current span, move to the end, checking for the skip delimiter + AdvanceCurrentSpan(remaining.Length); + remaining = CurrentSpan; + + Continue: + index = remaining.IndexOf(delimiter); + } while (!End); + + // Didn't find anything, reset our original state. + this = copy; + sequence = default; + return false; + } + + /// + /// Try to read everything up to the given . + /// + /// The read data, if any. + /// The delimiter to look for. + /// True to move past the if found. + /// True if the was found. + public bool TryReadTo(out ReadOnlySequence sequence, T delimiter, bool advancePastDelimiter = true) + { + return TryReadToInternal(out sequence, delimiter, advancePastDelimiter); + } + + private bool TryReadToInternal(out ReadOnlySequence sequence, T delimiter, bool advancePastDelimiter, int skip = 0) + { + Debug.Assert(skip >= 0); + SequenceReader copy = this; + if (skip > 0) + Advance(skip); + ReadOnlySpan remaining = UnreadSpan; + + while (_moreData) + { + int index = remaining.IndexOf(delimiter); + if (index != -1) + { + // Found the delimiter. Move to it, slice, then move past it. + if (index > 0) + { + AdvanceCurrentSpan(index); + } + + sequence = Sequence.Slice(copy.Position, Position); + if (advancePastDelimiter) + { + Advance(1); + } + return true; + } + + AdvanceCurrentSpan(remaining.Length); + remaining = CurrentSpan; + } + + // Didn't find anything, reset our original state. + this = copy; + sequence = default; + return false; + } + + /// + /// Try to read everything up to the given , ignoring delimiters that are + /// preceded by . + /// + /// The read data, if any. + /// The delimiter to look for. + /// If found prior to it will skip that occurrence. + /// True to move past the if found. + /// True if the was found. + public bool TryReadTo(out ReadOnlySequence sequence, T delimiter, T delimiterEscape, bool advancePastDelimiter = true) + { + SequenceReader copy = this; + + ReadOnlySpan remaining = UnreadSpan; + bool priorEscape = false; + + while (_moreData) + { + int index = remaining.IndexOf(delimiter); + if (index != -1) + { + if (index == 0 && priorEscape) + { + // We were in the escaped state, so skip this delimiter + priorEscape = false; + Advance(index + 1); + remaining = UnreadSpan; + continue; + } + else if (index > 0 && remaining[index - 1].Equals(delimiterEscape)) + { + // This delimiter might be skipped + + // Count our escapes + int escapeCount = 0; + for (int i = index; i > 0 && remaining[i - 1].Equals(delimiterEscape); i--, escapeCount++) + ; + if (escapeCount == index && priorEscape) + { + // Started and ended with escape, increment once more + escapeCount++; + } + + priorEscape = false; + if ((escapeCount & 1) != 0) + { + // Odd escape count means we're in the escaped state, so skip this delimiter + Advance(index + 1); + remaining = UnreadSpan; + continue; + } + } + + // Found the delimiter. Move to it, slice, then move past it. + if (index > 0) + { + Advance(index); + } + + sequence = Sequence.Slice(copy.Position, Position); + if (advancePastDelimiter) + { + Advance(1); + } + return true; + } + + // No delimiter, need to check the end of the span for odd number of escapes then advance + { + int escapeCount = 0; + for (int i = remaining.Length; i > 0 && remaining[i - 1].Equals(delimiterEscape); i--, escapeCount++) + ; + if (priorEscape && escapeCount == remaining.Length) + { + escapeCount++; + } + priorEscape = escapeCount % 2 != 0; + } + + // Nothing in the current span, move to the end, checking for the skip delimiter + Advance(remaining.Length); + remaining = CurrentSpan; + } + + // Didn't find anything, reset our original state. + this = copy; + sequence = default; + return false; + } + + /// + /// Try to read everything up to the given . + /// + /// The read data, if any. + /// The delimiters to look for. + /// True to move past the first found instance of any of the given . + /// True if any of the were found. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryReadToAny(out ReadOnlySpan span, scoped ReadOnlySpan delimiters, bool advancePastDelimiter = true) + { + ReadOnlySpan remaining = UnreadSpan; + int index = delimiters.Length == 2 + ? remaining.IndexOfAny(delimiters[0], delimiters[1]) + : remaining.IndexOfAny(delimiters); + + if (index != -1) + { + span = remaining.Slice(0, index); + Advance(index + (advancePastDelimiter ? 1 : 0)); + return true; + } + + return TryReadToAnySlow(out span, delimiters, advancePastDelimiter); + } + + private bool TryReadToAnySlow(out ReadOnlySpan span, scoped ReadOnlySpan delimiters, bool advancePastDelimiter) + { + if (!TryReadToAnyInternal(out ReadOnlySequence sequence, delimiters, advancePastDelimiter, CurrentSpan.Length - CurrentSpanIndex)) + { + span = default; + return false; + } + + span = sequence.IsSingleSegment ? sequence.First.Span : sequence.ToArray(); + return true; + } + + /// + /// Try to read everything up to the given . + /// + /// The read data, if any. + /// The delimiters to look for. + /// True to move past the first found instance of any of the given . + /// True if any of the were found. + public bool TryReadToAny(out ReadOnlySequence sequence, scoped ReadOnlySpan delimiters, bool advancePastDelimiter = true) + { + return TryReadToAnyInternal(out sequence, delimiters, advancePastDelimiter); + } + + private bool TryReadToAnyInternal(out ReadOnlySequence sequence, scoped ReadOnlySpan delimiters, bool advancePastDelimiter, int skip = 0) + { + SequenceReader copy = this; + if (skip > 0) + Advance(skip); + ReadOnlySpan remaining = UnreadSpan; + + while (!End) + { + int index = delimiters.Length == 2 + ? remaining.IndexOfAny(delimiters[0], delimiters[1]) + : remaining.IndexOfAny(delimiters); + + if (index != -1) + { + // Found one of the delimiters. Move to it, slice, then move past it. + if (index > 0) + { + AdvanceCurrentSpan(index); + } + + sequence = Sequence.Slice(copy.Position, Position); + if (advancePastDelimiter) + { + Advance(1); + } + return true; + } + + Advance(remaining.Length); + remaining = CurrentSpan; + } + + // Didn't find anything, reset our original state. + this = copy; + sequence = default; + return false; + } + + /// + /// Try to read everything up to the given . + /// + /// The read data, if any. + /// The delimiter to look for. + /// True to move past the if found. + /// True if the was found. + public bool TryReadTo(out ReadOnlySpan span, scoped ReadOnlySpan delimiter, bool advancePastDelimiter = true) + { + ReadOnlySpan remaining = UnreadSpan; + int index = remaining.IndexOf(delimiter); + + if (index >= 0) + { + span = remaining.Slice(0, index); + AdvanceCurrentSpan(index + (advancePastDelimiter ? delimiter.Length : 0)); + return true; + } + + // This delimiter might be skipped, go down the slow path + return TryReadToSlow(out span, delimiter, advancePastDelimiter); + } + + private bool TryReadToSlow(out ReadOnlySpan span, scoped ReadOnlySpan delimiter, bool advancePastDelimiter) + { + if (!TryReadTo(out ReadOnlySequence sequence, delimiter, advancePastDelimiter)) + { + span = default; + return false; + } + + Debug.Assert(sequence.Length > 0); + span = sequence.IsSingleSegment ? sequence.First.Span : sequence.ToArray(); + return true; + } + + /// + /// Try to read data until the entire given matches. + /// + /// The read data, if any. + /// The multi (T) delimiter. + /// True to move past the if found. + /// True if the was found. + public bool TryReadTo(out ReadOnlySequence sequence, scoped ReadOnlySpan delimiter, bool advancePastDelimiter = true) + { + if (delimiter.Length == 0) + { + sequence = default; + return true; + } + + SequenceReader copy = this; + + bool advanced = false; + while (!End) + { + if (!TryReadTo(out sequence, delimiter[0], advancePastDelimiter: false)) + { + this = copy; + return false; + } + + if (delimiter.Length == 1) + { + if (advancePastDelimiter) + { + Advance(1); + } + return true; + } + + if (IsNext(delimiter)) + { + // Probably a faster way to do this, potentially by avoiding the Advance in the previous TryReadTo call + if (advanced) + { + sequence = copy.Sequence.Slice(copy.Consumed, Consumed - copy.Consumed); + } + + if (advancePastDelimiter) + { + Advance(delimiter.Length); + } + return true; + } + else + { + Advance(1); + advanced = true; + } + } + + this = copy; + sequence = default; + return false; + } + + /// + /// Try to read data with given . + /// + /// Read count. + /// The read data, if successfully read requested data. + /// true if remaining items in current is enough for . + public bool TryReadExact(int count, out ReadOnlySequence sequence) + { + if (count < 0) + { + throw new ArgumentOutOfRangeException(nameof(count)); + } + + if (count > Remaining) + { + sequence = default; + return false; + } + + sequence = Sequence.Slice(Position, count); + if (count != 0) + { + Advance(count); + } + return true; + } + + /// + /// Advance until the given , if found. + /// + /// The delimiter to search for. + /// True to move past the if found. + /// True if the given was found. + public bool TryAdvanceTo(T delimiter, bool advancePastDelimiter = true) + { + ReadOnlySpan remaining = UnreadSpan; + int index = remaining.IndexOf(delimiter); + if (index != -1) + { + Advance(advancePastDelimiter ? index + 1 : index); + return true; + } + + return TryReadToInternal(out _, delimiter, advancePastDelimiter); + } + + /// + /// Advance until any of the given , if found. + /// + /// The delimiters to search for. + /// True to move past the first found instance of any of the given . + /// True if any of the given were found. + public bool TryAdvanceToAny(scoped ReadOnlySpan delimiters, bool advancePastDelimiter = true) + { + ReadOnlySpan remaining = UnreadSpan; + int index = remaining.IndexOfAny(delimiters); + if (index != -1) + { + AdvanceCurrentSpan(index + (advancePastDelimiter ? 1 : 0)); + return true; + } + + return TryReadToAnyInternal(out _, delimiters, advancePastDelimiter); + } + + /// + /// Advance past consecutive instances of the given . + /// + /// How many positions the reader has been advanced. + public long AdvancePast(T value) + { + long start = Consumed; + + do + { + // Advance past all matches in the current span + int i; + for (i = CurrentSpanIndex; i < CurrentSpan.Length && CurrentSpan[i].Equals(value); i++) + { + } + + int advanced = i - CurrentSpanIndex; + if (advanced == 0) + { + // Didn't advance at all in this span, exit. + break; + } + + AdvanceCurrentSpan(advanced); + + // If we're at position 0 after advancing and not at the End, + // we're in a new span and should continue the loop. + } while (CurrentSpanIndex == 0 && !End); + + return Consumed - start; + } + + /// + /// Skip consecutive instances of any of the given . + /// + /// How many positions the reader has been advanced. + public long AdvancePastAny(scoped ReadOnlySpan values) + { + long start = Consumed; + + do + { + // Advance past all matches in the current span + int i; + for (i = CurrentSpanIndex; i < CurrentSpan.Length && values.IndexOf(CurrentSpan[i]) != -1; i++) + { + } + + int advanced = i - CurrentSpanIndex; + if (advanced == 0) + { + // Didn't advance at all in this span, exit. + break; + } + + AdvanceCurrentSpan(advanced); + + // If we're at position 0 after advancing and not at the End, + // we're in a new span and should continue the loop. + } while (CurrentSpanIndex == 0 && !End); + + return Consumed - start; + } + + /// + /// Advance past consecutive instances of any of the given values. + /// + /// How many positions the reader has been advanced. + public long AdvancePastAny(T value0, T value1, T value2, T value3) + { + long start = Consumed; + + do + { + // Advance past all matches in the current span + int i; + for (i = CurrentSpanIndex; i < CurrentSpan.Length; i++) + { + T value = CurrentSpan[i]; + if (!value.Equals(value0) && !value.Equals(value1) && !value.Equals(value2) && !value.Equals(value3)) + { + break; + } + } + + int advanced = i - CurrentSpanIndex; + if (advanced == 0) + { + // Didn't advance at all in this span, exit. + break; + } + + AdvanceCurrentSpan(advanced); + + // If we're at position 0 after advancing and not at the End, + // we're in a new span and should continue the loop. + } while (CurrentSpanIndex == 0 && !End); + + return Consumed - start; + } + + /// + /// Advance past consecutive instances of any of the given values. + /// + /// How many positions the reader has been advanced. + public long AdvancePastAny(T value0, T value1, T value2) + { + long start = Consumed; + + do + { + // Advance past all matches in the current span + int i; + for (i = CurrentSpanIndex; i < CurrentSpan.Length; i++) + { + T value = CurrentSpan[i]; + if (!value.Equals(value0) && !value.Equals(value1) && !value.Equals(value2)) + { + break; + } + } + + int advanced = i - CurrentSpanIndex; + if (advanced == 0) + { + // Didn't advance at all in this span, exit. + break; + } + + AdvanceCurrentSpan(advanced); + + // If we're at position 0 after advancing and not at the End, + // we're in a new span and should continue the loop. + } while (CurrentSpanIndex == 0 && !End); + + return Consumed - start; + } + + /// + /// Advance past consecutive instances of any of the given values. + /// + /// How many positions the reader has been advanced. + public long AdvancePastAny(T value0, T value1) + { + long start = Consumed; + + do + { + // Advance past all matches in the current span + int i; + for (i = CurrentSpanIndex; i < CurrentSpan.Length; i++) + { + T value = CurrentSpan[i]; + if (!value.Equals(value0) && !value.Equals(value1)) + { + break; + } + } + + int advanced = i - CurrentSpanIndex; + if (advanced == 0) + { + // Didn't advance at all in this span, exit. + break; + } + + AdvanceCurrentSpan(advanced); + + // If we're at position 0 after advancing and not at the End, + // we're in a new span and should continue the loop. + } while (CurrentSpanIndex == 0 && !End); + + return Consumed - start; + } + + /// + /// Moves the reader to the end of the sequence. + /// + public void AdvanceToEnd() + { + if (_moreData) + { + Consumed = Length; + CurrentSpan = default; + CurrentSpanIndex = 0; + _currentPosition = Sequence.End; + _nextPosition = default; + _moreData = false; + } + } + + /// + /// Check to see if the given value is next. + /// + /// The value to compare the next items to. + /// Move past the value if found. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool IsNext(T next, bool advancePast = false) + { + if (End) + return false; + + if (CurrentSpan[CurrentSpanIndex].Equals(next)) + { + if (advancePast) + { + AdvanceCurrentSpan(1); + } + return true; + } + return false; + } + + /// + /// Check to see if the given values are next. + /// + /// The span to compare the next items to. + /// Move past the values if found. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool IsNext(scoped ReadOnlySpan next, bool advancePast = false) + { + ReadOnlySpan unread = UnreadSpan; + if (unread.StartsWith(next)) + { + if (advancePast) + { + AdvanceCurrentSpan(next.Length); + } + return true; + } + + // Only check the slow path if there wasn't enough to satisfy next + return unread.Length < next.Length && IsNextSlow(next, advancePast); + } + + private bool IsNextSlow(scoped ReadOnlySpan next, bool advancePast) + { + ReadOnlySpan currentSpan = UnreadSpan; + + // We should only come in here if we need more data than we have in our current span + Debug.Assert(currentSpan.Length < next.Length); + + int fullLength = next.Length; + SequencePosition nextPosition = _nextPosition; + + while (next.StartsWith(currentSpan)) + { + if (next.Length == currentSpan.Length) + { + // Fully matched + if (advancePast) + { + Advance(fullLength); + } + return true; + } + + // Need to check the next segment + while (true) + { + if (!Sequence.TryGet(ref nextPosition, out ReadOnlyMemory nextSegment, advance: true)) + { + // Nothing left + return false; + } + + if (nextSegment.Length > 0) + { + next = next.Slice(currentSpan.Length); + currentSpan = nextSegment.Span; + if (currentSpan.Length > next.Length) + { + currentSpan = currentSpan.Slice(0, next.Length); + } + break; + } + } + } + + return false; + } + } +} + +#endif diff --git a/src/IKVM.CoreLib/Buffers/SequenceReader.cs b/src/IKVM.CoreLib/Buffers/SequenceReader.cs index 853c59328..ddca1d188 100644 --- a/src/IKVM.CoreLib/Buffers/SequenceReader.cs +++ b/src/IKVM.CoreLib/Buffers/SequenceReader.cs @@ -1,9 +1,7 @@ -// Copyright (c) All contributors. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. +#if NETFRAMEWORK -/* Licensed to the .NET Foundation under one or more agreements. - * The .NET Foundation licenses this file to you under the MIT license. - * See the LICENSE file in the project root for more information. */ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. using System; using System.Buffers; @@ -13,169 +11,104 @@ namespace IKVM.CoreLib.Buffers { -#if NETFRAMEWORK - - internal ref partial struct SequenceReader - where T : unmanaged, IEquatable + ref partial struct SequenceReader where T : unmanaged, IEquatable { - /// - /// A value indicating whether we're using (as opposed to . - /// - private bool usingSequence; + private SequencePosition _currentPosition; + private SequencePosition _nextPosition; + private bool _moreData; + private readonly long _length; /// - /// Backing for the entire sequence when we're not using . - /// - private ReadOnlySequence sequence; - - /// - /// The position at the start of the . - /// - private SequencePosition currentPosition; - - /// - /// The position at the end of the . - /// - private SequencePosition nextPosition; - - /// - /// Backing for the entire sequence when we're not using . - /// - private ReadOnlyMemory memory; - - /// - /// A value indicating whether there is unread data remaining. - /// - private bool moreData; - - /// - /// The total number of elements in the sequence. - /// - private long length; - - /// - /// Initializes a new instance of the struct - /// over the given . + /// Create a over the given . /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public SequenceReader(ReadOnlySequence sequence) { - this.usingSequence = true; - this.CurrentSpanIndex = 0; - this.Consumed = 0; - this.sequence = sequence; - this.memory = default; - this.currentPosition = sequence.Start; - this.length = -1; + CurrentSpanIndex = 0; + Consumed = 0; + Sequence = sequence; + _currentPosition = sequence.Start; + _length = -1; ReadOnlySpan first = sequence.First.Span; - this.nextPosition = sequence.GetPosition(first.Length); - this.CurrentSpan = first; - this.moreData = first.Length > 0; + _nextPosition = sequence.GetPosition(first.Length); + CurrentSpan = first; + _moreData = first.Length > 0; - if (!this.moreData && !sequence.IsSingleSegment) + if (!_moreData && !sequence.IsSingleSegment) { - this.moreData = true; - this.GetNextSpan(); + _moreData = true; + GetNextSpan(); } } /// - /// Initializes a new instance of the struct - /// over the given . + /// True when there is no more data in the . /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public SequenceReader(ReadOnlyMemory memory) - { - this.usingSequence = false; - this.CurrentSpanIndex = 0; - this.Consumed = 0; - this.memory = memory; - this.CurrentSpan = memory.Span; - this.length = memory.Length; - this.moreData = memory.Length > 0; - - this.currentPosition = default; - this.nextPosition = default; - this.sequence = default; - } + public readonly bool End => !_moreData; /// - /// Gets a value indicating whether there is no more data in the . + /// The underlying for the reader. /// - public bool End => !this.moreData; + public ReadOnlySequence Sequence { get; } /// - /// Gets the underlying for the reader. + /// Gets the unread portion of the . /// - public ReadOnlySequence Sequence - { - get - { - if (this.sequence.IsEmpty && !this.memory.IsEmpty) - { - // We're in memory mode (instead of sequence mode). - // Lazily fill in the sequence data. - this.sequence = new ReadOnlySequence(this.memory); - this.currentPosition = this.sequence.Start; - this.nextPosition = this.sequence.End; - } - - return this.sequence; - } - } + /// + /// The unread portion of the . + /// + public readonly ReadOnlySequence UnreadSequence => Sequence.Slice(Position); /// - /// Gets the current position in the . + /// The current position in the . /// - public SequencePosition Position - => this.Sequence.GetPosition(this.CurrentSpanIndex, this.currentPosition); + public readonly SequencePosition Position + => Sequence.GetPosition(CurrentSpanIndex, _currentPosition); /// - /// Gets the current segment in the as a span. + /// The current segment in the as a span. /// public ReadOnlySpan CurrentSpan { get; private set; } /// - /// Gets the index in the . + /// The index in the . /// public int CurrentSpanIndex { get; private set; } /// - /// Gets the unread portion of the . + /// The unread portion of the . /// - public ReadOnlySpan UnreadSpan + public readonly ReadOnlySpan UnreadSpan { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => this.CurrentSpan.Slice(this.CurrentSpanIndex); + get => CurrentSpan.Slice(CurrentSpanIndex); } /// - /// Gets the total number of 's processed by the reader. + /// The total number of 's processed by the reader. /// public long Consumed { get; private set; } /// - /// Gets remaining 's in the reader's . + /// Remaining 's in the reader's . /// - public long Remaining => this.Length - this.Consumed; + public readonly long Remaining => Length - Consumed; /// - /// Gets count of in the reader's . + /// Count of in the reader's . /// - public long Length + public readonly long Length { - [MethodImpl(MethodImplOptions.AggressiveInlining)] get { - if (this.length < 0) + if (_length < 0) { - // Cache the length - this.length = this.Sequence.Length; + // Cast-away readonly to initialize lazy field + Unsafe.AsRef(in _length) = Sequence.Length; } - - return this.length; + return _length; } } @@ -185,11 +118,11 @@ public long Length /// The next value or default if at the end. /// False if at the end of the reader. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool TryPeek(out T value) + public readonly bool TryPeek(out T value) { - if (this.moreData) + if (_moreData) { - value = this.CurrentSpan[this.CurrentSpanIndex]; + value = CurrentSpan[CurrentSpanIndex]; return true; } else @@ -199,6 +132,64 @@ public bool TryPeek(out T value) } } + /// + /// Peeks at the next value at specific offset without advancing the reader. + /// + /// The offset from current position. + /// The next value, or the default value if at the end of the reader. + /// true if the reader is not at its end and the peek operation succeeded; false if at the end of the reader. + public readonly bool TryPeek(long offset, out T value) + { + if (offset < 0) + throw new ArgumentOutOfRangeException(nameof(offset)); + + // If we've got data and offset is not out of bounds + if (!_moreData || Remaining <= offset) + { + value = default; + return false; + } + + // Sum CurrentSpanIndex + offset could overflow as is but the value of offset should be very large + // because we check Remaining <= offset above so to overflow we should have a ReadOnlySequence close to 8 exabytes + Debug.Assert(CurrentSpanIndex + offset >= 0); + + // If offset doesn't fall inside current segment move to next until we find correct one + if ((CurrentSpanIndex + offset) <= CurrentSpan.Length - 1) + { + Debug.Assert(offset <= int.MaxValue); + + value = CurrentSpan[CurrentSpanIndex + (int)offset]; + return true; + } + else + { + long remainingOffset = offset - (CurrentSpan.Length - CurrentSpanIndex); + SequencePosition nextPosition = _nextPosition; + ReadOnlyMemory currentMemory; + + while (Sequence.TryGet(ref nextPosition, out currentMemory, advance: true)) + { + // Skip empty segment + if (currentMemory.Length > 0) + { + if (remainingOffset >= currentMemory.Length) + { + // Subtract current non consumed data + remainingOffset -= currentMemory.Length; + } + else + { + break; + } + } + } + + value = currentMemory.Span[(int)remainingOffset]; + return true; + } + } + /// /// Read the next value and advance the reader. /// @@ -207,26 +198,19 @@ public bool TryPeek(out T value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool TryRead(out T value) { - if (this.End) + if (End) { value = default; return false; } - value = this.CurrentSpan[this.CurrentSpanIndex]; - this.CurrentSpanIndex++; - this.Consumed++; + value = CurrentSpan[CurrentSpanIndex]; + CurrentSpanIndex++; + Consumed++; - if (this.CurrentSpanIndex >= this.CurrentSpan.Length) + if (CurrentSpanIndex >= CurrentSpan.Length) { - if (this.usingSequence) - { - this.GetNextSpan(); - } - else - { - this.moreData = false; - } + GetNextSpan(); } return true; @@ -235,69 +219,70 @@ public bool TryRead(out T value) /// /// Move the reader back the specified number of items. /// + /// + /// Thrown if trying to rewind a negative amount or more than . + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Rewind(long count) { - if (count < 0) + if ((ulong)count > (ulong)Consumed) { throw new ArgumentOutOfRangeException(nameof(count)); } - this.Consumed -= count; - - if (this.CurrentSpanIndex >= count) + if (count == 0) { - this.CurrentSpanIndex -= (int)count; - this.moreData = true; + return; } - else if (this.usingSequence) + + Consumed -= count; + + if (CurrentSpanIndex >= count) { - // Current segment doesn't have enough data, scan backward through segments - this.RetreatToPreviousSpan(this.Consumed); + CurrentSpanIndex -= (int)count; + _moreData = true; } else { - throw new ArgumentOutOfRangeException("Rewind went past the start of the memory."); + // Current segment doesn't have enough data, scan backward through segments + RetreatToPreviousSpan(Consumed); } } [MethodImpl(MethodImplOptions.NoInlining)] private void RetreatToPreviousSpan(long consumed) { - Debug.Assert(this.usingSequence, "usingSequence"); - this.ResetReader(); - this.Advance(consumed); + ResetReader(); + Advance(consumed); } private void ResetReader() { - Debug.Assert(this.usingSequence, "usingSequence"); - this.CurrentSpanIndex = 0; - this.Consumed = 0; - this.currentPosition = this.Sequence.Start; - this.nextPosition = this.currentPosition; + CurrentSpanIndex = 0; + Consumed = 0; + _currentPosition = Sequence.Start; + _nextPosition = _currentPosition; - if (this.Sequence.TryGet(ref this.nextPosition, out ReadOnlyMemory memory, advance: true)) + if (Sequence.TryGet(ref _nextPosition, out ReadOnlyMemory memory, advance: true)) { - this.moreData = true; + _moreData = true; if (memory.Length == 0) { - this.CurrentSpan = default; - + CurrentSpan = default; // No data in the first span, move to one with data - this.GetNextSpan(); + GetNextSpan(); } else { - this.CurrentSpan = memory.Span; + CurrentSpan = memory.Span; } } else { // No data in any spans and at end of sequence - this.moreData = false; - this.CurrentSpan = default; + _moreData = false; + CurrentSpan = default; } } @@ -306,29 +291,27 @@ private void ResetReader() /// private void GetNextSpan() { - Debug.Assert(this.usingSequence, "usingSequence"); - if (!this.Sequence.IsSingleSegment) + if (!Sequence.IsSingleSegment) { - SequencePosition previousNextPosition = this.nextPosition; - while (this.Sequence.TryGet(ref this.nextPosition, out ReadOnlyMemory memory, advance: true)) + SequencePosition previousNextPosition = _nextPosition; + while (Sequence.TryGet(ref _nextPosition, out ReadOnlyMemory memory, advance: true)) { - this.currentPosition = previousNextPosition; + _currentPosition = previousNextPosition; if (memory.Length > 0) { - this.CurrentSpan = memory.Span; - this.CurrentSpanIndex = 0; + CurrentSpan = memory.Span; + CurrentSpanIndex = 0; return; } else { - this.CurrentSpan = default; - this.CurrentSpanIndex = 0; - previousNextPosition = this.nextPosition; + CurrentSpan = default; + CurrentSpanIndex = 0; + previousNextPosition = _nextPosition; } } } - - this.moreData = false; + _moreData = false; } /// @@ -338,25 +321,15 @@ private void GetNextSpan() public void Advance(long count) { const long TooBigOrNegative = unchecked((long)0xFFFFFFFF80000000); - if ((count & TooBigOrNegative) == 0 && this.CurrentSpan.Length - this.CurrentSpanIndex > (int)count) + if ((count & TooBigOrNegative) == 0 && CurrentSpan.Length - CurrentSpanIndex > (int)count) { - this.CurrentSpanIndex += (int)count; - this.Consumed += count; - } - else if (this.usingSequence) - { - // Can't satisfy from the current span - this.AdvanceToNextSpan(count); - } - else if (this.CurrentSpan.Length - this.CurrentSpanIndex == (int)count) - { - this.CurrentSpanIndex += (int)count; - this.Consumed += count; - this.moreData = false; + CurrentSpanIndex += (int)count; + Consumed += count; } else { - throw new ArgumentOutOfRangeException(nameof(count)); + // Can't satisfy from the current span + AdvanceToNextSpan(count); } } @@ -366,14 +339,12 @@ public void Advance(long count) [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void AdvanceCurrentSpan(long count) { - Debug.Assert(count >= 0, "count >= 0"); + Debug.Assert(count >= 0); - this.Consumed += count; - this.CurrentSpanIndex += (int)count; - if (this.usingSequence && this.CurrentSpanIndex >= this.CurrentSpan.Length) - { - this.GetNextSpan(); - } + Consumed += count; + CurrentSpanIndex += (int)count; + if (CurrentSpanIndex >= CurrentSpan.Length) + GetNextSpan(); } /// @@ -383,57 +354,40 @@ internal void AdvanceCurrentSpan(long count) [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void AdvanceWithinSpan(long count) { - Debug.Assert(count >= 0, "count >= 0"); - - this.Consumed += count; - this.CurrentSpanIndex += (int)count; - - Debug.Assert(this.CurrentSpanIndex < this.CurrentSpan.Length, "this.CurrentSpanIndex < this.CurrentSpan.Length"); - } + Debug.Assert(count >= 0); - /// - /// Move the reader ahead the specified number of items - /// if there are enough elements remaining in the sequence. - /// - /// true if there were enough elements to advance; otherwise false. - internal bool TryAdvance(long count) - { - if (this.Remaining < count) - { - return false; - } + Consumed += count; + CurrentSpanIndex += (int)count; - this.Advance(count); - return true; + Debug.Assert(CurrentSpanIndex < CurrentSpan.Length); } private void AdvanceToNextSpan(long count) { - Debug.Assert(this.usingSequence, "usingSequence"); if (count < 0) { throw new ArgumentOutOfRangeException(nameof(count)); } - this.Consumed += count; - while (this.moreData) + Consumed += count; + while (_moreData) { - int remaining = this.CurrentSpan.Length - this.CurrentSpanIndex; + int remaining = CurrentSpan.Length - CurrentSpanIndex; if (remaining > count) { - this.CurrentSpanIndex += (int)count; + CurrentSpanIndex += (int)count; count = 0; break; } // As there may not be any further segments we need to // push the current index to the end of the span. - this.CurrentSpanIndex += remaining; + CurrentSpanIndex += remaining; count -= remaining; - Debug.Assert(count >= 0, "count >= 0"); + Debug.Assert(count >= 0); - this.GetNextSpan(); + GetNextSpan(); if (count == 0) { @@ -444,43 +398,52 @@ private void AdvanceToNextSpan(long count) if (count != 0) { // Not enough data left- adjust for where we actually ended and throw - this.Consumed -= count; + Consumed -= count; throw new ArgumentOutOfRangeException(nameof(count)); } } /// - /// Copies data from the current to the given span. + /// Copies data from the current to the given span if there + /// is enough data to fill it. /// - /// Destination to copy to. - /// True if there is enough data to copy to the . + /// + /// This API is used to copy a fixed amount of data out of the sequence if possible. It does not advance + /// the reader. To look ahead for a specific stream of data can be used. + /// + /// Destination span to copy to. + /// True if there is enough data to completely fill the span. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool TryCopyTo(Span destination) + public readonly bool TryCopyTo(Span destination) { - ReadOnlySpan firstSpan = this.UnreadSpan; + // This API doesn't advance to facilitate conditional advancement based on the data returned. + // We don't provide an advance option to allow easier utilizing of stack allocated destination spans. + // (Because we can make this method readonly we can guarantee that we won't capture the span.) + + ReadOnlySpan firstSpan = UnreadSpan; if (firstSpan.Length >= destination.Length) { firstSpan.Slice(0, destination.Length).CopyTo(destination); return true; } - return this.TryCopyMultisegment(destination); + // Not enough in the current span to satisfy the request, fall through to the slow path + return TryCopyMultisegment(destination); } - internal bool TryCopyMultisegment(Span destination) + internal readonly bool TryCopyMultisegment(Span destination) { - if (this.Remaining < destination.Length) - { + // If we don't have enough to fill the requested buffer, return false + if (Remaining < destination.Length) return false; - } - ReadOnlySpan firstSpan = this.UnreadSpan; - Debug.Assert(firstSpan.Length < destination.Length, "firstSpan.Length < destination.Length"); + ReadOnlySpan firstSpan = UnreadSpan; + Debug.Assert(firstSpan.Length < destination.Length); firstSpan.CopyTo(destination); int copied = firstSpan.Length; - SequencePosition next = this.nextPosition; - while (this.Sequence.TryGet(ref next, out ReadOnlyMemory nextSegment, true)) + SequencePosition next = _nextPosition; + while (Sequence.TryGet(ref next, out ReadOnlyMemory nextSegment, true)) { if (nextSegment.Length > 0) { @@ -497,9 +460,7 @@ internal bool TryCopyMultisegment(Span destination) return true; } - } +} #endif - -} \ No newline at end of file diff --git a/src/IKVM.CoreLib/Buffers/SequenceReaderExtensions.cs b/src/IKVM.CoreLib/Buffers/SequenceReaderExtensions.cs index 4609baa44..c7e5f451c 100644 --- a/src/IKVM.CoreLib/Buffers/SequenceReaderExtensions.cs +++ b/src/IKVM.CoreLib/Buffers/SequenceReaderExtensions.cs @@ -352,41 +352,6 @@ static int CalculateAlignment(int position, int alignment) return result + alignment; } - /// - /// Skip consecutive instances of any of the given . - /// - /// How many positions the reader has been advanced. - public static long AdvancePastAny(this ref SequenceReader reader, scoped ReadOnlySpan values) - where T : unmanaged, IEquatable - { - var start = reader.Consumed; - - do - { - // Advance past all matches in the current span - int i; - for (i = reader.CurrentSpanIndex; i < reader.CurrentSpan.Length && values.IndexOf(reader.CurrentSpan[i]) != -1; i++) - { - continue; - } - - int advanced = i - reader.CurrentSpanIndex; - if (advanced == 0) - { - // Didn't advance at all in this span, exit. - break; - } - - reader.Advance(advanced); - - // If we're at position 0 after advancing and not at the End, - // we're in a new span and should continue the loop. - } - while (reader.CurrentSpanIndex == 0 && !reader.End); - - return reader.Consumed - start; - } - } } diff --git a/src/IKVM.CoreLib/Symbols/AssemblyIdentity.cs b/src/IKVM.CoreLib/Symbols/AssemblyIdentity.cs index 3551bd310..e49f3612e 100644 --- a/src/IKVM.CoreLib/Symbols/AssemblyIdentity.cs +++ b/src/IKVM.CoreLib/Symbols/AssemblyIdentity.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reflection; using System.Security.Cryptography; @@ -133,6 +134,33 @@ static ImmutableArray CalculatePublicKeyToken(ImmutableArray publicK return result.ToImmutable(); } + /// + /// Parses a span of characters into a assembly name. + /// + /// A span containing the characters representing the assembly name to parse. + /// Parsed type name. + /// Provided assembly name was invalid. + public static AssemblyIdentity Parse(ReadOnlySpan assemblyName) => TryParse(assemblyName, out AssemblyIdentity? result) ? result! : throw new ArgumentException("Invalid assembly name.", nameof(assemblyName)); + + /// + /// Tries to parse a span of characters into an assembly name. + /// + /// A span containing the characters representing the assembly name to parse. + /// Contains the result when parsing succeeds. + /// true if assembly name was converted successfully, otherwise, false. + public static bool TryParse(ReadOnlySpan assemblyName, [NotNullWhen(true)] out AssemblyIdentity? result) + { + AssemblyIdentityParser.AssemblyIdentityParts parts = default; + if (!assemblyName.IsEmpty && AssemblyIdentityParser.TryParse(assemblyName, ref parts)) + { + result = new(parts._name, parts._version, parts._cultureName, parts._publicKeyOrToken?.ToImmutableArray() ?? [], parts._publicKeyOrToken != null); + return true; + } + + result = null; + return false; + } + readonly string _name; readonly Version _version; readonly string? _cultureName; diff --git a/src/IKVM.CoreLib/Symbols/Emit/TypeSymbolBuilderBase.cs b/src/IKVM.CoreLib/Symbols/Emit/TypeSymbolBuilderBase.cs index 5c0818432..c8390162e 100644 --- a/src/IKVM.CoreLib/Symbols/Emit/TypeSymbolBuilderBase.cs +++ b/src/IKVM.CoreLib/Symbols/Emit/TypeSymbolBuilderBase.cs @@ -11,25 +11,31 @@ namespace IKVM.CoreLib.Symbols.Emit { - abstract class TypeSymbolBuilderBase : ITypeSymbolBuilder + abstract class TypeSymbolBuilderBase : ITypeSymbolBuilder + where TContext : ISymbolContext { const BindingFlags DefaultBindingFlags = BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance; - readonly ISymbolContext _context; + readonly TContext _context; readonly IModuleSymbolBuilder _module; - string _name; - TypeAttributes _attributes; + readonly TypeAttributes _attributes; + readonly string _namespace; + readonly string _name; + readonly ITypeSymbol? _declaringType; + readonly PackingSize _packingSize; + readonly int _typeSize; ITypeSymbol? _parentType; - ImmutableList _genericTypeParameters = ImmutableList.Empty; + IConstructorSymbol? _typeInitializer = null; + ImmutableList _genericTypeParameters = ImmutableList.Empty; ImmutableList _interfaces = ImmutableList.Empty; - ImmutableList _fields = ImmutableList.Empty; - ImmutableList _constructors = ImmutableList.Empty; - ImmutableList _methods = ImmutableList.Empty; + ImmutableList _fields = ImmutableList.Empty; + ImmutableList _constructors = ImmutableList.Empty; + ImmutableList _methods = ImmutableList.Empty; ImmutableList<(IMethodSymbol, IMethodSymbol)> _methodOverrides = ImmutableList<(IMethodSymbol, IMethodSymbol)>.Empty; - ImmutableList _properties = ImmutableList.Empty; - ImmutableList _events = ImmutableList.Empty; + ImmutableList _properties = ImmutableList.Empty; + ImmutableList _events = ImmutableList.Empty; ImmutableList _customAttributes = ImmutableList.Empty; /// @@ -37,11 +43,34 @@ abstract class TypeSymbolBuilderBase : ITypeSymbolBuilder /// /// /// - public TypeSymbolBuilderBase(ISymbolContext context, IModuleSymbolBuilder module, TypeAttributes attributes) + /// + /// + /// + /// + /// + /// + public TypeSymbolBuilderBase(TContext context, IModuleSymbolBuilder module, TypeAttributes attributes, string name, ITypeSymbol? declaringType, PackingSize packingSize, int typeSize) { _context = context ?? throw new ArgumentNullException(nameof(context)); _module = module ?? throw new ArgumentNullException(nameof(module)); _attributes = attributes; + _declaringType = declaringType; + _packingSize = packingSize; + _typeSize = typeSize; + + int iLast = name.LastIndexOf('.'); + if (iLast <= 0) + { + // no name space + _namespace = string.Empty; + _name = name; + } + else + { + // split the name space + _namespace = name.Substring(0, iLast); + _name = name.Substring(iLast + 1); + } } /// @@ -447,9 +476,7 @@ public IPropertySymbolBuilder DefineProperty(string name, PropertyAttributes att /// public IConstructorSymbolBuilder DefineTypeInitializer() { - var constructor = CreateTypeInitializerBuilder(); - _constructors = _constructors.Add(constructor); - return constructor; + return (IConstructorSymbolBuilder)(_typeInitializer = CreateTypeInitializerBuilder()); } protected abstract IConstructorSymbolBuilder CreateTypeInitializerBuilder(); @@ -468,234 +495,341 @@ public void SetCustomAttribute(CustomAttribute attribute) #region ITypeSymbol - public void Foo() - { - System.Reflection.Metadata.TypeName t; - } - + /// public TypeAttributes Attributes => _attributes; + /// public IAssemblySymbol Assembly => _module.Assembly; + /// public IMethodBaseSymbol? DeclaringMethod => null; + /// public string? AssemblyQualifiedName => System.Reflection.Assembly.CreateQualifiedName(Assembly.FullName, FullName); - public string? FullName => _name; + /// + public string? FullName => string.IsNullOrEmpty(_namespace) ? _name : _namespace + "." + _name; - public string? Namespace => throw new NotImplementedException(); + /// + public string? Namespace => _namespace; - public TypeCode TypeCode => throw new NotImplementedException(); + /// + public TypeCode TypeCode => TypeCode.Object; - public ITypeSymbol? BaseType => throw new NotImplementedException(); + /// + public ITypeSymbol? BaseType => _parentType; - public bool ContainsGenericParameters => throw new NotImplementedException(); + /// + public bool ContainsGenericParameters => _genericTypeParameters.IsEmpty == false; + /// public GenericParameterAttributes GenericParameterAttributes => throw new NotImplementedException(); + /// public int GenericParameterPosition => throw new NotImplementedException(); - public IImmutableList GenericTypeArguments => throw new NotImplementedException(); + /// + public IImmutableList GenericTypeArguments => _genericTypeParameters; - public bool IsConstructedGenericType => throw new NotImplementedException(); + /// + public bool IsConstructedGenericType => false; - public bool IsGenericType => throw new NotImplementedException(); + /// + public bool IsGenericType => _genericTypeParameters.Count > 0; - public bool IsGenericTypeDefinition => throw new NotImplementedException(); + /// + public bool IsGenericTypeDefinition => IsGenericType; - public bool IsGenericParameter => throw new NotImplementedException(); + /// + public bool IsGenericParameter => false; - public bool IsAutoLayout => throw new NotImplementedException(); + /// + public bool IsAutoLayout => (_attributes & TypeAttributes.LayoutMask) == TypeAttributes.AutoLayout; + + /// + public bool IsExplicitLayout => (_attributes & TypeAttributes.LayoutMask) == TypeAttributes.ExplicitLayout; + + /// + public bool IsLayoutSequential => (_attributes & TypeAttributes.LayoutMask) == TypeAttributes.SequentialLayout; + + /// + public bool HasElementType => false; + + /// + public bool IsClass => (_attributes & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Class && !IsValueType; + + /// + public bool IsValueType => IsSubclassOf(Context.ResolveCoreType("System.ValueType")); + + /// + public bool IsInterface => (_attributes & TypeAttributes.Interface) != 0; + + /// + public bool IsPrimitive => false; - public bool IsExplicitLayout => throw new NotImplementedException(); + /// + public bool IsSZArray => false; - public bool IsLayoutSequential => throw new NotImplementedException(); + /// + public bool IsArray => false; - public bool HasElementType => throw new NotImplementedException(); + /// + public bool IsEnum => IsSubclassOf(Context.ResolveCoreType("System.Enum")); - public bool IsClass => throw new NotImplementedException(); + /// + public bool IsPointer => false; - public bool IsValueType => throw new NotImplementedException(); + /// + public bool IsFunctionPointer => false; - public bool IsInterface => throw new NotImplementedException(); + /// + public bool IsUnmanagedFunctionPointer => false; - public bool IsPrimitive => throw new NotImplementedException(); + /// + public bool IsByRef => false; - public bool IsSZArray => throw new NotImplementedException(); + /// + public bool IsAbstract => (_attributes & TypeAttributes.Abstract) != 0; - public bool IsArray => throw new NotImplementedException(); + /// + public bool IsSealed => (_attributes & TypeAttributes.Sealed) != 0; - public bool IsEnum => throw new NotImplementedException(); + /// + public bool IsVisible => GetIsVisible(); - public bool IsPointer => throw new NotImplementedException(); + bool GetIsVisible() + { + if (IsGenericParameter) + return true; - public bool IsFunctionPointer => throw new NotImplementedException(); + if (HasElementType) + return GetElementType()!.IsVisible; - public bool IsUnmanagedFunctionPointer => throw new NotImplementedException(); + var type = (ITypeSymbol)this; + while (type.IsNested) + { + if (!type.IsNestedPublic) + return false; - public bool IsByRef => throw new NotImplementedException(); + // this should be null for non-nested types. + type = type.DeclaringType!; + } - public bool IsAbstract => throw new NotImplementedException(); + // Now "type" should be a top level type + if (!type.IsPublic) + return false; - public bool IsSealed => throw new NotImplementedException(); + if (IsGenericType && !IsGenericTypeDefinition) + { + foreach (var t in GetGenericArguments()) + { + if (!t.IsVisible) + return false; + } + } - public bool IsVisible => throw new NotImplementedException(); + return true; + } - public bool IsPublic => throw new NotImplementedException(); + /// + public bool IsPublic => (_attributes & TypeAttributes.VisibilityMask) == TypeAttributes.Public; - public bool IsNotPublic => throw new NotImplementedException(); + /// + public bool IsNotPublic => (_attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NotPublic; - public bool IsNested => throw new NotImplementedException(); + /// + public bool IsNested => DeclaringType != null; - public bool IsNestedAssembly => throw new NotImplementedException(); + /// + public bool IsNestedAssembly => (_attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedAssembly; - public bool IsNestedFamANDAssem => throw new NotImplementedException(); + /// + public bool IsNestedFamANDAssem => (_attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamANDAssem; - public bool IsNestedFamily => throw new NotImplementedException(); + /// + public bool IsNestedFamily => (_attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamily; - public bool IsNestedFamORAssem => throw new NotImplementedException(); + /// + public bool IsNestedFamORAssem => (_attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamORAssem; - public bool IsNestedPrivate => throw new NotImplementedException(); + /// + public bool IsNestedPrivate => (_attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPrivate; - public bool IsNestedPublic => throw new NotImplementedException(); + /// + public bool IsNestedPublic => (_attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPublic; + /// public bool IsSerializable => throw new NotImplementedException(); - public bool IsSignatureType => throw new NotImplementedException(); + /// + public bool IsSignatureType => false; - public bool IsSpecialName => throw new NotImplementedException(); + /// + public bool IsSpecialName => (_attributes & TypeAttributes.SpecialName) != 0; + /// public IConstructorSymbol? TypeInitializer => throw new NotImplementedException(); - public IModuleSymbol Module => throw new NotImplementedException(); + /// + public IModuleSymbol Module => _module; - public ITypeSymbol? DeclaringType => throw new NotImplementedException(); + /// + public ITypeSymbol? DeclaringType => _declaringType; + /// public MemberTypes MemberType => throw new NotImplementedException(); + /// public int MetadataToken => throw new NotImplementedException(); - public string Name => throw new NotImplementedException(); + /// + public string Name => _name; - public bool IsMissing => throw new NotImplementedException(); + /// + public bool IsMissing => false; + /// public bool ContainsMissing => throw new NotImplementedException(); + /// public bool IsComplete => throw new NotImplementedException(); + /// public int GetArrayRank() { - throw new NotImplementedException(); + return 0; } + /// public IImmutableList GetDefaultMembers() { throw new NotImplementedException(); } + /// public ITypeSymbol? GetElementType() { - throw new NotImplementedException(); + return null; } + /// public string? GetEnumName(object value) { throw new NotImplementedException(); } + /// public IImmutableList GetEnumNames() { throw new NotImplementedException(); } + /// public ITypeSymbol GetEnumUnderlyingType() { throw new NotImplementedException(); } + /// public IImmutableList GetGenericArguments() { - throw new NotImplementedException(); + return _genericTypeParameters; } + /// public IImmutableList GetGenericParameterConstraints() { throw new NotImplementedException(); } + /// public ITypeSymbol GetGenericTypeDefinition() { throw new NotImplementedException(); } + /// public ITypeSymbol? GetInterface(string name) { throw new NotImplementedException(); } + /// public ITypeSymbol? GetInterface(string name, bool ignoreCase) { throw new NotImplementedException(); } + /// public IImmutableList GetInterfaces(bool inherit = true) { throw new NotImplementedException(); } + /// public InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType) { throw new NotImplementedException(); } + /// public IImmutableList GetDeclaredConstructors() { throw new NotImplementedException(); } + /// public IConstructorSymbol? GetConstructor(IImmutableList types) { throw new NotImplementedException(); } + /// public IConstructorSymbol? GetConstructor(BindingFlags bindingFlags, IImmutableList types) { throw new NotImplementedException(); } + /// public IImmutableList GetConstructors() { throw new NotImplementedException(); } + /// public IImmutableList GetConstructors(BindingFlags bindingFlags) { throw new NotImplementedException(); } + /// public IFieldSymbol? GetField(string name) { throw new NotImplementedException(); } + /// public IFieldSymbol? GetField(string name, BindingFlags bindingFlags) { throw new NotImplementedException(); } + /// public IImmutableList GetFields() { throw new NotImplementedException(); } + /// public IImmutableList GetFields(BindingFlags bindingFlags) { throw new NotImplementedException(); } + /// public IImmutableList GetDeclaredMethods() { - throw new NotImplementedException(); + return _methods; } /// @@ -707,27 +841,27 @@ public IImmutableList GetDeclaredMethods() /// public IMethodSymbol? GetMethod(string name, BindingFlags bindingFlags, IImmutableList? types, IImmutableList? modifiers) { - return SymbolUtil.SelectMethod(this, DefaultBindingFlags, name, types, modifiers); + return SymbolUtil.SelectMethod(this, bindingFlags, name, types, modifiers); } public IMethodSymbol? GetMethod(string name, IImmutableList types) { - throw new NotImplementedException(); + return SymbolUtil.SelectMethod(this, DefaultBindingFlags, null, types, null); } public IMethodSymbol? GetMethod(string name, BindingFlags bindingFlags) { - throw new NotImplementedException(); + return SymbolUtil.SelectMethod(this, bindingFlags, null, null, null); } public IMethodSymbol? GetMethod(string name, BindingFlags bindingFlags, IImmutableList types) { - throw new NotImplementedException(); + return SymbolUtil.SelectMethod(this, bindingFlags, null, types, null); } public IMethodSymbol? GetMethod(string name, BindingFlags bindingFlags, CallingConventions callConvention, IImmutableList types, IImmutableList modifiers) { - throw new NotImplementedException(); + return SymbolUtil.SelectMethod(this, bindingFlags, null, types, modifiers); } public IMethodSymbol? GetMethod(string name, int genericParameterCount, BindingFlags bindingFlags, CallingConventions callConvention, IImmutableList types, IImmutableList modifiers) diff --git a/src/IKVM.CoreLib/Symbols/ISymbolContext.cs b/src/IKVM.CoreLib/Symbols/ISymbolContext.cs index 776a0d862..fda80bd4f 100644 --- a/src/IKVM.CoreLib/Symbols/ISymbolContext.cs +++ b/src/IKVM.CoreLib/Symbols/ISymbolContext.cs @@ -8,6 +8,13 @@ namespace IKVM.CoreLib.Symbols interface ISymbolContext { + /// + /// Resolves the named type from the core assembly. + /// + /// + /// + ITypeSymbol ResolveCoreType(string typeName); + /// /// Defines a dynamic assembly that has the specified name and access rights. /// @@ -26,6 +33,7 @@ interface ISymbolContext /// /// IAssemblySymbolBuilder DefineAssembly(AssemblyIdentity name, ImmutableArray attributes, bool collectable = true, bool saveable = false); + } } diff --git a/src/IKVM.CoreLib/Symbols/TypeSymbolName.cs b/src/IKVM.CoreLib/Symbols/TypeSymbolName.cs new file mode 100644 index 000000000..8743f4b7a --- /dev/null +++ b/src/IKVM.CoreLib/Symbols/TypeSymbolName.cs @@ -0,0 +1,503 @@ +// 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.Generic; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; +using System.Text; +using IKVM.CoreLib.Text; +using System; + + + +#if !SYSTEM_PRIVATE_CORELIB +using System.Collections.Immutable; +#endif + +namespace IKVM.CoreLib.Symbols +{ + + [DebuggerDisplay("{AssemblyQualifiedName}")] + sealed class TypeSymbolName + { + /// + /// Positive value is array rank. + /// Negative value is modifier encoded using constants defined in . + /// + private readonly int _rankOrModifier; + /// + /// To avoid the need of allocating a string for all declaring types (example: A+B+C+D+E+F+G), + /// length of the name is stored and the fullName passed in ctor represents the full name of the nested type. + /// So when the name is needed, a substring is being performed. + /// + private readonly int _nestedNameLength; + private readonly TypeSymbolName? _elementOrGenericType; + private readonly TypeSymbolName? _declaringType; + private readonly ImmutableArray _genericArguments; + private string? _name, _fullName, _assemblyQualifiedName; + + internal TypeSymbolName(string? fullName, + AssemblyIdentity? assemblyName, + TypeSymbolName? elementOrGenericType = default, + TypeSymbolName? declaringType = default, + ImmutableArray.Builder? genericTypeArguments = default, + int rankOrModifier = default, + int nestedNameLength = -1) + { + _fullName = fullName; + AssemblyName = assemblyName; + _rankOrModifier = rankOrModifier; + _elementOrGenericType = elementOrGenericType; + _declaringType = declaringType; + _nestedNameLength = nestedNameLength; + + _genericArguments = genericTypeArguments is null + ? ImmutableArray.Empty + : genericTypeArguments.Count == genericTypeArguments.Capacity ? genericTypeArguments.MoveToImmutable() : genericTypeArguments.ToImmutableArray(); + } + + /// + /// The assembly-qualified name of the type; e.g., "System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089". + /// + /// + /// If returns null, simply returns . + /// + public string AssemblyQualifiedName + => _assemblyQualifiedName ??= AssemblyName is null ? FullName : $"{FullName}, {AssemblyName.FullName}"; // see recursion comments in FullName + + /// + /// Returns assembly name which contains this type, or null if this was not + /// created from a fully-qualified name. + /// + public AssemblyIdentity? AssemblyName { get; } + + /// + /// If this type is a nested type (see ), gets + /// the declaring type. If this type is not a nested type, throws. + /// + /// + /// For example, given "Namespace.Declaring+Nested", unwraps the outermost type and returns "Namespace.Declaring". + /// + /// The current type is not a nested type. + public TypeSymbolName DeclaringType + { + get + { + if (_declaringType is null) + { + throw new InvalidOperationException(); + } + + return _declaringType; + } + } + + /// + /// The full name of this type, including namespace, but without the assembly name; e.g., "System.Int32". + /// Nested types are represented with a '+'; e.g., "MyNamespace.MyType+NestedType". + /// + /// + /// For constructed generic types, the type arguments will be listed using their fully qualified + /// names. For example, given "List<int>", the property will return + /// "System.Collections.Generic.List`1[[System.Int32, mscorlib, ...]]". + /// For open generic types, the convention is to use a backtick ("`") followed by + /// the arity of the generic type. For example, given "Dictionary<,>", the + /// property will return "System.Collections.Generic.Dictionary`2". Given "Dictionary<,>.Enumerator", + /// the property will return "System.Collections.Generic.Dictionary`2+Enumerator". + /// See ECMA-335, Sec. I.10.7.2 (Type names and arity encoding) for more information. + /// + public string FullName + { + get + { + // This is a recursive method over potentially hostile input. Protection against DoS is offered + // via the [Try]Parse method and TypeNameParserOptions.MaxNodes property at construction time. + // This FullName property getter and related methods assume that this TypeName instance has an + // acceptable node count. + // + // The node count controls the total amount of work performed by this method, including: + // - The max possible stack depth due to the recursive methods calls; and + // - The total number of bytes allocated by this function. For a deeply-nested TypeName + // object, the total allocation across the full object graph will be + // O(FullName.Length * GetNodeCount()). + + if (_fullName is null) + { + if (IsConstructedGenericType) + { + _fullName = TypeSymbolNameParserHelpers.GetGenericTypeFullName(GetGenericTypeDefinition().FullName.AsSpan(), _genericArguments.AsSpan()); + } + else if (IsArray || IsPointer || IsByRef) + { + ValueStringBuilder builder = new(stackalloc char[128]); + builder.Append(GetElementType().FullName); + _fullName = TypeSymbolNameParserHelpers.GetRankOrModifierStringRepresentation(_rankOrModifier, ref builder); + } + else + { + Debug.Fail("Pre-allocated full name should have been provided in the ctor"); + } + } + else if (_nestedNameLength > 0 && _fullName.Length > _nestedNameLength) // Declaring types + { + // Stored fullName represents the full name of the nested type. + // Example: Namespace.Declaring+Nested + _fullName = _fullName.Substring(0, _nestedNameLength); + } + + return _fullName!; + } + } + + /// + /// Returns true if this type represents any kind of array, regardless of the array's + /// rank or its bounds. + /// + public bool IsArray => _rankOrModifier == TypeSymbolNameParserHelpers.SZArray || _rankOrModifier > 0; + + /// + /// Returns true if this type represents a constructed generic type (e.g., "List<int>"). + /// + /// + /// Returns false for open generic types (e.g., "Dictionary<,>"). + /// + public bool IsConstructedGenericType => +#if SYSTEM_PRIVATE_CORELIB + _genericArguments is not null; +#else + _genericArguments.Length > 0; +#endif + + /// + /// Returns true if this is a "plain" type; that is, not an array, not a pointer, not a reference, and + /// not a constructed generic type. Examples of elemental types are "System.Int32", + /// "System.Uri", and "YourNamespace.YourClass". + /// + /// + /// This property returning true doesn't mean that the type is a primitive like string + /// or int; it just means that there's no underlying type. + /// This property will return true for generic type definitions (e.g., "Dictionary<,>"). + /// This is because determining whether a type truly is a generic type requires loading the type + /// and performing a runtime check. + /// + public bool IsSimple => _elementOrGenericType is null; + + /// + /// Returns true if this is a managed pointer type (e.g., "ref int"). + /// Managed pointer types are sometimes called byref types () + /// + public bool IsByRef => _rankOrModifier == TypeSymbolNameParserHelpers.ByRef; + + /// + /// Returns true if this is a nested type (e.g., "Namespace.Declaring+Nested"). + /// For nested types returns their declaring type. + /// + public bool IsNested => _declaringType is not null; + + /// + /// Returns true if this type represents a single-dimensional, zero-indexed array (e.g., "int[]"). + /// + public bool IsSZArray => _rankOrModifier == TypeSymbolNameParserHelpers.SZArray; + + /// + /// Returns true if this type represents an unmanaged pointer (e.g., "int*" or "void*"). + /// Unmanaged pointer types are often just called pointers () + /// + public bool IsPointer => _rankOrModifier == TypeSymbolNameParserHelpers.Pointer; + + /// + /// Returns true if this type represents a variable-bound array; that is, an array of rank greater + /// than 1 (e.g., "int[,]") or a single-dimensional array which isn't necessarily zero-indexed. + /// + public bool IsVariableBoundArrayType => _rankOrModifier >= 1; + + /// + /// The name of this type, without the namespace and the assembly name; e.g., "Int32". + /// Nested types are represented without a '+'; e.g., "MyNamespace.MyType+NestedType" is just "NestedType". + /// + public string Name + { + get + { + // Lookups to Name and FullName might be recursive. See comments in FullName property getter. + + if (_name is null) + { + if (IsConstructedGenericType) + { + _name = TypeSymbolNameParserHelpers.GetName(GetGenericTypeDefinition().FullName.AsSpan()).ToString(); + } + else if (IsPointer || IsByRef || IsArray) + { + ValueStringBuilder builder = new(stackalloc char[64]); + builder.Append(GetElementType().Name); + _name = TypeSymbolNameParserHelpers.GetRankOrModifierStringRepresentation(_rankOrModifier, ref builder); + } + else if (_nestedNameLength > 0 && _fullName is not null) + { + _name = TypeSymbolNameParserHelpers.GetName(_fullName.AsSpan(0, _nestedNameLength)).ToString(); + } + else + { + _name = TypeSymbolNameParserHelpers.GetName(FullName.AsSpan()).ToString(); + } + } + + return _name; + } + } + + /// + /// Represents the total number of instances that are used to describe + /// this instance, including any generic arguments or underlying types. + /// + /// + /// This value is computed every time this method gets called, it's not cached. + /// There's not really a parallel concept to this in reflection. Think of it + /// as the total number of instances that would be created if + /// you were to totally deconstruct this instance and visit each intermediate + /// that occurs as part of deconstruction. + /// "int" and "Person" each have complexities of 1 because they're standalone types. + /// "int[]" has a node count of 2 because to fully inspect it involves inspecting the + /// array type itself, plus unwrapping the underlying type ("int") and inspecting that. + /// + /// "Dictionary<string, List<int[][]>>" has node count 8 because fully visiting it + /// involves inspecting 8 instances total: + /// + /// Dictionary<string, List<int[][]>> (the original type) + /// Dictionary`2 (the generic type definition) + /// string (a type argument of Dictionary) + /// List<int[][]> (a type argument of Dictionary) + /// List`1 (the generic type definition) + /// int[][] (a type argument of List) + /// int[] (the underlying type of int[][]) + /// int (the underlying type of int[]) + /// + /// + /// + public int GetNodeCount() + { + // This method uses checked arithmetic to avoid silent overflows. + // It's impossible to parse a TypeName with NodeCount > int.MaxValue + // (TypeNameParseOptions.MaxNodes is an int), but it's possible + // to create such names with the Make* APIs. + int result = 1; + + if (IsArray || IsPointer || IsByRef) + { + result = checked(result + GetElementType().GetNodeCount()); + } + else if (IsConstructedGenericType) + { + result = checked(result + GetGenericTypeDefinition().GetNodeCount()); + + foreach (TypeSymbolName genericArgument in GetGenericArguments()) + { + result = checked(result + genericArgument.GetNodeCount()); + } + } + else if (IsNested) + { + result = checked(result + DeclaringType.GetNodeCount()); + } + + return result; + } + + /// + /// The TypeName of the object encompassed or referred to by the current array, pointer, or reference type. + /// + /// + /// For example, given "int[][]", unwraps the outermost array and returns "int[]". + /// + /// The current type is not an array, pointer or reference. + public TypeSymbolName GetElementType() + { + if (!(IsArray || IsPointer || IsByRef)) + { + TypeSymbolNameParserHelpers.ThrowInvalidOperation_NoElement(); + } + + return _elementOrGenericType!; + } + + /// + /// Returns a TypeName object that represents a generic type name definition from which the current generic type name can be constructed. + /// + /// + /// Given "Dictionary<string, int>", returns the generic type definition "Dictionary<,>". + /// + /// The current type is not a generic type. + public TypeSymbolName GetGenericTypeDefinition() + { + if (!IsConstructedGenericType) + { + TypeSymbolNameParserHelpers.ThrowInvalidOperation_NotGenericType(); + } + + return _elementOrGenericType!; + } + + /// + /// Parses a span of characters into a type name. + /// + /// A span containing the characters representing the type name to parse. + /// An object that describes optional parameters to use. + /// Parsed type name. + /// Provided type name was invalid. + /// Parsing has exceeded the limit set by . + public static TypeSymbolName Parse(ReadOnlySpan typeName) + => TypeNameParser.Parse(typeName, throwOnError: true)!; + + /// + /// Tries to parse a span of characters into a type name. + /// + /// A span containing the characters representing the type name to parse. + /// An object that describes optional parameters to use. + /// Contains the result when parsing succeeds. + /// true if type name was converted successfully, otherwise, false. + public static bool TryParse(ReadOnlySpan typeName, [NotNullWhen(true)] out TypeSymbolName? result, TypeNameParseOptions? options = default) + { + result = TypeNameParser.Parse(typeName, throwOnError: false, options); + return result is not null; + } + + /// + /// Gets the number of dimensions in an array. + /// + /// An integer that contains the number of dimensions in the current type. + /// The current type is not an array. + public int GetArrayRank() + { + if (!(_rankOrModifier == TypeNameParserHelpers.SZArray || _rankOrModifier > 0)) + { + TypeNameParserHelpers.ThrowInvalidOperation_HasToBeArrayClass(); + } + + return _rankOrModifier == TypeNameParserHelpers.SZArray ? 1 : _rankOrModifier; + } + + /// + /// If this represents a constructed generic type, returns an array + /// of all the generic arguments. Otherwise it returns an empty array. + /// + /// + /// For example, given "Dictionary<string, int>", returns a 2-element array containing + /// string and int. + /// + public +#if SYSTEM_PRIVATE_CORELIB + ReadOnlySpan GetGenericArguments() => CollectionsMarshal.AsSpan(_genericArguments); +#else + ImmutableArray GetGenericArguments() => _genericArguments; +#endif + +#if SYSTEM_REFLECTION_METADATA + /// + /// Creates a new object that represents current simple name with provided assembly name. + /// + /// Assembly name. + /// Created simple name. + /// The current type name is not simple. + public TypeName WithAssemblyName(AssemblyNameInfo? assemblyName) + { + // Recursive method. See comments in FullName property getter for more information + // on how this is protected against attack. + // + // n.b. AssemblyNameInfo could also be hostile. The typical exploit is that a single + // long AssemblyNameInfo is associated with one or more simple TypeName objects, + // leading to an alg. complexity attack (DoS). It's important that TypeName doesn't + // actually *do* anything with the provided AssemblyNameInfo rather than store it. + // For example, don't use it inside a string concat operation unless the caller + // explicitly requested that to happen. If the input is hostile, the caller should + // never perform such concats in a loop. + + if (!IsSimple) + { + TypeNameParserHelpers.ThrowInvalidOperation_NotSimpleName(FullName); + } + + TypeName? declaringType = IsNested + ? DeclaringType.WithAssemblyName(assemblyName) + : null; + + return new TypeName(fullName: _fullName, + assemblyName: assemblyName, + elementOrGenericType: null, + declaringType: declaringType, + genericTypeArguments: ImmutableArray.Empty, + nestedNameLength: _nestedNameLength); + } + + /// + /// Creates a object representing a one-dimensional array + /// of the current type, with a lower bound of zero. + /// + /// + /// A object representing a one-dimensional array + /// of the current type, with a lower bound of zero. + /// + public TypeName MakeSZArrayTypeName() => MakeElementTypeName(TypeNameParserHelpers.SZArray); + + /// + /// Creates a object representing an array of the current type, + /// with the specified number of dimensions. + /// + /// The number of dimensions for the array. This number must be more than zero and less than or equal to 32. + /// + /// A object representing an array of the current type, + /// with the specified number of dimensions. + /// + /// rank is invalid. For example, 0 or negative. + public TypeName MakeArrayTypeName(int rank) + => rank <= 0 + ? throw new ArgumentOutOfRangeException(nameof(rank)) + : MakeElementTypeName(rank); + + /// + /// Creates a object that represents a pointer to the current type. + /// + /// + /// A object that represents a pointer to the current type. + /// + public TypeName MakePointerTypeName() => MakeElementTypeName(TypeNameParserHelpers.Pointer); + + /// + /// Creates a object that represents a managed reference to the current type. + /// + /// + /// A object that represents a managed reference to the current type. + /// + public TypeName MakeByRefTypeName() => MakeElementTypeName(TypeNameParserHelpers.ByRef); + + /// + /// Creates a new constructed generic type name. + /// + /// An array of type names to be used as generic arguments of the current simple type name. + /// + /// A representing the constructed type name formed by using the elements + /// of for the generic arguments of the current simple type name. + /// + /// The current type name is not simple. + public TypeName MakeGenericTypeName(ImmutableArray typeArguments) + { + if (!IsSimple) + { + TypeNameParserHelpers.ThrowInvalidOperation_NotSimpleName(FullName); + } + + return new TypeName(fullName: null, AssemblyName, elementOrGenericType: this, declaringType: _declaringType, genericTypeArguments: typeArguments); + } + + private TypeName MakeElementTypeName(int rankOrModifier) + => new TypeName( + fullName: null, + assemblyName: AssemblyName, + elementOrGenericType: this, + declaringType: null, + genericTypeArguments: ImmutableArray.Empty, + rankOrModifier: rankOrModifier); +#endif + } +} \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/TypeSymbolNameParserHelpers.cs b/src/IKVM.CoreLib/Symbols/TypeSymbolNameParserHelpers.cs index bf940d819..fe18e4a8c 100644 --- a/src/IKVM.CoreLib/Symbols/TypeSymbolNameParserHelpers.cs +++ b/src/IKVM.CoreLib/Symbols/TypeSymbolNameParserHelpers.cs @@ -1,26 +1,30 @@ -using System; +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Buffers; using System.Collections.Generic; -using System.Collections.Immutable; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Text; +using IKVM.CoreLib.Symbols; using IKVM.CoreLib.Text; namespace IKVM.CoreLib.Symbols { - - internal static class TypeNameParserHelpers + internal static class TypeSymbolNameParserHelpers { - - const int maxDepth = 32; internal const int SZArray = -1; internal const int Pointer = -2; internal const int ByRef = -3; - const char EscapeCharacter = '\\'; - + private const char EscapeCharacter = '\\'; +#if NET8_0_OR_GREATER // Keep this in sync with GetFullTypeNameLength/NeedsEscaping - private static readonly string s_endOfFullTypeNameDelimitersSearchValues = "[]&*,+\\"; + private static readonly SearchValues s_endOfFullTypeNameDelimitersSearchValues = SearchValues.Create("[]&*,+\\"); +#endif - internal static string GetGenericTypeFullName(ReadOnlySpan fullTypeName, ReadOnlySpan genericArgs) + internal static string GetGenericTypeFullName(ReadOnlySpan fullTypeName, ReadOnlySpan genericArgs) { Debug.Assert(genericArgs.Length > 0); @@ -57,7 +61,8 @@ internal static int GetFullTypeNameLength(ReadOnlySpan input, out bool isN // input, that makes the total loop complexity potentially O(m * n^2), where // 'n' is adversary-controlled. To avoid DoS issues here, we'll loop manually. - int offset = input.IndexOfAny(s_endOfFullTypeNameDelimitersSearchValues.AsSpan()); +#if NET8_0_OR_GREATER + int offset = input.IndexOfAny(s_endOfFullTypeNameDelimitersSearchValues); if (offset < 0) { return input.Length; // no type name end chars were found, the whole input is the type name @@ -67,6 +72,9 @@ internal static int GetFullTypeNameLength(ReadOnlySpan input, out bool isN { offset = GetUnescapedOffset(input, startOffset: offset); // this is slower, but very rare so acceptable } +#else + int offset = GetUnescapedOffset(input, startOffset: 0); +#endif isNestedType = offset > 0 && offset < input.Length && input[offset] == '+'; return offset; @@ -229,10 +237,10 @@ internal static bool IsBeginningOfGenericArgs(ref ReadOnlySpan span, out b return false; } - internal static bool TryGetTypeNameInfo(ref ReadOnlySpan input, ref List? nestedNameLengths, ref int recursiveDepth, out int totalLength) + internal static bool TryGetTypeNameInfo(ref ReadOnlySpan input, + ref List? nestedNameLengths, ref int recursiveDepth, out int totalLength) { bool isNestedType; - totalLength = 0; do { @@ -245,16 +253,6 @@ internal static bool TryGetTypeNameInfo(ref ReadOnlySpan input, ref List 1 && input[0] == '.' && input.Slice(0, length).LastIndexOf('.') == 0) - { - input = input.Slice(1); - length--; - } - if (isNestedType) { if (!TryDive(ref recursiveDepth)) @@ -345,37 +343,43 @@ internal static bool TryStripFirstCharAndTrailingSpaces(ref ReadOnlySpan s return false; } + [DoesNotReturn] internal static void ThrowArgumentException_InvalidTypeName(int errorIndex) { - throw new InvalidOperationException(); + throw new ArgumentException(); } + [DoesNotReturn] internal static void ThrowInvalidOperation_MaxNodesExceeded(int limit) { throw new InvalidOperationException(); } + [DoesNotReturn] internal static void ThrowInvalidOperation_NotGenericType() { throw new InvalidOperationException(); } + [DoesNotReturn] internal static void ThrowInvalidOperation_NotNestedType() { throw new InvalidOperationException(); } + [DoesNotReturn] internal static void ThrowInvalidOperation_NoElement() { throw new InvalidOperationException(); } + [DoesNotReturn] internal static void ThrowInvalidOperation_HasToBeArrayClass() { throw new InvalidOperationException(); } - internal static bool IsMaxDepthExceeded(int depth) => depth > maxDepth; + internal static bool IsMaxDepthExceeded(int depth) => false; internal static bool TryDive(ref int depth) { @@ -383,11 +387,5 @@ internal static bool TryDive(ref int depth) return !IsMaxDepthExceeded(depth); } - internal static void ThrowInvalidOperation_NotSimpleName(string fullName) - { - throw new InvalidOperationException(); - } - } - -} +} \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/TypeSymbolNameParserResult.cs b/src/IKVM.CoreLib/Symbols/TypeSymbolNameParserResult.cs deleted file mode 100644 index 984395419..000000000 --- a/src/IKVM.CoreLib/Symbols/TypeSymbolNameParserResult.cs +++ /dev/null @@ -1,41 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Immutable; -using System.Diagnostics; - -namespace IKVM.CoreLib.Symbols -{ - - [DebuggerDisplay("{AssemblyQualifiedName}")] - struct TypeSymbolNameParserResult - { - - readonly ReadOnlyMemory _namespaceName; - readonly ReadOnlyMemory _name; - readonly AssemblyIdentity? _assembly; - readonly ImmutableArray _genericTypeArguments; - readonly int _rankOrModifier; - - /// - /// Initializes a new instance. - /// - /// - /// - /// - /// - internal TypeSymbolNameParserResult(ReadOnlyMemory namespaceName, ReadOnlyMemory name, AssemblyIdentity? assembly, ImmutableArray genericTypeArguments, int rankOrModifier = default) - { - _namespaceName = namespaceName; - _name = name; - _assembly = assembly; - _genericTypeArguments = genericTypeArguments; - _rankOrModifier = rankOrModifier; - } - - public string AssemblyQualifiedName { get; } - - } - -} \ No newline at end of file diff --git a/src/IKVM.CoreLib/Symbols/TypeSymbolNameReader.cs b/src/IKVM.CoreLib/Symbols/TypeSymbolNameReader.cs index c50c7527a..06fb74130 100644 --- a/src/IKVM.CoreLib/Symbols/TypeSymbolNameReader.cs +++ b/src/IKVM.CoreLib/Symbols/TypeSymbolNameReader.cs @@ -1,52 +1,38 @@ using System; -using System.Buffers; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; -using IKVM.CoreLib.Buffers; +using static IKVM.CoreLib.Symbols.TypeSymbolNameParserHelpers; namespace IKVM.CoreLib.Symbols { - ref struct TypeSymbolNameReader + [DebuggerDisplay("{_inputString}")] + ref struct TypeNameParser { - private readonly bool _throwOnError; - private ReadOnlySpan _inputString; - - private TypeSymbolNameReader(ReadOnlySpan name, bool throwOnError, TypeNameParseOptions? options) : this() + public static TypeSymbolName? Parse(ReadOnlySpan typeName, bool throwOnError) { - _inputString = name; - _throwOnError = throwOnError; - _parseOptions = options ?? s_defaults; - } - - internal static TypeName? Parse(ReadOnlySpan typeName, bool throwOnError, TypeNameParseOptions? options = default) - { - ReadOnlySpan trimmedName = typeName.TrimStart(); // whitespaces at beginning are always OK + var trimmedName = typeName.TrimStart(); // whitespaces at beginning are always OK if (trimmedName.IsEmpty) { if (throwOnError) - { ThrowArgumentException_InvalidTypeName(errorIndex: 0); // whitespace input needs to report the error index as 0 - } return null; } int recursiveDepth = 0; - TypeNameParser parser = new(trimmedName, throwOnError, options); - TypeName? parsedName = parser.ParseNextTypeName(allowFullyQualifiedName: true, ref recursiveDepth); + var parser = new TypeNameParser(trimmedName, throwOnError); + var parsedName = parser.ParseNextTypeName(allowFullyQualifiedName: true, ref recursiveDepth); if (parsedName is null || !parser._inputString.IsEmpty) // unconsumed input == error { if (throwOnError) { - if (IsMaxDepthExceeded(parser._parseOptions, recursiveDepth)) - { - ThrowInvalidOperation_MaxNodesExceeded(parser._parseOptions.MaxNodes); - } + if (IsMaxDepthExceeded(recursiveDepth)) + ThrowInvalidOperation_MaxNodesExceeded(32); int errorIndex = typeName.Length - parser._inputString.Length; ThrowArgumentException_InvalidTypeName(errorIndex); @@ -60,16 +46,30 @@ private TypeSymbolNameReader(ReadOnlySpan name, bool throwOnError, TypeNam return parsedName; } + readonly bool _throwOnError; + ReadOnlySpan _inputString; + + /// + /// Initializes a new instance. + /// + /// + /// + TypeNameParser(ReadOnlySpan name, bool throwOnError) : this() + { + _inputString = name; + _throwOnError = throwOnError; + } + // this method should return null instead of throwing, so the caller can get errorIndex and include it in error msg - private TypeName? ParseNextTypeName(bool allowFullyQualifiedName, ref int recursiveDepth) + TypeSymbolName? ParseNextTypeName(bool allowFullyQualifiedName, ref int recursiveDepth) { - if (!TryDive(_parseOptions, ref recursiveDepth)) + if (!TryDive(ref recursiveDepth)) { return null; } List? nestedNameLengths = null; - if (!TryGetTypeNameInfo(_parseOptions, ref _inputString, ref nestedNameLengths, ref recursiveDepth, out int fullTypeNameLength)) + if (!TryGetTypeNameInfo(ref _inputString, ref nestedNameLengths, ref recursiveDepth, out int fullTypeNameLength)) { return null; } @@ -80,11 +80,7 @@ private TypeSymbolNameReader(ReadOnlySpan name, bool throwOnError, TypeNam _inputString = _inputString.Slice(fullTypeNameLength); // Don't allocate now, as it may be an open generic type like "Name`1" -#if SYSTEM_PRIVATE_CORELIB - List? genericArgs = null; -#else - ImmutableArray.Builder? genericArgs = null; -#endif + ImmutableArray.Builder? genericArgs = null; // Are there any captured generic args? We'll look for "[[" and "[". // There are no spaces allowed before the first '[', but spaces are allowed @@ -99,7 +95,7 @@ private TypeSymbolNameReader(ReadOnlySpan name, bool throwOnError, TypeNam // Namespace.Type`2[GenericArgument1,GenericArgument2] - single square bracket syntax is legal only for non-fully qualified type names // Namespace.Type`2[[GenericArgument1, AssemblyName1], GenericArgument2] - mixed mode // Namespace.Type`2[GenericArgument1, [GenericArgument2, AssemblyName2]] - mixed mode - TypeName? genericArg = ParseNextTypeName(allowFullyQualifiedName: doubleBrackets, ref recursiveDepth); + TypeSymbolName? genericArg = ParseNextTypeName(allowFullyQualifiedName: doubleBrackets, ref recursiveDepth); if (genericArg is null) // parsing failed { return null; @@ -113,11 +109,7 @@ private TypeSymbolNameReader(ReadOnlySpan name, bool throwOnError, TypeNam if (genericArgs is null) { -#if SYSTEM_PRIVATE_CORELIB - genericArgs = new List(2); -#else - genericArgs = ImmutableArray.CreateBuilder(2); -#endif + genericArgs = ImmutableArray.CreateBuilder(2); } genericArgs.Add(genericArg); @@ -154,7 +146,7 @@ private TypeSymbolNameReader(ReadOnlySpan name, bool throwOnError, TypeNam else { // Every constructed generic type needs the generic type definition. - if (!TryDive(_parseOptions, ref recursiveDepth)) + if (!TryDive(ref recursiveDepth)) { return null; } @@ -168,7 +160,7 @@ private TypeSymbolNameReader(ReadOnlySpan name, bool throwOnError, TypeNam // iterate over the decorators to ensure there are no illegal combinations while (TryParseNextDecorator(ref _inputString, out int parsedDecorator)) { - if (!TryDive(_parseOptions, ref recursiveDepth)) + if (!TryDive(ref recursiveDepth)) { return null; } @@ -178,18 +170,10 @@ private TypeSymbolNameReader(ReadOnlySpan name, bool throwOnError, TypeNam previousDecorator = parsedDecorator; } - AssemblyNameInfo? assemblyName = null; + AssemblyIdentity? assemblyName = null; if (allowFullyQualifiedName && !TryParseAssemblyName(ref assemblyName)) { -#if SYSTEM_PRIVATE_CORELIB - // backward compat: throw FileLoadException for non-empty invalid strings - if (_throwOnError || !_inputString.TrimStart().StartsWith(",")) - { - throw new IO.FileLoadException(SR.InvalidAssemblyName, _inputString.ToString()); - } -#else return null; -#endif } // No matter what was parsed, the full name string is allocated only once. @@ -197,8 +181,8 @@ private TypeSymbolNameReader(ReadOnlySpan name, bool throwOnError, TypeNam // when needed for the first time . string fullName = fullTypeName.ToString(); - TypeName? declaringType = GetDeclaringType(fullName, nestedNameLengths, assemblyName); - TypeName result = new(fullName, assemblyName, declaringType: declaringType); + TypeSymbolName? declaringType = GetDeclaringType(fullName, nestedNameLengths, assemblyName); + TypeSymbolName result = new(fullName, assemblyName, declaringType: declaringType); if (genericArgs is not null) { result = new(fullName: null, assemblyName, elementOrGenericType: result, declaringType, genericArgs); @@ -243,16 +227,14 @@ private bool TryParseAssemblyName(ref AssemblyIdentity? assemblyName) return true; } - private static TypeSymbolNameParserResult? GetDeclaringType(string fullTypeName, List? nestedNameLengths, AssemblyIdentity? assemblyName) + private static TypeSymbolName? GetDeclaringType(string fullTypeName, List? nestedNameLengths, AssemblyIdentity? assemblyName) { if (nestedNameLengths is null) - { return null; - } // The loop below is protected by the dive check in GetFullTypeNameLength. - TypeSymbolNameParserResult? declaringType = null; + TypeSymbolName? declaringType = null; int nameOffset = 0; foreach (int nestedNameLength in nestedNameLengths) { @@ -267,4 +249,4 @@ private bool TryParseAssemblyName(ref AssemblyIdentity? assemblyName) } -} +} \ No newline at end of file